[Bbs2ch-cvs 73] CVS update: bbs2chreader/content/bbs2chreader/bbsmenu

アーカイブの一覧に戻る

flyson flyso****@users*****
2005年 12月 14日 (水) 00:39:03 JST


Index: bbs2chreader/content/bbs2chreader/bbsmenu/updater.xml
diff -u /dev/null bbs2chreader/content/bbs2chreader/bbsmenu/updater.xml:1.1
--- /dev/null	Wed Dec 14 00:39:03 2005
+++ bbs2chreader/content/bbs2chreader/bbsmenu/updater.xml	Wed Dec 14 00:39:03 2005
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+
+<bindings id="bbsmenuUpdaterBindings"
+		xmlns="http://www.mozilla.org/xbl"
+		xmlns:xbl="http://www.mozilla.org/xbl"
+		xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+
+<binding id="bbsmenuUpdater">
+	<content>
+		<xul:hbox flex="1">
+			<xul:progressmeter anonid="prgrsMeter" flex="1" style="min-width:50px"/>
+			<xul:toolbarbutton anonid="btnCancel" label="X"/>
+			<xul:spacer class="small-margin"/>
+		</xul:hbox>
+	</content>
+
+	<resources>
+		<stylesheet src="chrome://bbs2chreader/skin/ff-statusbar.css"/>
+	</resources>
+
+	<implementation>
+		<field name="_bbs2chService"/>
+		<field name="_bbsMenuFile"/>
+		<field name="_downloader"/>
+		<field name="_prgrsMeter"/>
+		<property name="bbsMenuFile" onget="return this._bbsMenuFile" readonly="true"/>
+
+		<constructor><![CDATA[
+			this._bbs2chService = Components.classes["@mozilla.org/bbs2ch-service;1"]
+						.getService(Components.interfaces.nsIBbs2chService);
+			this._bbsMenuFile = this._bbs2chService.getDataDir();
+			this._bbsMenuFile.appendRelativePath("bbsmenu.html");
+
+			this._downloader = null;
+			this._prgrsMeter = document.getAnonymousElementByAttribute(
+						this, "anonid", "prgrsMeter");
+			this._prgrsMeter.value = 0;
+		]]></constructor>
+
+		<destructor>this.cancel()</destructor>
+
+
+		<method name="_fireEvent">
+			<parameter name="aEventType"/>
+			<body><![CDATA[
+				var event = document.createEvent("Events");
+				event.initEvent(aEventType, false, true);
+
+				var noCancel = this.dispatchEvent(event);
+				var handler = this.getAttribute("on" + aEventType);
+				if(handler){
+					var fn = new Function("event", handler);
+					var returned = fn(event);
+					if (returned == false) noCancel = false;
+				}
+				return noCancel;
+			]]></body>
+		</method>
+
+		<method name ="update">
+			<body><![CDATA[
+				var urlSpec = this._bbs2chService.pref.getCharPref(
+								"fls.bbs2chreader.bbsmenu_load_url");
+				var filePath = this._bbsMenuFile.path;
+				this._downloader = new Bbs2chDownloader(urlSpec, filePath);
+				this._downloader._context = this;
+				this._downloader.onStart = function(aDownloader){
+					var context = this._context;
+					context._prgrsMeter.mode = "undetermined";
+				};
+
+				this._downloader.onStop = function(aDownloader, aStatus){
+					var context = this._context;
+					context._prgrsMeter.mode = "determined";
+					context._prgrsMeter.value = 0;
+					context._downloader = null;
+					context._fireEvent("updated");
+				};
+
+				this._downloader.onProgressChange = function(aDownloader, aPercentage){
+					var context = this._context;
+					context._prgrsMeter.mode = "determined";
+					context._prgrsMeter.value = aPercentage;
+				};
+				this._downloader.onError = function(aDownloader, aErrorCode){
+					var context = this._context;
+					context._prgrsMeter.mode = "determined";
+					context._prgrsMeter.value = 0;
+					context._fireEvent("upddateerror");
+				};
+				this._downloader.download();
+			]]></body>
+		</method>
+
+		<method name ="cancel">
+			<body><![CDATA[
+				if(this._downloader && this._downloader.loading)
+						this._downloader.abort(true);
+			]]></body>
+		</method>
+
+		<method name ="_doCommand">
+			<parameter name="aEvent"/>
+			<body><![CDATA[
+				var targetElement = aEvent.originalTarget;
+				var anonymousID = targetElement.getAttribute("anonid");
+				switch(anonymousID){
+					case "btnCancel":
+						this.cancel();
+						break;
+				}
+			]]></body>
+		</method>
+	</implementation>
+
+	<handlers>
+		<handler event="command" action="this._doCommand(event)"/>
+	</handlers>
+</binding>
+
+
+</bindings>
\ No newline at end of file
Index: bbs2chreader/content/bbs2chreader/bbsmenu/treeview.js
diff -u /dev/null bbs2chreader/content/bbs2chreader/bbsmenu/treeview.js:1.1
--- /dev/null	Wed Dec 14 00:39:03 2005
+++ bbs2chreader/content/bbs2chreader/bbsmenu/treeview.js	Wed Dec 14 00:39:03 2005
@@ -0,0 +1,210 @@
+function b2rBbsmenuTreeView(){
+	this._items = new Array();
+	this._viewItems = new Array();
+}
+
+b2rBbsmenuTreeView.prototype = {
+
+	get items(){
+		return this._items;
+	},
+
+	get viewItems(){
+		return this._viewItems;
+	},
+
+	get searchString(){
+		return this._searchString;
+	},
+	set searchString(aValue){
+		this._searchString = aValue;
+		this._searchMode = (aValue != "");
+
+		this._treeBox.rowCountChanged(0, - this.rowCount);
+		this._refreshItems();
+		this._treeBox.rowCountChanged(0, this.rowCount);
+		
+		return aValue;
+	},
+
+	get searchMode(){
+		return this._searchMode;
+	},
+	
+	init: function(){
+		this._atomService = Components.classes["@mozilla.org/atom-service;1"]
+				.getService(Components.interfaces.nsIAtomService);
+		this._searchMode = false;
+		this._items = new Array();
+
+		var openedCategories = gTreeBbsMenu.getAttribute("openedCategories");
+		openedCategories = openedCategories.split(" ");
+		openedCategories = openedCategories.map(function(aElement, aIndex, aArray){
+			return decodeURI(aElement);
+		});
+		for(var i=0; i<arguments.length; i++){
+			var doc = arguments[i];
+			if(doc.documentElement.localName != "bbsmenu") continue;
+			doc.documentElement._item = null;
+			var allElements = doc.documentElement.getElementsByTagName("*");
+			for(var j=0; j<allElements.length; j++){
+				var element = allElements[j];
+				var item = {};
+				item.title = element.getAttribute("title");
+				item.url = element.getAttribute("url");
+				item.type = element.getAttribute("type");
+				item.isSeparator = (element.localName == "separator");
+				item.isContainer = (element.localName == "category");
+				item.isOpen = ((item.isContainer) && (openedCategories.indexOf(item.title) != -1));
+				element._item = item;
+				item.parent = (element.parentNode._item) ? element.parentNode._item : null;
+				item.level = (item.parent) ? item.parent.level + 1 : 0;
+				this._items.push(item);
+			}
+		}
+		this._refreshItems();
+	},
+	
+	_refreshItems: function(){
+		this._viewItems = new Array();
+
+		if(this.searchMode){
+			var unicodeNormalizer  = Components.classes["@mozilla.org/intl/unicodenormalizer;1"]
+					.createInstance(Components.interfaces.nsIUnicodeNormalizer);
+			var normalizedStr = {};
+
+			var searchString = this.searchString.toLowerCase();
+			unicodeNormalizer.NormalizeUnicodeNFKC(searchString, normalizedStr);
+			searchString = normalizedStr.value;
+
+			var items = this.items;
+			for(var i=0; i<items.length; i++){
+				var item = items[i];
+				if(item.isContainer) continue;
+				var title = item.title.toLowerCase();
+				unicodeNormalizer.NormalizeUnicodeNFKC(title, normalizedStr);				
+				title = normalizedStr.value;
+				if(title.indexOf(searchString) != -1)
+					this._viewItems.push(item);
+			}
+			return;
+		}
+		
+		for(var i=0; i<this.items.length; i++){
+			var item = this.items[i];
+			var view = true;
+			var parent = item.parent;
+			
+			for(var parent=item.parent; parent!=null; parent=parent.parent){
+				if(!parent.isOpen) view = false;
+			}
+			if(view) this._viewItems.push(item);
+		}
+	},
+
+	persistOpenedCategories: function(){
+		var openedCategories = new Array();
+		this.viewItems.forEach(function(aElement, aIndex, aArray){
+			if(aElement.isOpen) this.push(encodeURI(aElement.title));
+		}, openedCategories);
+		gTreeBbsMenu.setAttribute("openedCategories", openedCategories.join(" "));
+	},
+
+
+// ********** ********* implements nsITreeView ********** **********
+
+	get rowCount(){
+		return this.viewItems.length;
+	},
+	
+	selection: null,
+
+	getCellText : function(aRow, aCol){
+		if(this.viewItems[aRow].isSeparator) return "";
+		return this.viewItems[aRow][aCol.id];
+	},
+
+	setTree: function(aTree){
+		this._treeBox = aTree;
+	},
+
+	cycleHeader: function(aCol, aElement){
+	},
+
+	getRowProperties: function(aIndex, aProperties){},
+	getCellProperties: function(aRow, aCol, aProperties){
+		if(this.viewItems[aRow].isSeparator) return;
+		if(aCol.primary){
+			aProperties.AppendElement(this._atomService.getAtom("Name"));
+			var type = this.viewItems[aRow].type;
+			if(type)
+				aProperties.AppendElement(this._atomService.getAtom("type-" + type));
+		}
+	},
+	getColumnProperties: function(aCol, aColElement, aProperties){},
+	isContainer: function(aRow){
+		return this.viewItems[aRow].isContainer;
+	},
+	isContainerOpen: function(aRow){
+		if(this.viewItems[aRow].isContainer){
+			return this.viewItems[aRow].isOpen;
+		}
+		return false;
+	},
+	isContainerEmpty: function(aRow){
+		return false;
+	},
+	isSeparator: function(aRow){
+		return this.viewItems[aRow].isSeparator;	
+	},
+	isSorted: function(aRow){},
+	canDropOn: function(aIndex){},
+	canDropBeforeAfter: function(aIndex, aBefore){},
+	drop: function(aIndex, aOrientation){},
+	getParentIndex: function getParentIndex(aIndex){
+		if(this.searchMode) return -1;
+		if(this.viewItems[aIndex].isContainer) return -1;
+
+		var parent = this.viewItems[aIndex].parent;
+		if(!parent) return -1;
+		return this.viewItems.indexOf(parent);
+	},
+	hasNextSibling: function(aIndex, aAfterIndex){
+		if(this.searchMode) return false;
+		if(aIndex + 1 == this.viewItems.length) return false;
+
+		var item = this.viewItems[aIndex];
+		if(item.isContainer){
+			for(var i=aIndex+1; i<this.viewItems.length; i++){
+				if(item.parent == this.viewItems[i].parent) return true;
+			}
+			return false;
+		}else if(item.level == this.viewItems[aIndex+1].level){
+			return true;
+		}
+		return false;
+	},
+ 	getLevel: function(aIndex){
+		if(this.searchMode) return 0;
+		return this.viewItems[aIndex].level;
+	},
+	getImageSrc: function(aRow, aCol){},
+	getProgressMode: function(aRow, aCol){},
+	getCellValue: function(aRow, aCol){},
+	selectionChanged: function(){},
+	cycleCell: function(aRow, aCol){},
+	isEditable: function(aRow, aCol){},
+	setCellText: function(aRow, aCol, aValue){},
+	toggleOpenState: function(aIndex){
+		var category = this.viewItems[aIndex];
+		category.isOpen = !category.isOpen;
+		var lastCount = this.rowCount;
+		this._refreshItems();
+		var delta = this.rowCount - lastCount;
+		this._treeBox.rowCountChanged(aIndex + 1, delta);
+		this._treeBox.invalidateRow(aIndex);		
+	},
+	performAction: function(aAction){},
+	performActionOnRow: function(aAction, aRow){},
+	performActionOnCell: function(aAction, aRow, aCol){}
+}
\ No newline at end of file
Index: bbs2chreader/content/bbs2chreader/bbsmenu/page.xul
diff -u /dev/null bbs2chreader/content/bbs2chreader/bbsmenu/page.xul:1.1
--- /dev/null	Wed Dec 14 00:39:03 2005
+++ bbs2chreader/content/bbs2chreader/bbsmenu/page.xul	Wed Dec 14 00:39:03 2005
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="EUC-JP"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://bbs2chreader/skin/bbsmenu-page.css" type="text/css"?>
+
+<!DOCTYPE page [
+	<!ENTITY % bbsmenu-page-dtd SYSTEM "chrome://bbs2chreader/locale/bbsmenu-page.dtd">
+	%bbsmenu-page-dtd;
+]>
+<page id="pageMain" title="BBSMENU [bbs2chreader]"
+	onload="startup()" onunload="shutdown()"
+	onmousedown="event.preventBubble()" onkeypress="event.preventBubble()"
+	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+
+<script type="application/x-javascript" src="chrome://bbs2chreader/content/lib/downloader.js"/>
+<script type="application/x-javascript" src="chrome://bbs2chreader/content/lib/clipboard.js"/>
+<script type="application/x-javascript" src="chrome://bbs2chreader/content/lib/rdf.js"/>
+<script type="application/x-javascript" src="chrome://bbs2chreader/content/bbsmenu/treeview.js"/>
+<script type="application/x-javascript" src="chrome://bbs2chreader/content/bbsmenu/page.js"/>
+
+<popupset>
+	<popup id="popBbsMenuContext"
+				onpopupshowing="return showBbsMenuContext(event)">
+		<menuitem label="&ctxtOpen.label;" oncommand="openBoard(false)"/>
+		<menuitem label="&ctxtOpenInNewTab.label;" oncommand="openBoard(true)"/>
+		<menuseparator/>
+		<menuitem label="&ctxtCopuURL.label;" oncommand="copyURL(false)"/>
+		<menuitem label="&ctxtCopuURLnTitle.label;" oncommand="copyURL(true)"/>
+	</popup>
+</popupset>
+
+<hbox align="center">
+	<textbox id="search-box" value="" flex="1" type="autocomplete"
+			autocompletesearch="form-history"
+			autocompletesearchparam="bbs2ch-bbsmenu-history"
+			ontextentered="searchTitle(this.value)"/>
+	<toolbarbutton id="btnHistory" label="&history.label;" type="menu">
+		<menupopup id="popHistory" onpopupshowing="updateHistoryMenu()"
+				onclick="popHistoryClick(event)"/>
+	</toolbarbutton>
+	<toolbarbutton label="&tools.label;" type="menu">
+		<menupopup>
+			<menuitem label="&bbsmenuUpdate.label;" oncommand="bbsmenuUpdate()"/>
+			<menuseparator/>
+			<menuitem label="&openLogsDirectory.label;" oncommand="openLogsDir()"/>
+			<menuitem label="&options.label;" oncommand="openSettings()"/>
+			<menuitem label="&about.label;" oncommand="openAbout()"/>
+		</menupopup>
+	</toolbarbutton>
+	<spacer class="small-margin"/>
+</hbox>
+
+<hbox id="bbsmenuUpdater" collapsed="true"
+	onupdated="onBbsmenuUpdated()" onupddateerror="alert('UPDATE ERROR')"
+	style="-moz-binding:url(chrome://bbs2chreader/content/bbsmenu/updater.xml#bbsmenuUpdater)"/>
+
+<tree id="treeBbsMenu" onclick="treeBbsMenuClick(event)" hidecolumnpicker="true"
+		context="popBbsMenuContext"
+		persist="openedCategories" flags="dont-build-content" class="plain" flex="1">
+	<treecols>
+		<treecol id="title" flex="1" hideheader="true" primary="true"/>
+	</treecols>
+	<treechildren/>
+</tree>
+
+<!-- History Menu -->
+<tree flex="1" id="treeHiddenHistory" hidden="true" collapsed="true"
+	datasources="rdf:null" flags="dont-build-content" hidecolumnpicker="true">
+	<template>
+		<rule>
+			<treechildren>
+				<treeitem uri="rdf:*" rdf:type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type">
+					<treerow>
+						<treecell label="rdf:http://home.netscape.com/NC-rdf#Date"/>
+					</treerow>
+				</treeitem>
+			</treechildren>
+		</rule>
+	</template>
+	<treecols>
+		<treecol flex="1" id="ColHiddenHistoryTreeDate" hideheader="true"
+				primary="true" sort="rdf:http://home.netscape.com/NC-rdf#Date"
+				sortActive="true" sortDirection="descending"/>
+	</treecols>
+</tree>
+
+</page>
\ No newline at end of file
Index: bbs2chreader/content/bbs2chreader/bbsmenu/page.js
diff -u /dev/null bbs2chreader/content/bbs2chreader/bbsmenu/page.js:1.1
--- /dev/null	Wed Dec 14 00:39:03 2005
+++ bbs2chreader/content/bbs2chreader/bbsmenu/page.js	Wed Dec 14 00:39:03 2005
@@ -0,0 +1,412 @@
+var gBbs2chService = Components.classes["@mozilla.org/bbs2ch-service;1"]
+			.getService(Components.interfaces.nsIBbs2chService);
+
+var gBbsmenuUpdater
+var gTreeBbsMenu;
+var gTreeBbsMenuView;
+var gBbsMenuFile;
+var gBbsMenuXMLFile;
+var gHistoryRDF;
+
+function startup(){
+	gBbsmenuUpdater = document.getElementById("bbsmenuUpdater");
+	gTreeBbsMenu = document.getElementById("treeBbsMenu");
+	gBbsMenuFile = gBbs2chService.getDataDir();
+	gBbsMenuFile.appendRelativePath("bbsmenu.html");
+	gBbsMenuXMLFile = gBbs2chService.getDataDir();
+	gBbsMenuXMLFile.appendRelativePath("bbsmenu.xml");
+
+
+	gHistoryRDF = new Bbs2chRDF();
+	gHistoryRDF.initWithRDFURL("rdf:history");
+	var btnHistory = document.getElementById("btnHistory");
+	btnHistory.hidden = !gBbs2chService.pref.getBoolPref(
+								"fls.bbs2chreader.bbsmenu_historymenu_show");
+
+	if(gBbsMenuXMLFile.exists()){
+		initTreeBbsMenu();
+	}else{	// bbsmenu.html ‚ª–³‚¢‚Æ‚«‚ÍŽ©“®‚Ŏ擾
+		bbsmenuUpdate();
+	}
+}
+
+function shutdown(){
+	if(gTreeBbsMenuView) gTreeBbsMenuView.persistOpenedCategories();
+	gTreeBbsMenu.view = null;
+}
+
+
+function initTreeBbsMenu(){
+	if(!gBbsMenuXMLFile.exists()){
+		createBbsmenuXML();
+	}else if(gBbsMenuFile.exists() && 
+					(gBbsMenuXMLFile.lastModifiedTime < gBbsMenuFile.lastModifiedTime)){
+		createBbsmenuXML();	
+	}
+
+	var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+				.getService(Components.interfaces.nsIIOService);
+	var bbsMenuXMLURL = ioService.newFileURI(gBbsMenuXMLFile);
+	var bbsmenuDoc = document.implementation.createDocument("", "", null);
+	bbsmenuDoc.async = false;
+	bbsmenuDoc.load(bbsMenuXMLURL.spec);
+
+		// ŠO•””Â
+	var	outsidexmlFile = gBbs2chService.getDataDir();
+	outsidexmlFile.appendRelativePath("outside.xml");
+	if(!outsidexmlFile.exists()){
+		var outsideContent = gBbs2chService.readLocalURI(
+				"chrome://bbs2chreader/content/res/outside.xml");
+		gBbs2chService.writeFile(outsidexmlFile.path, outsideContent, false);
+	}
+	var outsideXMLURL = ioService.newFileURI(outsidexmlFile);
+	var outsideDoc = document.implementation.createDocument("", "", null);
+	outsideDoc.async = false;
+	outsideDoc.load(outsideXMLURL.spec);
+
+	// outsideDoc.documentElement.appendChild(outsideDoc.createElement("separator"));
+
+	gTreeBbsMenu.view = null;
+	gTreeBbsMenuView = new b2rBbsmenuTreeView();
+	gTreeBbsMenuView.init(outsideDoc, bbsmenuDoc);
+	gTreeBbsMenu.view = gTreeBbsMenuView;
+}
+
+
+function createBbsmenuXML(){
+		// bbsmenu.html ‚ð“ǂݍž‚ñ‚ŁAs‚ð”z—ñ‚ÉŠi”[
+	var contentLines = gBbs2chService.readFile(gBbsMenuFile.path);
+	contentLines = gBbs2chService.fromSJIS(contentLines);
+		// ‰üsˆÊ’u‚ª‚¨‚©‚µ‚¢•”•ª‚̏C³
+	contentLines = contentLines.replace(/<\/B><BR><A HREF/igm, "</B><BR>\n<A HREF");
+	contentLines = contentLines.split("\n");
+
+	var categoryReg = /<BR><B>([^<]+)<\/B><BR>/i;
+	var threadReg	= /^<A HREF=([^> ]+)>([^<]+)<\/A>/i;
+	var threadReg2	= /^<A HREF=([^> ]+) TARGET=_blank>([^<]+)<\/A>/i;
+
+	var currentCategory = null;
+	var doc = new DOMParser().parseFromString("<bbsmenu/>", "text/xml");
+	for(var i=0; i<contentLines.length; i++){
+		var line = contentLines[i];
+		if(categoryReg.test(line)){
+			currentCategory = doc.createElement("category");
+			currentCategory.setAttribute("title", RegExp.$1);
+			doc.documentElement.appendChild(currentCategory);
+		}else if((threadReg.test(line) || threadReg2.test(line)) && currentCategory){
+			var board = doc.createElement("board");
+			board.setAttribute("title", RegExp.$2);
+			var url = RegExp.$1;
+			url = url.replace(/"/g, "");
+			board.setAttribute("url", url);
+			try{
+				board.setAttribute("type", gBbs2chService.getBoardType(url));
+				currentCategory.appendChild(board);
+			}catch(ex){
+				dump(RegExp.$1 +"\n");
+			}
+		}
+	}
+	var xmlSource = new XMLSerializer().serializeToString(doc);
+	xmlSource = gBbs2chService.toSJIS(xmlSource);
+	xmlSource = xmlSource.replace(/></gm, ">\n<");
+	xmlSource = xmlSource.replace(/<board/gm, "\t<board");
+	xmlSource = '<?xml version="1.0" encoding="SHIFT_JIS"?>\n' + xmlSource;
+	gBbs2chService.writeFile(gBbsMenuXMLFile.path, xmlSource, false);
+}
+
+
+/**
+ * —š—ð‚ð“Ç‚ñ‚Å History ƒƒjƒ…[‚ðXV‚·‚é
+ */
+function updateHistoryMenu(){
+	const NS_NC_NAME = "http://home.netscape.com/NC-rdf#Name";
+
+	var popHistory = document.getElementById("popHistory");
+	while(popHistory.hasChildNodes()){
+		popHistory.removeChild(popHistory.firstChild);
+	}
+
+	var treeHiddenHistory = document.getElementById("treeHiddenHistory");
+	if(treeHiddenHistory.hidden){
+		treeHiddenHistory.hidden = false;
+		treeHiddenHistory.database.AddDataSource(gHistoryRDF.ds);
+	}
+	
+	treeHiddenHistory.ref = "find:datasource=history&match=URL&method=startswith&text=bbs2ch:board:";
+	var boardCount = treeHiddenHistory.treeBoxObject.view.rowCount;
+	var boardMax = gBbs2chService.pref.getIntPref("fls.bbs2chreader.bbsmenu_historymenu_board_max");
+	if(boardMax > 15) boardMax = 15;
+	if(boardCount > boardMax) boardCount = boardMax;
+	if(boardCount > 0){
+		for(var i=0; i<boardCount; i++){
+			try{
+				var url = treeHiddenHistory.builder.getResourceAtIndex(i).Value;
+				var title = gHistoryRDF.getLiteralProperty(url, NS_NC_NAME);
+				title = title.replace(" [bbs2chreader]", "");
+				var menuNode = document.createElement("menuitem");
+				menuNode.setAttribute("label", title);
+				menuNode.setAttribute("value", url);
+				menuNode.setAttribute("tooltiptext", url);
+				popHistory.appendChild(menuNode);
+			}catch(ex){}
+		}
+	}
+
+	treeHiddenHistory.ref = "find:datasource=history&match=URL&method=startswith&text=bbs2ch:thread:";
+	var threadCount = treeHiddenHistory.treeBoxObject.view.rowCount;
+	var threadMax = gBbs2chService.pref.getIntPref("fls.bbs2chreader.bbsmenu_historymenu_thread_max");
+	if(threadMax > 15) threadMax = 15;
+	if(threadCount > threadMax) threadCount = threadMax;
+	if(threadCount > 0){
+		if(boardCount > 0) popHistory.appendChild(document.createElement("menuseparator"));
+		
+		for(i=0; i<threadCount; i++){
+			try{
+				url = treeHiddenHistory.builder.getResourceAtIndex(i).Value;
+				title = gHistoryRDF.getLiteralProperty(url, NS_NC_NAME);
+				title = title.replace(" [bbs2chreader]", "");
+				menuNode = document.createElement("menuitem");
+				menuNode.setAttribute("label", title);
+				menuNode.setAttribute("value", url);
+				menuNode.setAttribute("tooltiptext", url);
+				popHistory.appendChild(menuNode);
+			}catch(ex){}
+		}
+	}
+}
+
+
+/**
+ * History ƒƒjƒ…[ƒAƒCƒeƒ€‚ðƒNƒŠƒbƒN‚µ‚½‚Æ‚«‚̏ˆ—
+ * @param aEvent event ƒCƒxƒ“ƒgƒIƒuƒWƒFƒNƒg
+ */
+function popHistoryClick(aEvent){
+	var target = aEvent.originalTarget;
+	if(target.localName != "menuitem" || !(target.value)) return;
+	if(aEvent.button == 0){
+		gBbs2chService.openURL(target.value, null, false);
+	}else if(aEvent.button == 1){
+		target.parentNode.hidePopup();
+		gBbs2chService.openURL(target.value, null, true);	
+	}
+}
+
+
+/**
+ * bbsmenu.html ‚ðƒ_ƒEƒ“ƒ[ƒh‚µ‚Ĕˆꗗ‚ðXV‚·‚é
+ */
+function bbsmenuUpdate(){
+	gBbsmenuUpdater.collapsed = false;
+	gBbsmenuUpdater.update();
+}
+
+function onBbsmenuUpdated(){
+	gBbsmenuUpdater.collapsed = true;
+	gBbsMenuFile.initWithFile(gBbsMenuFile);
+	initTreeBbsMenu();
+}
+
+
+/**
+ * ƒƒOƒtƒHƒ‹ƒ_‚ðŠJ‚­
+ */
+function openLogsDir(){
+	var logDir = gBbs2chService.getDataDir();
+
+	try{
+		logDir.reveal();
+	}catch(ex){
+			// for Unix
+		var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+				.getService(Components.interfaces.nsIIOService);
+	    var protocolService = Components.classes
+	    		["@mozilla.org/uriloader/external-protocol-service;1"]
+    				.getService(Components.interfaces.nsIExternalProtocolService);
+		var logDirURI = ioService.newFileURI(logDir);
+		protocolService.loadUrl(logDirURI);
+	}
+}
+
+
+/**
+ * Ý’èƒ_ƒCƒAƒƒO‚ðŠJ‚­
+ */
+function openSettings(){
+	var settingDialogURL = "chrome://bbs2chreader/content/settings/settings.xul";
+	window.openDialog(settingDialogURL, "_blank", "chrome, modal, resizable");
+}
+
+
+/**
+ * ƒGƒNƒXƒeƒ“ƒVƒ‡ƒ“ƒ}ƒl[ƒWƒƒ‚ðŽg‚Á‚½ About ‚Ì•\Ž¦
+ */
+function openAbout(){
+	var ExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
+								.getService(Components.interfaces.nsIExtensionManager);
+	var emDS = ExtensionManager.datasource;
+	var ExtensionID = "urn:mozilla:item:{0B9D558E-6983-486b-9AAD-B6CBCD2FC807}";
+	window.openDialog("chrome://mozapps/content/extensions/about.xul", "",
+				"chrome, modal", ExtensionID, emDS);
+}
+/**
+ * About ƒ_ƒCƒAƒƒO‚ªƒz[ƒ€ƒy[ƒW‚ðŠJ‚­Žž‚É—˜—p‚·‚郁ƒ\ƒbƒh
+ */
+function openURL(aURLSpec){
+	gBbs2chService.openURL(aURLSpec, null, true);
+}
+
+/**
+ * ‘I‘𒆂̔‚ðƒuƒ‰ƒEƒU‚ÅŠJ‚­
+ * @param {boolean} aAddTab true ‚È‚çV‚µ‚¢ƒ^ƒu‚ÅŠJ‚­
+ */
+function openBoard(aAddTab){
+	if(gTreeBbsMenu.currentIndex == -1) return;
+	
+	var item = gTreeBbsMenuView.viewItems[gTreeBbsMenu.currentIndex];
+	var boardURL = item.url;
+	if(boardURL.indexOf("http://") != 0) return;
+
+	var boardType = item.type;
+	switch(parseInt(boardType)){
+		case gBbs2chService.BOARD_TYPE_2CH:
+		case gBbs2chService.BOARD_TYPE_BE2CH:
+		case gBbs2chService.BOARD_TYPE_JBBS:
+			boardURL = "bbs2ch:board:" + boardURL;
+			break;
+	}		
+	gBbs2chService.openURL(boardURL, null, aAddTab);
+}
+
+
+/**
+ * ƒcƒŠ[‚ðƒNƒŠƒbƒN‚µ‚½‚Æ‚«‚ɌĂ΂ê‚é
+ * @param {event} aEvent 
+ */
+function treeBbsMenuClick(aEvent){
+	var row = {}
+	var obj = {};
+	gTreeBbsMenu.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY, row, {}, obj);
+	if(row.value == -1) return;	// ƒcƒŠ[‚̃AƒCƒeƒ€ˆÈŠO‚ðƒNƒŠƒbƒN
+
+	var eButton = aEvent.button;
+	var eDetail = aEvent.detail;
+	var isSeparator = gTreeBbsMenu.view.isSeparator(row.value);
+	var isContainer = gTreeBbsMenu.view.isContainer(row.value);
+
+	if(isSeparator) return;
+
+	if(eButton==0 && eDetail==1 && obj.value=="twisty"){
+			// twisty ƒ{ƒ^ƒ“‚ðŽg‚Á‚½ƒRƒ“ƒeƒi‚̃I[ƒvƒ“
+		closeAllOpendContainers(row.value);
+		return;
+	}else if(eDetail==2 && obj.value!="twisty" && isContainer){
+			// ƒ_ƒuƒ‹ƒNƒŠƒbƒN‚É‚æ‚éƒRƒ“ƒeƒi‚̃I[ƒvƒ“
+		closeAllOpendContainers(row.value);
+		return;
+	}
+
+	var openAction = gBbs2chService.pref.getIntPref("fls.bbs2chreader.bbsmenu_open_action");
+	if(eButton==0 && eDetail==1 && !isContainer){
+			// ƒNƒŠƒbƒN
+	}else if(eButton==0 && eDetail==2 && !isContainer){
+			// ƒ_ƒuƒ‹ƒNƒŠƒbƒN
+			openBoard(openAction == 1);
+	}else if(eButton==1 && eDetail==1 && !isContainer){
+			// ƒ~ƒhƒ‹ƒNƒŠƒbƒN
+			openBoard(openAction == 0);
+	}
+}
+
+
+/**
+ * ŠJ‚¢‚Ä‚¢‚é‚·‚ׂẴcƒŠ[ƒRƒ“ƒeƒi‚ð•Â‚¶‚é
+ * @param aExceptIndex number •Â‚¶‚È‚¢ƒRƒ“ƒeƒi‚̃Cƒ“ƒfƒbƒNƒX
+ */
+function closeAllOpendContainers(aExceptIndex){
+	// XXX TODO b2rBbsmenuTreeView ‚Ɉړ®‚³‚¹‚é
+	if(!gTreeBbsMenu.view.isContainerOpen(aExceptIndex)) return;
+
+	if(!gBbs2chService.pref.getBoolPref(
+					"fls.bbs2chreader.bbsmenu_toggle_open_container")) return;
+
+	var exceptItemTitle = gTreeBbsMenuView.viewItems[aExceptIndex].title;
+	var exceptItem;
+
+	for(var i=0; i<gTreeBbsMenuView.items.length; i++){
+		var item = gTreeBbsMenuView.items[i];
+		if(!item.isContainer) continue;
+		if(item.title == exceptItemTitle){
+			item.isOpen = true;
+			exceptItem = item;
+		}else{
+			item.isOpen = false;
+		}
+	}
+	for(i=exceptItem.parent; i!=null; i=i.parent){
+		i.isOpen = true;
+	}
+	
+	gTreeBbsMenu.treeBoxObject.rowCountChanged(0, - gTreeBbsMenuView.rowCount);
+	gTreeBbsMenuView._refreshItems();
+	gTreeBbsMenu.treeBoxObject.rowCountChanged(0, gTreeBbsMenuView.rowCount);
+
+	for(i=0; i<gTreeBbsMenuView.viewItems.length; i++){
+		item = gTreeBbsMenuView.viewItems[i];
+		if(item.title == exceptItemTitle){
+			gTreeBbsMenu.boxObject.ensureRowIsVisible(i);
+			return;
+		}
+	}
+}
+
+
+/**
+ * ƒcƒŠ[‚̃Rƒ“ƒeƒLƒXƒgƒƒjƒ…[‚ª•\Ž¦‚³‚ê‚é‚Æ‚«‚ɌĂ΂ê‚é
+ * @param {event} aEvent
+ */
+function showBbsMenuContext(aEvent){
+	var row = {}
+	var obj = {};
+	gTreeBbsMenu.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY, row, {}, obj);
+
+		// ƒcƒŠ[‚̃AƒCƒeƒ€ˆÈŠO‚ðƒNƒŠƒbƒN
+	if(row.value == -1) return false;
+		// ƒZƒpƒŒ[ƒ^‚̏ꍇ‚̓Rƒ“ƒeƒLƒXƒgƒƒjƒ…[‚ðo‚³‚È‚¢
+	if(gTreeBbsMenu.view.isSeparator(row.value)) return false;
+		// ƒRƒ“ƒeƒi‚̏ꍇ‚̓Rƒ“ƒeƒLƒXƒgƒƒjƒ…[‚ðo‚³‚È‚¢
+	if(gTreeBbsMenu.view.isContainer(row.value)) return false;
+	return true;
+}
+
+
+function searchTitle(aSearchString){
+	if(aSearchString){
+				// ƒtƒH[ƒ€—š—ð‚ÉŒŸõ•¶Žš—ñ‚ð’ljÁ
+		var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
+					.getService(Components.interfaces.nsIFormHistory);
+		formHistory.addEntry("bbs2ch-bbsmenu-history", aSearchString);
+		gTreeBbsMenuView.searchString = aSearchString;
+	}else{
+		gTreeBbsMenuView.searchString = "";
+	}
+}
+
+
+/**
+ * ‘I‘ð’†‚Ì”Â‚Ì URL ‚ðƒNƒŠƒbƒvƒ{[ƒh‚ɃRƒs[
+ * @param {boolean} aAddTitle ^‚È‚çƒ^ƒCƒgƒ‹‚àƒRƒs[‚·‚é
+ */
+function copyURL(aAddTitle){
+	if(gTreeBbsMenu.currentIndex == -1) return;
+	var item = gTreeBbsMenuView.viewItems[gTreeBbsMenu.currentIndex];
+
+	var boardURL = item.url;
+	if(boardURL.indexOf("http://")!=0) return;
+	var boardTitle = item.title;
+	if(aAddTitle){
+		Bbs2chClipboard.setString(boardTitle +"\n"+ boardURL);
+	}else{
+		Bbs2chClipboard.setString(boardURL);
+	}
+}


bbs2ch-cvs メーリングリストの案内
アーカイブの一覧に戻る