[Pkg-mozext-commits] [sage-extension] 01/07: initial add

David Prévot taffit at moszumanska.debian.org
Fri May 1 03:10:16 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to tag sage_1_0
in repository sage-extension.

commit 31ca91c31b2a7832abf42c6d14881a3f38db79b2
Author: Peter Andrews <petea at jhu.edu>
Date:   Sat May 22 18:27:01 2004 +0000

    initial add
---
 src/install.js                                     |  28 +
 src/sage/content/bookmarksTree.xml                 |  58 ++
 src/sage/content/commonfunc.js                     | 284 +++++++++
 src/sage/content/contents.rdf                      |  28 +
 src/sage/content/createhtml.js                     | 123 ++++
 src/sage/content/getrsstitle.js                    |  76 +++
 src/sage/content/opml/opml.js                      | 272 +++++++++
 src/sage/content/opml/opml.xul                     |  41 ++
 src/sage/content/popupex.xml                       |  86 +++
 src/sage/content/res/sage.css                      |  79 +++
 src/sage/content/res/template-html.txt             |  19 +
 src/sage/content/res/template-item.txt             |   8 +
 src/sage/content/sage-Overlay.xul                  |  33 ++
 src/sage/content/sage.js                           | 657 +++++++++++++++++++++
 src/sage/content/sage.xul                          | 132 +++++
 src/sage/content/search/blogdigger.png             | Bin 0 -> 363 bytes
 src/sage/content/search/bulkfeeds.png              | Bin 0 -> 215 bytes
 src/sage/content/search/daypop.png                 | Bin 0 -> 180 bytes
 src/sage/content/search/feedback.png               | Bin 0 -> 319 bytes
 src/sage/content/search/feedsearch.js              | 104 ++++
 src/sage/content/search/feedster.png               | Bin 0 -> 179 bytes
 src/sage/content/search/searchEngine.rdf           |  55 ++
 .../content/settings/bookmarkfoldermenulist.js     |  72 +++
 src/sage/content/settings/exUnregisterer.js        | 540 +++++++++++++++++
 src/sage/content/settings/settings.js              | 168 ++++++
 src/sage/content/settings/settings.xul             |  51 ++
 src/sage/content/updatechecker.js                  | 124 ++++
 src/sage/locale/en-US/contents.rdf                 |  17 +
 src/sage/locale/en-US/opml.dtd                     |  11 +
 src/sage/locale/en-US/sage.dtd                     |  31 +
 src/sage/locale/en-US/sage.properties              |  13 +
 src/sage/locale/ja-JP/contents.rdf                 |  17 +
 src/sage/locale/ja-JP/opml.dtd                     |  11 +
 src/sage/locale/ja-JP/sage.dtd                     |  32 +
 src/sage/locale/ja-JP/sage.properties              |  13 +
 src/sage/skin/classic/contents.rdf                 |  29 +
 src/sage/skin/classic/icon/checking.gif            | Bin 0 -> 288 bytes
 src/sage/skin/classic/icon/error.gif               | Bin 0 -> 138 bytes
 src/sage/skin/classic/icon/no-updated.png          | Bin 0 -> 335 bytes
 src/sage/skin/classic/icon/search-submit.gif       | Bin 0 -> 111 bytes
 src/sage/skin/classic/icon/unknown.png             | Bin 0 -> 399 bytes
 src/sage/skin/classic/icon/updated.png             | Bin 0 -> 448 bytes
 src/sage/skin/classic/sage-button.css              |   9 +
 src/sage/skin/classic/sage-small.png               | Bin 0 -> 635 bytes
 src/sage/skin/classic/sage.css                     | 108 ++++
 src/sage/skin/classic/sage.png                     | Bin 0 -> 1600 bytes
 46 files changed, 3329 insertions(+)

diff --git a/src/install.js b/src/install.js
new file mode 100755
index 0000000..ca5fc05
--- /dev/null
+++ b/src/install.js
@@ -0,0 +1,28 @@
+const APP_NAME			= "Sage";
+const APP_CHROME_NAME		= "sage";
+const APP_VERSION		= "1.0";
+const APP_FILE 			= "sage.jar";
+const APP_CONTENTS_PATH		= "content/";
+const APP_SKIN_CLASSIC_PATH	= "skin/classic/";
+const APP_LOCALE_ENUS_PATH	= "locale/en-US/";
+const APP_LOCALE_JAJP_PATH	= "locale/ja-JP/";
+
+
+initInstall(APP_NAME, APP_CHROME_NAME, APP_VERSION); 
+
+var chromeFolder = getFolder("Current User", "chrome");
+setPackageFolder(chromeFolder);
+addFile(APP_NAME, APP_FILE, chromeFolder, "");
+
+var jarFolder = getFolder(chromeFolder, APP_FILE);
+registerChrome(CONTENT | PROFILE_CHROME, jarFolder, APP_CONTENTS_PATH);
+registerChrome(SKIN | PROFILE_CHROME, jarFolder, APP_SKIN_CLASSIC_PATH);
+registerChrome(LOCALE | PROFILE_CHROME, jarFolder, APP_LOCALE_ENUS_PATH);
+registerChrome(LOCALE | PROFILE_CHROME, jarFolder, APP_LOCALE_JAJP_PATH);
+
+var result = getLastError(); 
+if(result == SUCCESS) {
+	performInstall();
+} else {
+	cancelInstall(result);
+}
diff --git a/src/sage/content/bookmarksTree.xml b/src/sage/content/bookmarksTree.xml
new file mode 100755
index 0000000..21b1083
--- /dev/null
+++ b/src/sage/content/bookmarksTree.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>  
+
+<!DOCTYPE window [
+	<!ENTITY % bookmarksDTD SYSTEM "chrome://browser/locale/bookmarks/bookmarks.dtd">
+		%bookmarksDTD;
+]>
+
+<bindings id="bookmarksBindings"	
+		  xmlns="http://www.mozilla.org/xbl"	
+		  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
+		  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+		  xmlns:xbl="http://www.mozilla.org/xbl">
+
+  <binding id="bookmarks-tree-name" extends="chrome://browser/content/bookmarks/bookmarksTree.xml#bookmarks-tree">
+	<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"	
+				 xmlns:xbl="http://www.mozilla.org/xbl" contextmenu="_child">
+	  <!-- context menu -->
+	  <menupopup xbl:inherits="onpopupshowing"
+				 onpopupshowing="this.parentNode.createTreeContextMenu(event);createTreeContextMenu2(event)"
+				 onpopuphidden="if (content) content.focus()"
+				 onclick="event.preventBubble();"
+				 onkeypress="event.preventBubble();"/>
+	  <tree anonid="bookmarks-tree" flex="1" class="plain" hidecolumnpicker="true"
+				datasources="rdf:bookmarks rdf:internetsearch rdf:localsearch" ref="NC:BookmarksRoot" flags="dont-build-content"
+				onselect="this.parentNode.treeBoxObject.view.selectionChanged();" seltype="single">
+		<template xmlns:nc="http://home.netscape.com/NC-rdf#">
+		  <rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
+			<treechildren>
+			  <treeitem uri="rdf:*">
+				<treerow properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type separator">
+				  <treecell properties="separator" label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+				</treerow>
+			  </treeitem>
+			</treechildren>
+		  </rule>
+		  <rule>
+			<treechildren>
+			  <treeitem uri="rdf:*">
+				<treerow properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type rdf:http://home.netscape.com/NC-rdf#loading rdf:http://home.netscape.com/WEB-rdf#status">
+				  <treecell	label="rdf:http://home.netscape.com/NC-rdf#Name"
+							properties="rdf:http://home.netscape.com/NC-rdf#Description rss"/>
+				</treerow>
+			  </treeitem>
+			</treechildren>
+		  </rule>
+		</template>
+		<treecols anonid="treecols">
+		  <treecol id="Name" flex="1" primary="true" hideheader="true"
+				   sort="rdf:http://home.netscape.com/NC-rdf#Name"
+				   sortActive="true" sortDirection="none"/>
+		</treecols>
+	  </tree>
+	</xbl:content>
+	<implementation>
+	  <field name="clickCount">1</field>
+	</implementation>
+  </binding>
+</bindings>
diff --git a/src/sage/content/commonfunc.js b/src/sage/content/commonfunc.js
new file mode 100755
index 0000000..368e93d
--- /dev/null
+++ b/src/sage/content/commonfunc.js
@@ -0,0 +1,284 @@
+var CommonFunc = {
+
+	RSS_READER_FOLDER_ID: "sage.folder_id",
+	USER_AGENT: "Mozilla/5.0 (Sage)",
+
+
+
+// ++++++++++ ++++++++++ Bookmark RDF ++++++++++ ++++++++++
+
+	BM_LAST_VISIT: 		"http://home.netscape.com/WEB-rdf#LastVisitDate",
+	BM_LAST_MODIFIED:	"http://home.netscape.com/WEB-rdf#LastModifiedDate",
+	BM_DESCRIPTION:		"http://home.netscape.com/NC-rdf#Description",
+	BM_NAME:			"http://home.netscape.com/NC-rdf#Name",
+	BM_URL:				"http://home.netscape.com/NC-rdf#URL",
+
+	STATUS_UPDATE: "updated",
+	STATUS_NO_UPDATE: "no-updated",
+	STATUS_UNKNOWN: "unknown",
+	STATUS_ERROR: "error",
+	STATUS_NO_CHECK: "no-check",
+
+	setBMDSProperty: function(aInput, aArcURI, aNewValue){
+		var changed = false;
+		var aOldValue = this.getBMDSTargetByURL(aInput, aArcURI);		
+		if(typeof(aInput) == "string"){
+			aInput = RDF.GetResource(aInput);
+		}
+		if(typeof(aArcURI) == "string"){
+			aArcURI = RDF.GetResource(aArcURI);
+		}
+
+		if(typeof(aNewValue) == "string"){
+			aNewValue = RDF.GetLiteral(aNewValue);
+		}else if(typeof(aNewValue) == "number"){
+			aNewValue = RDF.GetIntLiteral(aNewValue);		
+		}
+
+		
+		if(aArcURI && (aOldValue || aNewValue) && aOldValue != aNewValue) {
+			if(aOldValue && !aNewValue){
+				BMDS.Unassert(aInput, aArcURI, aOldValue);
+			}else if (!aOldValue && aNewValue){
+				BMDS.Assert(aInput, aArcURI, aNewValue, true);
+			}else /* if (aOldValue && aNewValue) */ {
+				BMDS.Change(aInput, aArcURI, aOldValue, aNewValue);
+			}
+			changed = true;
+		}
+		return changed;
+	},
+
+	getBMDSProperty: function(aInput, aArcURI){
+		if(typeof(aInput) == "string"){
+			aInput = RDF.GetResource(aInput);
+		}
+		if(typeof(aArcURI) == "string"){
+			aArcURI = RDF.GetResource(aArcURI);
+		}
+		return this.getBMDSTargetByURL(aInput, aArcURI).Value;
+	},
+	
+	getBMDSTargetByURL: function(aInput, aArcURI){
+		if(typeof(aArcURI) == "string"){
+			aArcURI = RDF.GetResource(aArcURI);
+		}
+		var node = BMDS.GetTarget(aInput, aArcURI, true);
+		try{
+			return node.QueryInterface(kRDFRSCIID);
+		}catch(e){
+			try{
+				return node.QueryInterface(Components.interfaces.nsIRDFDate);
+			}catch(e){
+				return node? node.QueryInterface(kRDFLITIID) : RDF.GetLiteral("");
+			}
+		}	
+	},
+
+	getBMDSCChildren: function(aResource){
+		if(typeof(aResource) == "string"){
+			aResource = RDF.GetResource(aResource);
+		}
+	
+		var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"]
+								.getService(Components.interfaces.nsIRDFContainer);
+		rdfContainer.Init(BMDS, aResource);
+	   	var containerChildren = rdfContainer.GetElements();
+
+	   	var resultArray = new Array();
+	   	while(containerChildren.hasMoreElements()){
+		   	var res = containerChildren.getNext().QueryInterface(kRDFRSCIID);
+	   	
+		   	if(RDFCU.IsContainer(BMDS, res)){
+		   		resultArray = resultArray.concat(this.getBMDSCChildren(res));
+		   	}else{
+			   	resultArray.push(res);
+			}
+	   	}
+		return resultArray;
+	},
+
+
+
+// ++++++++++ ++++++++++ CharCode ++++++++++ ++++++++++
+
+	convertCharCodeFrom: function(aString, aCharCode){
+		var UConvID = "@mozilla.org/intl/scriptableunicodeconverter";
+		var UConvIF  = Components.interfaces.nsIScriptableUnicodeConverter;
+		var UConv = Components.classes[UConvID].getService(UConvIF);
+		
+		var tmpString = "";
+		try{
+			UConv.charset = aCharCode;
+			tmpString = UConv.ConvertFromUnicode(aString);
+		}catch(e){
+			tmpString = null;
+		}
+		return tmpString;
+	},
+
+
+
+	// node ��̃e�L�X�g��Ԃ�
+	getInnerText: function(aNode) {
+		if(!aNode.hasChildNodes()) return "";
+	
+		var resultArray = new Array();
+		var currentNode;
+		var walker = aNode.ownerDocument.createTreeWalker(aNode,
+						NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_TEXT, null, false);
+		while(currentNode = walker.nextNode()) resultArray.push(currentNode.nodeValue);
+		return resultArray.join('').replace(/^\s+|\s+$/g, "");
+	},
+
+
+	loadText: function(aURI){
+		var	URI = Components.classes["@mozilla.org/network/standard-url;1"]
+					.createInstance(Components.interfaces.nsIURI);
+		URI.spec = aURI;
+	
+		var IOService = Components.classes['@mozilla.org/network/io-service;1']
+							.getService(Components.interfaces.nsIIOService);
+		var channel = IOService.newChannelFromURI(URI);
+		var stream	= channel.open();
+		var scriptableStream = Components.classes['@mozilla.org/scriptableinputstream;1']
+									.createInstance(Components.interfaces.nsIScriptableInputStream);
+		scriptableStream.init(stream);
+
+		var fileContents = scriptableStream.read(scriptableStream.available());
+
+		scriptableStream.close();
+		stream.close();
+
+		return fileContents;
+	},
+
+// ++++++++++ ++++++++++ preferences ++++++++++ ++++++++++
+
+
+		// 	preferences �̒l��������
+	setPrefValue : function(aPrefString, aPrefType, aValue){
+		var nsISupportsString = Components.interfaces.nsISupportsString;
+		var xpPref = Components.classes["@mozilla.org/preferences;1"]
+						.getService(Components.interfaces.nsIPrefBranch);
+
+		var prefType = xpPref.getPrefType(aPrefString);
+
+		try{
+			switch (aPrefType){
+				case "wstr":
+					var string = Components.classes['@mozilla.org/supports-string;1']
+									.createInstance(nsISupportsString);
+					string.data = aValue;
+					return xpPref.setComplexValue(aPrefString, nsISupportsString, string);
+					break;
+				case "str":
+					return xpPref.setCharPref(aPrefString, aValue);
+					break;
+				case "int":
+					aValue = parseInt(aValue); // ������𐮐��l�ɕϊ�
+					return xpPref.setIntPref(aPrefString, aValue);
+					break;
+				case "bool":
+				default:
+					if(typeof(aValue) == "string"){
+						aValue = (aValue == "true"); // �������^�U�l�ɕϊ�
+					}
+					return xpPref.setBoolPref(aPrefString, aValue);
+					break;
+			}
+		}catch(e){
+		}
+		return null;
+	},
+
+		// 	preferences �̒l��ǂݍ���
+	getPrefValue : function(aPrefString, aPrefType, aDefault){
+		var nsISupportsString = Components.interfaces.nsISupportsString;
+		var xpPref = Components.classes["@mozilla.org/preferences;1"]
+						.getService(Components.interfaces.nsIPrefBranch);
+		
+		if(xpPref.getPrefType(aPrefString) == xpPref.PREF_INVALID){
+			return aDefault;
+		}
+		try{
+			switch (aPrefType){
+				case "wstr":
+					return xpPref.getComplexValue(aPrefString, nsISupportsString).data;
+					break;
+				case "str":
+					return xpPref.getCharPref(aPrefString).toString();
+					break;
+				case "int":
+					return xpPref.getIntPref(aPrefString);
+					break;
+				case "bool":
+				default:
+					return xpPref.getBoolPref(aPrefString);
+					break;
+			}
+		}catch(e){
+		}
+		return aDefault;
+	},
+
+		// preferences �̓�e�����
+	clearPref: function(aPrefString) {
+		var xpPref = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPrefBranch);
+
+		try {
+			xpPref.clearUserPref(aPrefString);
+			return true;
+		} catch(e) {
+			return false;
+		}
+	},
+
+		// remove all preferences
+	removePrefs: function() {
+		var xpPref = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
+
+		var prefBranch = xpPref.getBranch("sage.");
+
+		try {
+			prefBranch.deleteBranch("");
+			return true;
+		} catch(e) {
+			return false;
+		}
+	},
+	
+		// ����J�n����
+	addPrefListener: function(aPrefString, aFunc){
+		var prefObserver;
+		try {
+			prefObserver = {
+				domain: aPrefString,
+				observe: aFunc
+			};
+			
+			var pbi = Components.classes["@mozilla.org/preferences-service;1"]
+							.getService(Components.interfaces.nsIPrefBranchInternal);
+			pbi.addObserver(prefObserver.domain, prefObserver, false);
+		} catch(e){
+			alert(e);
+			prefObserver = null; 
+		}
+		
+		return prefObserver;
+	},
+
+	// ����I������
+	removePrefListener: function(aObserver){
+		var prefObserver;
+		try {
+			var pbi = Components.classes["@mozilla.org/preferences-service;1"]
+							.getService(Components.interfaces.nsIPrefBranchInternal);
+			pbi.removeObserver(aObserver.domain, aObserver);
+		} catch(e) {
+			alert(e)
+		}
+	}
+
+
+}
\ No newline at end of file
diff --git a/src/sage/content/contents.rdf b/src/sage/content/contents.rdf
new file mode 100755
index 0000000..10d20f9
--- /dev/null
+++ b/src/sage/content/contents.rdf
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+		 xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+
+  <RDF:Seq about="urn:mozilla:package:root">
+	<RDF:li resource="urn:mozilla:package:sage"/>
+  </RDF:Seq>
+
+  <RDF:Description about="urn:mozilla:package:sage"
+		chrome:displayName="Sage"
+		chrome:author="sage.mozdev.org"
+		chrome:authorURL="http://sage.mozdev.org"
+		chrome:name="sage"
+		chrome:extension="true"
+		chrome:settingsURL="chrome://sage/content/settings/settings.xul"
+		chrome:description="A lightweight RSS and ATOM feed aggregator.">
+  </RDF:Description>
+
+
+	<RDF:Seq about="urn:mozilla:overlays">
+		<RDF:li resource="chrome://browser/content/browser.xul"/>		
+	</RDF:Seq>
+
+	<!-- overlay information for Mozilla Firebird-->
+	<RDF:Seq about="chrome://browser/content/browser.xul">
+		<RDF:li>chrome://sage/content/sage-Overlay.xul</RDF:li>
+	</RDF:Seq>
+</RDF:RDF>
diff --git a/src/sage/content/createhtml.js b/src/sage/content/createhtml.js
new file mode 100755
index 0000000..3a3f3cd
--- /dev/null
+++ b/src/sage/content/createhtml.js
@@ -0,0 +1,123 @@
+var CreateHTML = {
+	USER_CSS_ENABLE: "sage.user_css.enable",
+	USER_CSS_PATH: "sage.user_css.path",
+	ALLOW_ENCODED_CONTENT: "sage.allow_encoded_content",
+	HTML_SOURCE: CommonFunc.loadText("chrome://sage/content/res/template-html.txt"),
+	ITEM_SOURCE: CommonFunc.loadText("chrome://sage/content/res/template-item.txt"),
+	DEFAULT_CSS: "chrome://sage/content/res/sage.css",
+
+	_tabbed: false,
+
+	set tabbed(aValue){ this._tabbed = aValue },
+
+	openHTML: function(aRssObject){
+		if(!aRssObject) return;
+
+		try{
+			var htmlURL = this.createHTML(aRssObject);
+			if(this._tabbed){
+				getContentBrowser().addTab(htmlURL);
+			}else{
+				getContentBrowser().loadURI(htmlURL);
+			}
+		}catch(e){}
+	},
+
+	createHTML: function(aRssObject){
+		var tmpFile = this.getSpecialDir("UChrm");
+		tmpFile.appendRelativePath("sage.html");
+
+		var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+							.getService(Components.interfaces.nsIIOService);
+		var xmlFilePath = ioService.newFileURI(tmpFile).spec;
+
+		if(tmpFile.exists()){
+			tmpFile.remove(true);
+		}
+		tmpFile.create(tmpFile.NORMAL_FILE_TYPE, 0666);
+
+		var stream = Components.classes['@mozilla.org/network/file-output-stream;1']
+						.createInstance(Components.interfaces.nsIFileOutputStream);
+		stream.init(tmpFile, 2, 0x200, false); // open as "write only"
+		
+		var content = this.createHTMLSource(aRssObject);
+		stream.write(content, content.length);
+		stream.flush();
+		stream.close();
+		
+		return xmlFilePath;
+	},
+
+	getUserCssURL: function(){
+		var userCssEnable = CommonFunc.getPrefValue(this.USER_CSS_ENABLE, "bool", false);
+		var userCssPath = CommonFunc.getPrefValue(this.USER_CSS_PATH, "wstr", "");
+		if(!userCssEnable || !userCssPath) return null;
+
+		var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+							.getService(Components.interfaces.nsIIOService);
+		var tmpFile = Components.classes['@mozilla.org/file/local;1']
+							.createInstance(Components.interfaces.nsILocalFile);
+		try{		
+			tmpFile.initWithPath(userCssPath);
+			var cssUrl = ioService.newFileURI(tmpFile);
+			var contentType = ioService.newChannelFromURI(cssUrl).contentType;
+			if(contentType != "text/css") return null;
+
+			return cssUrl.spec;
+		}catch(e){
+			return null;
+		}
+	},
+
+	createHTMLSource: function(aRssObject){
+		var allowEContent = CommonFunc.getPrefValue(this.ALLOW_ENCODED_CONTENT, "bool", false);
+
+		var htmlSource = this.HTML_SOURCE;
+		var cssUrl	= this.getUserCssURL();
+		if(cssUrl){
+			htmlSource = htmlSource.replace("**CSSURL**", cssUrl);
+		}else{
+			htmlSource = htmlSource.replace("**CSSURL**", this.DEFAULT_CSS);
+		}
+		htmlSource = htmlSource.replace("**HTMLTITLE**", aRssObject.title);
+		htmlSource = htmlSource.replace("**TITLE**", aRssObject.title);
+		htmlSource = htmlSource.replace("**LINK**", aRssObject.link);
+		htmlSource = htmlSource.replace("**DESCRIPTION**", aRssObject.description);
+
+		var itemsSource = "";
+		for(var i=0; i<aRssObject.items.length; i++){
+			var link = aRssObject.items[i].link;
+			var title = aRssObject.items[i].title;
+			
+			var description = allowEContent ? aRssObject.items[i].content : aRssObject.items[i].description;
+
+			var pubDate = aRssObject.items[i].pubDate;
+	
+			if(!title)
+				title = "No Title";
+
+			if(description)
+				description = "<div class=\"item-desc\">" + description + "</div>";
+
+			if(pubDate)
+				pubDate = "<div class=\"item-pubDate\">" + pubDate.toLocaleString() + "</div>";
+
+			var itemSource = this.ITEM_SOURCE;
+			itemSource = itemSource.replace("**NUMBER**", i+1);
+			itemSource = itemSource.replace("**LINK**", link);
+			itemSource = itemSource.replace("**TITLE**", title);
+			itemSource = itemSource.replace("**DESCRIPTION**", description);
+			itemSource = itemSource.replace("**PUBDATE**", pubDate);
+			itemsSource += itemSource;
+		}
+		htmlSource = htmlSource.replace("**ITEMS**", itemsSource);
+
+		return CommonFunc.convertCharCodeFrom(htmlSource, "UTF-8");
+	},
+
+	getSpecialDir: function(aProp){
+		var dirService = Components.classes['@mozilla.org/file/directory_service;1']
+							.getService(Components.interfaces.nsIProperties);
+		return dirService.get(aProp, Components.interfaces.nsILocalFile);
+	}
+}
\ No newline at end of file
diff --git a/src/sage/content/getrsstitle.js b/src/sage/content/getrsstitle.js
new file mode 100755
index 0000000..38448e8
--- /dev/null
+++ b/src/sage/content/getrsstitle.js
@@ -0,0 +1,76 @@
+var GetRssTitle = {
+	checking: false,
+	httpReq: null,
+	res: null,
+	url: "",
+	
+	getRssTitle: function(aBookmrkID){
+		if(this.checking) return;
+	
+		this.res = RDF.GetResource(aBookmrkID);
+		this.url = CommonFunc.getBMDSProperty(this.res, CommonFunc.BM_URL);
+		
+		this.httpReq = new XMLHttpRequest();
+		this.httpReq.onload = this.httpLoaded;
+		this.httpReq.onreadystatechange = this.httpReadyStateChange;
+		this.httpReq.open("GET", this.url);
+		this.httpReq.setRequestHeader("User-Agent", USER_AGENT);
+		this.httpReq.overrideMimeType("application/xml");
+		try{
+			this.httpReq.send(null);
+		}catch(e){
+				// FAILURE
+			this.httpReq.abort();
+			this.checking = false;
+		}
+	},
+	
+	httpReadyStateChange: function(){
+		if(GetRssTitle.httpReq.readyState == 2){
+			try{
+				GetRssTitle.httpReq.status;
+			}catch(e){
+					// URL NOT AVAILABLE
+				GetRssTitle.httpReq.abort();
+				GetRssTitle.checking = false;
+			}
+		}
+	},
+	
+	httpLoaded: function(){
+		this.checking = false;
+		
+		var xmlDoc = GetRssTitle.httpReq.responseXML;
+		var rootNodeName = xmlDoc.documentElement.localName.toLowerCase();
+		var rssTitle = "";
+
+		switch(rootNodeName){
+			case "rss":	// RSS
+			case "rdf":
+				var channelNode = xmlDoc.getElementsByTagName("channel")[0];
+				var titleNode = channelNode.getElementsByTagName("title")[0];
+				rssTitle = CommonFunc.getInnerText(titleNode);
+				break;
+			case "feed": // ATOM
+				for(var i = xmlDoc.documentElement.firstChild; i!=null; i=i.nextSibling){
+					if(i.nodeType != i.ELEMENT_NODE) continue;
+					if(i.localName == "title") rssTitle = CommonFunc.getInnerText(i);
+				}
+				break;
+			default:
+				return;
+				break;
+		}
+		if(!rssTitle) return;
+		
+		var prompt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+						.getService(Components.interfaces.nsIPromptService);
+		var resultValue = { value: rssTitle };
+		var result = prompt.prompt(window, "RSS Reader Panel", "New Title", resultValue, null, {});
+
+		if(result){
+			CommonFunc.setBMDSProperty(GetRssTitle.res,
+							CommonFunc.BM_NAME, resultValue.value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/sage/content/opml/opml.js b/src/sage/content/opml/opml.js
new file mode 100755
index 0000000..87aa92b
--- /dev/null
+++ b/src/sage/content/opml/opml.js
@@ -0,0 +1,272 @@
+const WIZ_MODE_IMPORT = 0;
+const WIZ_MODE_EXPORT = 1;
+
+var wizMode = WIZ_MODE_IMPORT;
+
+	// XUL Object
+var winMain;
+var txtImportFile;
+var txtExportFile;
+
+
+function init(){
+		// Bookmarks Service
+	initServices();
+	initBMService();
+
+	winMain = document.getElementById("winMain");
+	txtImportFile = document.getElementById("txtImportFile");
+	txtExportFile = document.getElementById("txtExportFile");
+}
+
+function finish(){
+	if(wizMode == WIZ_MODE_IMPORT){
+		if(!checkFilePath(txtImportFile.value, true)) return false;
+		if(!importOPML()) return false;
+	}else{
+		if(!checkFilePath(txtExportFile.value, false)) return false;
+		exportOPML();
+	}
+	
+	alert("complete");
+	return true;
+}
+
+
+function browseImportFile(){
+	var fpicker = Components.classes["@mozilla.org/filepicker;1"]
+					.createInstance(Components.interfaces.nsIFilePicker);
+	fpicker.init(window, "Select OPML File", fpicker.modeOpen);
+	fpicker.appendFilter("OPML File(*.xml, *.opml)", "*.xml;*.opml");
+	fpicker.appendFilters(fpicker.filterAll);
+
+	var showResult = fpicker.show();
+	if(showResult == fpicker.returnOK){
+		txtImportFile.value = fpicker.file.path;	
+	}
+}
+
+function browseExportFile(){
+	var fpicker = Components.classes["@mozilla.org/filepicker;1"]
+					.createInstance(Components.interfaces.nsIFilePicker);
+	fpicker.init(window, "Select OPML File", fpicker.modeSave);
+	fpicker.appendFilter("OPML File(*.xml, *.opml)", "*.xml;*.opml");
+	fpicker.appendFilters(fpicker.filterAll);
+	fpicker.defaultString = "export.opml";
+
+	var showResult = fpicker.show();
+	if(showResult == fpicker.returnOK || showResult == fpicker.returnReplace){
+		txtExportFile.value = fpicker.file.path;	
+	}
+}
+
+
+
+function checkFilePath(aFilePath, aExistCheck){
+	if(!aFilePath){
+		alert("Please choose a OPML file.");
+		return false;
+	}
+	
+	var tmpFile = Components.classes['@mozilla.org/file/local;1']
+					.createInstance(Components.interfaces.nsILocalFile);
+	try{
+		tmpFile.initWithPath(aFilePath);
+		if(aExistCheck){
+			if(!tmpFile.exists()){
+					// �t�@�C�������݂��Ȃ�
+				alert("The specified file does not exist.");
+				return false;
+			}
+		}
+	}catch(e){
+			// �s���ȃt�@�C���p�X
+		alert("unjust file path.")
+		return false;
+	}
+	
+	return true;
+}
+
+
+
+// ********** ********** Import OPML ********** **********
+function importOPML(){
+	var uriFixup = Components.classes['@mozilla.org/docshell/urifixup;1']
+						.getService(Components.interfaces.nsIURIFixup);
+	var opmlUrl = uriFixup.createFixupURI(txtImportFile.value,
+					uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
+
+	var httpReq = new XMLHttpRequest();
+	try{
+		httpReq.open("GET" , opmlUrl.spec, false);
+		httpReq.overrideMimeType("application/xml");
+		httpReq.send(null);
+	}catch(e){
+		alert("Load Failure");
+		return false;
+	}
+	
+	opmlDoc = httpReq.responseXML;
+	if(opmlDoc.documentElement.localName != "opml"){
+		alert("This File Is Not OPML");
+		return false;
+	}
+	var rssReaderFolderID = CommonFunc.getPrefValue(CommonFunc.RSS_READER_FOLDER_ID,
+								"str", "NC:BookmarksRoot");
+
+	var folderName = "OPML Imported";
+	var opmlTitles = opmlDoc.getElementsByTagName("title");
+	if(opmlTitles.length > 0){
+		var opmlTitle = CommonFunc.getInnerText(opmlTitles[0]);
+		folderName += " - " + opmlTitle;
+	}
+	var rootFolder = BMSVC.createFolderInContainer(folderName,
+								RDF.GetResource(rssReaderFolderID), 1);
+
+	var treeWalker = opmlDoc.createTreeWalker(opmlDoc,
+								NodeFilter.SHOW_ELEMENT, outlineFiltter, true);
+
+	while(treeWalker.nextNode()){
+		var cNode = treeWalker.currentNode;
+		var pNode = cNode.parentNode;
+		var parentFolder = ("_folder" in pNode)? pNode._folder : rootFolder;
+		if(cNode.hasChildNodes()){
+			var title = cNode.getAttribute("title");
+			if(!title) title = cNode.getAttribute("text");
+			if(!title) title = "folder";
+			cNode._folder = BMSVC.createFolderInContainer(title, parentFolder, 1);
+		}else{
+			createRssItem(cNode, parentFolder);
+		}
+	}
+
+
+		// �u�b�N�}�[�N�̕ۑ�
+	BookmarksUtils.flushDataSource();
+
+	return true;
+}
+
+function outlineFiltter(aNode){
+	if(aNode.localName == "outline") return NodeFilter.FILTER_ACCEPT;
+	return NodeFilter.FILTER_SKIP;	
+}
+
+	// outline �v�f���� �u�b�N�}�[�N�A�C�e����쐬
+function createRssItem(aOutlineNode, aRssFolder){
+	var type = aOutlineNode.getAttribute("type");
+	var title = aOutlineNode.getAttribute("title");
+	if(!title) title = aOutlineNode.getAttribute("text");
+	var xmlUrl = aOutlineNode.getAttribute("xmlUrl");
+		// �s���S�� OUTLINE �͖�������
+	if(type!="rss" && !title && xmlUrl) return;
+
+	BMSVC.createBookmarkInContainer(title, xmlUrl, null, null, null, aRssFolder, 1)
+}
+
+
+
+
+// ********** ********** Export OPML ********** **********
+
+
+function exportOPML(){
+	var opmlSource = createOpmlSource();
+	opmlSource = CommonFunc.convertCharCodeFrom(opmlSource, "UTF-8");
+
+	var tmpFile = Components.classes['@mozilla.org/file/local;1']
+					.createInstance(Components.interfaces.nsILocalFile);
+	try{
+		tmpFile.initWithPath(txtExportFile.value);
+		if(tmpFile.exists()){
+			tmpFile.remove(true);
+		}
+		tmpFile.create(tmpFile.NORMAL_FILE_TYPE, 0666);
+		var stream = Components.classes['@mozilla.org/network/file-output-stream;1']
+						.createInstance(Components.interfaces.nsIFileOutputStream);
+		stream.init(tmpFile, 2, 0x200, false); // open as "write only"
+		stream.write(opmlSource, opmlSource.length);
+		stream.flush();
+		stream.close();
+	}catch(e){
+		alert("file create error");
+	}
+}
+
+
+function createOpmlSource(){
+	var rssReaderFolderID = CommonFunc.getPrefValue(CommonFunc.RSS_READER_FOLDER_ID,
+								"str", "NC:BookmarksRoot");
+	var rssReaderFolderRes = RDF.GetResource(rssReaderFolderID);
+	
+	var srcTemplate =  '<?xml version="1.0" encoding="UTF-8"?>';
+		srcTemplate += '<opml version="1.0">';
+		srcTemplate += '<head><title>RSS Reader Panel Export OPML</title></head>';
+		srcTemplate += '<body/></opml>';
+	
+	var opmlDoc = new DOMParser().parseFromString(srcTemplate, "text/xml");
+	var opmlBody = opmlDoc.getElementsByTagName("body")[0];
+	
+	opmlBody.appendChild(createOpmlOutline(opmlDoc, rssReaderFolderRes));
+	xmlIndent(opmlDoc);
+	
+	var opmlSource = new XMLSerializer().serializeToString(opmlDoc);
+	return opmlSource;
+}
+
+
+function createOpmlOutline(aOpmlDoc, aRssItem){
+	var url = CommonFunc.getBMDSProperty(aRssItem, CommonFunc.BM_URL);
+	var title = CommonFunc.getBMDSProperty(aRssItem, CommonFunc.BM_NAME);
+	var isContainer = RDFCU.IsContainer(BMDS, aRssItem);
+	var outlineNode = aOpmlDoc.createElement("outline");
+
+	if(isContainer){
+		outlineNode.setAttribute("text", title);
+		
+		var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"]
+								.getService(Components.interfaces.nsIRDFContainer);
+		rdfContainer.Init(BMDS, aRssItem);
+		var containerChildren = rdfContainer.GetElements();
+
+	   	while(containerChildren.hasMoreElements()){
+			var res = containerChildren.getNext().QueryInterface(kRDFRSCIID);
+			outlineNode.appendChild(createOpmlOutline(aOpmlDoc, res));
+		}
+	}else{
+		outlineNode.setAttribute("type", "rss");
+		outlineNode.setAttribute("text", title);
+		outlineNode.setAttribute("title", title);
+		outlineNode.setAttribute("xmlUrl", url);
+	}
+	return outlineNode;
+}
+
+
+
+	// XML �\�[�X�̃C���f���g
+function xmlIndent(aDoc){
+	var treeWalker = aDoc.createTreeWalker(aDoc, NodeFilter.SHOW_ELEMENT, null, true);
+	aDoc._depth = 0;
+	while(treeWalker.nextNode()){
+		var cNode = treeWalker.currentNode;
+		var pNode = cNode.parentNode;
+		var tmpTextNode;
+
+		if(pNode){
+			cNode._depth = pNode._depth + 1;
+			if(cNode == aDoc.documentElement) continue;
+			tmpTextNode = aDoc.createTextNode("\n" + getIndent(cNode._depth));
+			pNode.insertBefore(tmpTextNode, cNode);
+		}
+		if(!cNode.nextSibling){
+			tmpTextNode = aDoc.createTextNode("\n" + getIndent(cNode._depth - 1));
+			pNode.appendChild(tmpTextNode);
+		}
+	}
+	function getIndent(aDepth){
+		var result = new Array(aDepth);
+		return result.join("\t");
+	}
+}
\ No newline at end of file
diff --git a/src/sage/content/opml/opml.xul b/src/sage/content/opml/opml.xul
new file mode 100755
index 0000000..7215246
--- /dev/null
+++ b/src/sage/content/opml/opml.xul
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<!DOCTYPE wizard SYSTEM "chrome://sage/locale/opml.dtd">
+<wizard id="winMain" title="OPML Import/Export Wizard"
+	onload="init()" onwizardfinish="return finish()"
+	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<script type="application/x-javascript" src="chrome://browser/content/bookmarks/bookmarks.js"></script>
+<script type="application/x-javascript" src="chrome://sage/content/commonfunc.js"></script>
+<script type="application/x-javascript" src="chrome://sage/content/opml/opml.js"></script>
+
+<wizardpage pageid="pageStart" next="pageImport"
+		label="&pageStart.label;" description="&pageStart.desc;">
+	<spacer height="40px"/>
+	<hbox>
+		<radiogroup>
+			<radio id="rdoImport" label="&rdoImport.label;" selected="true"
+				onclick="winMain.currentPage.next='pageImport'; wizMode=WIZ_MODE_IMPORT"/>
+			<radio id="rdoExport" label="&rdoExport.label;"
+				onclick="winMain.currentPage.next='pageExport'; wizMode=WIZ_MODE_EXPORT"/>
+		</radiogroup>
+		<spacer flex="1"/>
+	</hbox>
+</wizardpage>
+
+<wizardpage pageid="pageImport" label="&pageImport.label;" description="&pageImport.desc;">
+	<spacer height="40px"/>
+	<hbox align="center">
+		<textbox flex="1" id="txtImportFile"/>
+		<button label="&browseButton.label;" oncommand="browseImportFile()"/>
+	</hbox>
+</wizardpage>
+
+<wizardpage pageid="pageExport" label="&pageExport.label;" description="&pageExport.desc;">
+	<spacer height="40px"/>
+	<hbox align="center">
+		<textbox flex="1" id="txtExportFile"/>
+		<button label="&browseButton.label;" oncommand="browseExportFile()"/>
+	</hbox>
+</wizardpage>
+
+</wizard>
diff --git a/src/sage/content/popupex.xml b/src/sage/content/popupex.xml
new file mode 100755
index 0000000..2be9da9
--- /dev/null
+++ b/src/sage/content/popupex.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+
+<bindings id="popupBindings"
+   xmlns="http://www.mozilla.org/xbl"
+   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+   xmlns:xbl="http://www.mozilla.org/xbl">
+
+  <binding id="popupex" extends="chrome://global/content/bindings/popup.xml#popup">
+	<content>
+	  <xul:vbox anonid="popupExBox" class="popupex-internal-box">
+	  	<children/>
+	  	<xul:vbox anonid="popupExTitleBox" flex="1"/>
+	  	<xul:vbox anonid="popupExDescBox" flex="1"/>
+	  </xul:vbox>
+	</content>
+	
+	<implementation>
+
+	<property name="title" onget="return this.getAttribute('title');">
+		<setter><![CDATA[
+			this.setAttribute('label', val);
+
+			var popupExTitleBox = document.getAnonymousElementByAttribute(this, "anonid", "popupExTitleBox")
+			while(popupExTitleBox.hasChildNodes()){
+				popupExTitleBox.removeChild(popupExTitleBox.firstChild);
+			}
+			const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+			var popupTitle = document.createElementNS(XUL_NS, "label");
+			popupTitle.className = "popupex-title";
+			popupTitle.appendChild(document.createTextNode(val))
+			popupExTitleBox.appendChild(popupTitle);
+
+			return val;
+		]]></setter>
+	</property>
+	
+
+	<property name="description" onget="return this.getAttribute('description');">
+		<setter><![CDATA[
+			this.setAttribute('description', val);
+			
+			var popupExDescBox = document.getAnonymousElementByAttribute(this, "anonid", "popupExDescBox")
+			while(popupExDescBox.hasChildNodes()){
+				popupExDescBox.removeChild(popupExDescBox.firstChild);
+			}
+
+			if(val == ""){
+				return val;
+			}
+			const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+			var popupDesc = document.createElementNS(XUL_NS, "label");
+			popupDesc.className = "popupex-description";
+			popupDesc.appendChild(document.createTextNode(val))
+			popupExDescBox.appendChild(popupDesc);
+
+			return val;
+		]]></setter>
+	</property>
+	</implementation>
+
+	<handlers>
+		<handler event="popupshowing"><![CDATA[
+			var popupExBox = document.getAnonymousElementByAttribute(this, "anonid", "popupExBox");
+			this.sizeTo(this.popupBoxObject.width, popupExBox.boxObject.height + 5);
+			
+				// �X�N���[������͂ݏo�Ȃ��悤�ɂ���
+			var popupBox = this.popupBoxObject;
+			var popupBoxX = popupBox.screenX;
+			var popupBoxY = popupBox.screenY;
+			var popupBoxBottom = popupBox.screenY + popupBox.height;
+			var popupBoxRight = popupBox.screenX + popupBox.width;
+			
+			if(screen.availWidth < popupBoxRight){
+				popupBoxX =  popupBox.screenX  - popupBox.width - 5;
+				this.moveTo(popupBoxX, popupBoxY);
+			}
+
+			if(screen.availHeight < popupBoxBottom){
+				popupBoxY = popupBox.screenY - popupBox.height - 30
+				this.moveTo(popupBoxX, popupBoxY);
+			}
+		]]></handler>
+	</handlers>
+
+</binding>
+</bindings>
\ No newline at end of file
diff --git a/src/sage/content/res/sage.css b/src/sage/content/res/sage.css
new file mode 100755
index 0000000..3e9517e
--- /dev/null
+++ b/src/sage/content/res/sage.css
@@ -0,0 +1,79 @@
+html * {
+	-moz-box-sizing: border-box;
+}
+
+html {
+	line-height: 1.3; 
+	background-color: #FFF;
+}
+				
+body {
+	margin: 0px;
+	color: #222;
+	font-family: verdana;
+}
+
+a:link		{ text-decoration: none; color: #DD2B13; }
+a:visited	{ text-decoration: none;  color: #955322; }
+a:hover		{ text-decoration: underline; }
+a:active	{ text-decoration: none; }
+
+p.item-desc a:link { color: #029; }
+
+#rss-header {
+	-moz-border-radius: 5px;
+	background-color: #EEEAE4;
+	border: 1px solid #cccccc;
+	padding: 6px 8px;
+	margin: 10px 2%;
+}
+
+#rss-title {
+	font-size: large;
+	line-height: 1;
+	margin: 0px;
+	padding: 0px;
+}
+
+#rss-desc {
+	font-size: small;
+	margin: 0px;
+	padding: 5px 0px 0px 20px;
+}
+
+div.item {
+	-moz-border-radius: 5px;
+	background-color: #fafafa;
+	border: 1px solid #cccccc;
+	width: 47%;
+	min-width: 14em;
+	margin: 0px 0px 8px 2%;
+	padding: 0px;
+	float: left;
+}
+
+h2.item-title {
+	background-color: #EEEAE4;
+	font-size: x-small;
+	font-weight: normal;
+	line-height: 1.1;
+	margin: 0px;
+	padding: 5px 5px 8px 8px;
+}
+
+span.item-ordinal {
+	padding-right: 0.2em;
+}
+
+div.item-desc {
+	min-height: 6em;
+	font-size: x-small;
+	margin: 0px;
+	padding: 8px 10px;
+}
+
+div.item-pubDate {
+	font-size: x-small;
+	margin: 0px;
+	padding: 8px 10px;
+}
\ No newline at end of file
diff --git a/src/sage/content/res/template-html.txt b/src/sage/content/res/template-html.txt
new file mode 100755
index 0000000..1d65d15
--- /dev/null
+++ b/src/sage/content/res/template-html.txt
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<meta http-equiv="Content-Style-Type" content="text/css">
+	<link rel="stylesheet" type="text/css" title="standard Style"
+		href="**CSSURL**">
+	<title>RSS - **HTMLTITLE**</title>
+</head>
+<body>
+	<div id="rss-header">
+		<h1 id="rss-title"><a id="rss-link" href="**LINK**">**TITLE**</a></h1>
+		<p id="rss-desc">**DESCRIPTION**</p>
+	</div>
+	
+	**ITEMS**
+</body>
+</html>
\ No newline at end of file
diff --git a/src/sage/content/res/template-item.txt b/src/sage/content/res/template-item.txt
new file mode 100755
index 0000000..f21822b
--- /dev/null
+++ b/src/sage/content/res/template-item.txt
@@ -0,0 +1,8 @@
+	<div class="item">
+		<h2 class="item-title">
+			<span class="item-ordinal">**NUMBER**.</span>
+			<a href="**LINK**">**TITLE**</a>
+		</h2>
+		**DESCRIPTION**
+		**PUBDATE**
+	</div>
diff --git a/src/sage/content/sage-Overlay.xul b/src/sage/content/sage-Overlay.xul
new file mode 100755
index 0000000..2a84903
--- /dev/null
+++ b/src/sage/content/sage-Overlay.xul
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://sage/skin/sage-button.css" type="text/css"?>
+
+<!DOCTYPE overlay SYSTEM "chrome://sage/locale/sage.dtd">
+<overlay id="sageOverlay"
+	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+	<menupopup id="viewSidebarMenu">
+		<menuitem key="key_openSageSidebar" observes="viewSageSidebar"/>
+	</menupopup>
+
+	<keyset id="mainKeyset">
+		<key id="key_openSageSidebar" command="viewSageSidebar"
+			key="&openSageSidebar.commandkey;"
+			modifiers="&openSageSidebar.modifiersKey;"/>
+	</keyset>
+
+	<broadcasterset id="mainBroadcasterSet">
+		<broadcaster id="viewSageSidebar"
+			autoCheck="false"
+			label="&sage.toolbarLabel;"
+			type="checkbox" group="sidebar"
+			sidebarurl="chrome://sage/content/sage.xul"
+			sidebartitle="&sage.sidebarTitle;"
+			oncommand="toggleSidebar('viewSageSidebar');"/>
+	</broadcasterset>
+
+
+	<toolbarpalette id="BrowserToolbarPalette">
+		<toolbarbutton id="sage-button" tooltiptext="&sage.tooltip;"
+			observes="viewSageSidebar" class="toolbarbutton-1"/>
+	</toolbarpalette>
+</overlay>
diff --git a/src/sage/content/sage.js b/src/sage/content/sage.js
new file mode 100755
index 0000000..d9067cb
--- /dev/null
+++ b/src/sage/content/sage.js
@@ -0,0 +1,657 @@
+const USER_AGENT = CommonFunc.USER_AGENT;
+
+const RESULT_OK = 0;
+const RESULT_PARSE_ERROR = 1;
+const RESULT_NOT_RSS = 2;
+const RESULT_NOT_FOUND = 3;
+const RESULT_NOT_AVAILABLE = 4;
+const RESULT_ERROR_FAILURE = 5;
+
+var resultStrArray = null;
+
+	// XUL Object
+var strRes // stringbundle Object
+var bookmarksTree;
+var rssItemListBox;
+var rssStatusImage;
+var rssStatusLabel;
+var rssTitleLabel;
+var rssItemListPopup;
+
+var rssObject;
+var httpReq;
+var prefObserverSageFolder;
+var responseXML;
+var lastResource;
+var rssLoading = false;
+var sageFolderID = "";
+var enableTooltip = true;
+var popupTimeoutId=0;
+
+function init(){
+	strRes = document.getElementById("strRes");
+	bookmarksTree = document.getElementById("bookmarksTree");
+	rssItemListBox = document.getElementById("rssItemListBox");
+	rssStatusImage = document.getElementById("rssStatusImage");
+	rssStatusLabel = document.getElementById("rssStatusLabel");
+	rssTitleLabel = document.getElementById("rssTitleLabel");
+	rssItemListPopup = document.getElementById("rssItemListPopup");
+
+	resultStrArray = new Array(
+		strRes.getString("RESULT_OK_STR"),
+		strRes.getString("RESULT_PARSE_ERROR_STR"),
+		strRes.getString("RESULT_NOT_RSS_STR"),
+		strRes.getString("RESULT_NOT_FOUND_STR"),
+		strRes.getString("RESULT_NOT_AVAILABLE_STR"),
+		strRes.getString("RESULT_ERROR_FAILURE_STR")
+	);
+
+  	// Load Preference
+	sageFolderID = CommonFunc.getPrefValue(CommonFunc.RSS_READER_FOLDER_ID, "str", "NC:BookmarksRoot");
+  	// observe Preference
+  	prefObserverSageFolder = CommonFunc.addPrefListener(CommonFunc.RSS_READER_FOLDER_ID, sageFolderChanged);
+
+	bookmarksTree.tree.setAttribute("ref", sageFolderID);
+	bookmarksTree.treeBoxObject.selection.select(0);
+	
+	FeedSearch.init();
+	toggleShowSearchBar();
+	toggleShowFeedItemList();
+}
+
+
+	// �X�V���ꂽRSS�̂ݕ\��
+function showOnlyUpdated(){
+	if(getCheckboxCheck("chkOnlyUpdate")){
+		var findURL = "find:datasource=rdf:bookmarks&match=";
+			findURL += CommonFunc.BM_DESCRIPTION;
+			findURL += "&method=is&text=updated";
+		bookmarksTree.tree.setAttribute("ref", findURL);
+	}else{
+		bookmarksTree.tree.setAttribute("ref", sageFolderID);
+	}
+}
+
+function sageFolderChanged(subject, topic, prefName) {
+		// observe Preference
+	sageFolderID = CommonFunc.getPrefValue(CommonFunc.RSS_READER_FOLDER_ID, "str", "NC:BookmarksRoot");
+	bookmarksTree.tree.setAttribute("ref", sageFolderID);
+	bookmarksTree.treeBoxObject.selection.select(0);
+}
+
+function done() {
+	if(prefObserverSageFolder){
+		CommonFunc.removePrefListener(prefObserverSageFolder);
+	}
+
+	if(rssLoading) {
+		httpReq.abort();
+		rssLoading = false;
+	}
+	UpdateChecker.done();
+}
+
+function openOPMLWizard() {
+	var dialogURL = "chrome://sage/content/opml/opml.xul";
+	window.openDialog(dialogURL, "", "chrome,dialog,modal");
+}
+
+function openSettingDialog() {
+	var dialogURL = "chrome://sage/content/settings/settings.xul";
+	window.openDialog(dialogURL, "", "chrome,dialog,modal");
+}
+
+function manageRSSList() {
+	var dialogURL = "chrome://browser/content/bookmarks/bookmarksManager.xul";
+	window.openDialog(dialogURL, "", "chrome,all,dialog=no", sageFolderID);
+}
+
+
+function updateCheck(aCheckFolderId) {	
+	UpdateChecker.onCheck = function(aName, aURL) {
+			rssStatusImage.setAttribute("loading", "true");
+			rssStatusLabel.value = "Checking: " + aName;
+	}
+	UpdateChecker.onChecked = function(aName, aURL) {
+		setStatusDone();
+	}
+	
+	if(aCheckFolderId) {
+		UpdateChecker.startCheck(aCheckFolderId);
+	} else {
+		UpdateChecker.startCheck(sageFolderID);
+	}
+}
+	
+function BookmarkResource(aRes, aDB){
+	this.res = aRes;
+	this.db = aDB;
+	this.name = BookmarksUtils.getProperty(this.res, NC_NS + "Name", this.db);
+	this.url = BookmarksUtils.getProperty(this.res, NC_NS + "URL", this.db);
+}
+
+function bookmarksOpen(){
+	lastResource = new BookmarkResource(bookmarksTree.currentResource, bookmarksTree.db);
+	setStatusLoading();
+	httpGet(lastResource.url);
+}
+
+
+function createTreeContextMenu2(aEvent){
+	var popup = aEvent.target;
+	if(popup.localName != "menupopup") return;
+
+	var selection = bookmarksTree._selection;
+	var itemId = selection.item[0].Value;
+	var cmdSrc = "";
+
+	if(selection.type == "Bookmark"){
+		cmdSrc = "GetRssTitle.getRssTitle('" + itemId + "')";
+		var tempMenuItem = document.createElement("menuitem");
+		tempMenuItem.setAttribute("label", strRes.getString("GET_RSS_TITLE"));
+		tempMenuItem.setAttribute("oncommand", cmdSrc);
+		popup.appendChild(document.createElement("menuseparator"));
+		popup.appendChild(tempMenuItem);
+	}else if(selection.type == "Folder"){
+		cmdSrc = "updateCheck('" + itemId + "')";
+		var tempMenuItem = document.createElement("menuitem");
+		tempMenuItem.setAttribute("label", strRes.getString("CHECK_UPDATE"));
+		tempMenuItem.setAttribute("oncommand", cmdSrc);
+		popup.appendChild(document.createElement("menuseparator"));
+		popup.appendChild(tempMenuItem);
+	}
+}
+
+function bookmarksTreeClick(aEvent){
+	if(aEvent.type == "click"){
+		if(aEvent.button == 2 || aEvent.originalTarget.localName != "treechildren"){
+			return;
+		}
+		var obj = {};
+		bookmarksTree.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY, {}, {}, obj);
+		if(obj.value == "twisty") return;
+	}else if(aEvent.type == "keypress"){
+		if(aEvent.originalTarget.localName != "tree"){
+			return;
+		}
+	}
+	
+	CreateHTML.tabbed = false;
+	if(aEvent.button == 1){ CreateHTML.tabbed = true; } // click middle button
+	if(aEvent.ctrlKey){ CreateHTML.tabbed = true; } // press Ctrl Key
+
+	const BOOKMARK_TYPE = RDF_NS + "type";
+	const BOOKMARK_SEPARATOR = NC_NS + "BookmarkSeparator";
+	const BOOKMARK_FOLDER = NC_NS + "Folder"
+	var bookmarkType = (BookmarksUtils.getProperty(bookmarksTree.currentResource,
+							BOOKMARK_TYPE , bookmarksTree.db))
+	if(bookmarkType == BOOKMARK_SEPARATOR || bookmarkType == BOOKMARK_FOLDER){
+		return;
+	}
+	
+	bookmarksOpen();
+}
+
+
+
+function rssItemListBoxClick(aEvent){
+	if(aEvent.type == "click"){
+		if(aEvent.button == 2 || aEvent.originalTarget.localName != "listitem"){
+			return;
+		}
+	}else if(aEvent.type == "keypress"){
+		if(aEvent.originalTarget.localName != "listbox"){
+			return;
+		}
+	}
+
+	var selectedItem = rssItemListBox.selectedItem;
+	var link = rssObject.items[selectedItem.value].link;
+	var tabbed = false;
+
+	if(aEvent.button == 1){ tabbed = true; } // click middle button
+	if(aEvent.ctrlKey){ tabbed = true; } // press Ctrl Key
+	
+	if(tabbed){
+		getContentBrowser().addTab(link);	
+	}else{
+		getContentBrowser().loadURI(link);
+	}
+	selectedItem.setAttribute("visited", "true");
+}
+
+
+function rssTitleLabelClick(aNode, aEvent){
+	var tabbed = false;
+	if(!aNode.hasAttribute("href") || aEvent.button == 2){
+		return;
+	}
+
+	var link = aNode.getAttribute("href");
+	var tabbed = false;
+
+	if(aEvent.button == 1){ tabbed =true; } // click middle button
+	if(aEvent.ctrlKey){ tabbed = true; } // press Ctrl Key
+	
+	if(tabbed){
+		getContentBrowser().addTab(link);	
+	}else{
+		getContentBrowser().loadURI(link);
+	}
+}
+
+
+function setStatusLoading(){
+	rssStatusImage.setAttribute("loading", "true");
+	rssStatusLabel.value = "Loading: " + lastResource.name;
+}
+
+function setStatusDone(){
+	rssStatusImage.setAttribute("loading", "false");
+	rssStatusLabel.value = "";
+
+	if(rssObject){
+		rssTitleLabel.value = htmlToText(rssObject.title);
+		if(rssObject.link){
+			rssTitleLabel.setAttribute("href", rssObject.link);
+			rssTitleLabel.tooltipText = rssObject.link;
+		}else{
+			rssTitleLabel.removeAttribute("href");
+			rssTitleLabel.tooltipText = "";
+		}
+	}
+}
+
+function setStatusError(aStatus){
+	rssStatusImage.setAttribute("loading", "error");
+	rssStatusLabel.value = "Error: " + aStatus;
+}
+
+
+	// �u���E�U�I�u�W�F�N�g��Ԃ�
+function getContentBrowser(){
+	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
+							.getService(Components.interfaces.nsIWindowMediator);
+	var topWindowOfType = windowManager.getMostRecentWindow("navigator:browser");
+	if (topWindowOfType) {
+		return topWindowOfType.document.getElementById('content');
+	}
+	return null;
+}
+
+
+	// RSS
+function createRssObject(){
+	if(!responseXML){ return; }
+	
+	rssObject = {
+		rssURL: lastResource.url,
+		title: "",
+		link: "",
+		description: "",
+		charSet: responseXML.characterSet,
+		items: new Array()
+	}
+
+	var rootNodeName = responseXML.documentElement.localName.toLowerCase();
+	if(rootNodeName == "feed"){
+		createRssObjectAtom();
+		return;
+	}
+
+	var channelNode;
+	if(responseXML.getElementsByTagName("channel").length != 0){
+		channelNode = responseXML.getElementsByTagName("channel")[0];
+	}else{
+		return;
+	}
+
+	for(var i = channelNode.firstChild; i!=null; i=i.nextSibling){
+		if(i.nodeType != i.ELEMENT_NODE) continue;
+		switch(i.localName){
+			case "title":
+				rssObject.title = CommonFunc.getInnerText(i);
+				break;
+			case "link":
+				rssObject.link = CommonFunc.getInnerText(i);
+				break;
+			case "description":
+				rssObject.description = CommonFunc.getInnerText(i);
+				break;
+		}
+	}
+
+	var itemNodes = responseXML.getElementsByTagName("item");
+	for(i=0; itemNodes.length>i; i++){
+		var rssItem = {title:"", link:"", description:"", content:"", pubDate:""};
+
+		for(var j = itemNodes[i].firstChild; j!=null; j=j.nextSibling){
+			if(j.nodeType != j.ELEMENT_NODE) continue;
+			switch(j.localName){
+				case "title":
+					rssItem.title = CommonFunc.getInnerText(j);
+					break;
+				case "link":
+					rssItem.link = CommonFunc.getInnerText(j);
+					break;
+				case "guid":
+					if(!rssItem.link){
+						rssItem.link = CommonFunc.getInnerText(j);
+					}
+					break;
+				case "description":
+					rssItem.description = CommonFunc.getInnerText(j);
+					break;
+				case "encoded":
+					rssItem.content = CommonFunc.getInnerText(j);
+					break;
+				case "pubDate":
+					rssItem.pubDate = new Date(CommonFunc.getInnerText(j));
+					break;
+				case "date":
+					tmp_str = CommonFunc.getInnerText(j);
+					tmp_date = new Date();
+					tmp_date.setUTCFullYear(tmp_str.substring(0,4));
+					tmp_date.setUTCMonth(tmp_str.substring(5,7) - 1);
+					tmp_date.setUTCDate(tmp_str.substring(8,10));
+					tmp_date.setUTCHours(tmp_str.substring(11,13));
+					tmp_date.setUTCMinutes(tmp_str.substring(14,16));
+					tmp_date.setUTCSeconds(tmp_str.substring(17,19));
+					rssItem.pubDate = new Date(tmp_date);
+					break;
+			}
+		}
+			// title �������Ƃ��̏���
+		if(!rssItem.title) {
+			if(rssItem.description) {
+				tempStr = rssItem.description.replace(/<.*?>/g,'');
+				rssItem.title = tempStr.substring(0, 30) + "...";
+			}
+		}
+			// content �������Ƃ��̏���
+		if(!rssItem.content) rssItem.content = rssItem.description;
+			// description ��v���[���e�L�X�g�ɂ���
+		rssItem.description = htmlToText(rssItem.description);
+
+		rssObject.items.push(rssItem);
+	}
+}
+
+
+	// ATOM
+function createRssObjectAtom(){
+	for(var i = responseXML.documentElement.firstChild; i!=null; i=i.nextSibling){
+		if(i.nodeType != i.ELEMENT_NODE) continue;
+		switch(i.localName){
+			case "title":
+				rssObject.title = CommonFunc.getInnerText(i);
+				break;
+			case "link":
+				if(rssObject.link){
+					if(i.getAttribute("rel") == "alternate"){
+						rssObject.link = i.getAttribute("href");
+					}
+				}else{
+					rssObject.link = i.getAttribute("href");
+				}
+				break;
+			case "tagline":
+				rssObject.description = CommonFunc.getInnerText(i);
+				break;
+		}
+	}
+
+	var entryNodes = responseXML.getElementsByTagName("entry");
+	for(i=0; entryNodes.length>i; i++){
+		var rssItem = {title:"", link:"", description:"", content:"", pubDate:""};
+
+		var titleNodes = entryNodes[i].getElementsByTagName("title");
+		if(titleNodes.length) rssItem.title = CommonFunc.getInnerText(titleNodes[0]);
+
+		var linkNodes = entryNodes[i].getElementsByTagName("link");
+		if(linkNodes.length) {
+			for (j = 0; j < linkNodes.length; j++) {
+				if (linkNodes[j].getAttribute("rel") == "alternate") {
+					rssItem.link = linkNodes[j].getAttribute("href");
+					break;
+				}
+			}
+		}
+
+
+		var issuedNodes = entryNodes[i].getElementsByTagName("issued");
+		if(issuedNodes.length) {
+			tmp_str = CommonFunc.getInnerText(issuedNodes[0]);
+			tmp_date = new Date();
+			tmp_date.setUTCFullYear(tmp_str.substring(0,4));
+			tmp_date.setUTCMonth(tmp_str.substring(5,7) - 1);
+			tmp_date.setUTCDate(tmp_str.substring(8,10));
+			tmp_date.setUTCHours(tmp_str.substring(11,13));
+			tmp_date.setUTCMinutes(tmp_str.substring(14,16));
+			tmp_date.setUTCSeconds(tmp_str.substring(17,19));
+			rssItem.pubDate = new Date(tmp_date);
+		}
+
+		rssItem.content = getAtomContent(entryNodes[i]);
+		rssItem.description = htmlToText(rssItem.content);
+		rssObject.items.push(rssItem);
+	}
+}
+
+
+function getAtomContent(aEntryNode){
+	var contentNodes = aEntryNode.getElementsByTagName("content");
+	var contentArray = new Array();
+	for(var i=0; i<contentNodes.length; i++){
+		var contType = contentNodes[i].getAttribute("type");
+		contentArray[contType] = CommonFunc.getInnerText(contentNodes[i]);
+	}
+
+	if("application/xhtml+xml" in contentArray) return contentArray["application/xhtml+xml"];
+	if("text/html" in contentArray) return contentArray["text/html"];
+	if("text/plain" in contentArray) return contentArray["text/plain"];
+
+	var summaryNodes = aEntryNode.getElementsByTagName("summary");
+	if(summaryNodes.length) return CommonFunc.getInnerText(summaryNodes[0]);
+
+	return "";
+}
+
+function toggleShowSearchBar() {
+	var showSearchBar = getCheckboxCheck("chkShowSearchBar");
+	document.getElementById("barSearch").hidden = !showSearchBar;
+}
+
+function toggleShowFeedItemList() {
+	var showFeedItemList = getCheckboxCheck("chkShowFeedItemList");
+	document.getElementById("sage-splitter").hidden = !showFeedItemList;
+	document.getElementById("rssItemListBoxBox").hidden = !showFeedItemList;
+	if(showFeedItemList) setRssItemListBox();
+}
+
+function setRssItemListBox() {
+	if(!rssObject) return;
+	if(document.getElementById("rssItemListBoxBox").hidden) return;
+
+	while(rssItemListBox.getRowCount() != 0){
+		rssItemListBox.removeItemAt(0);
+	}
+
+	for(var i=0; rssObject.items.length>i; i++){
+		var rssItem = rssObject.items[i];
+		var itemLabel = rssItem.title ? htmlToText(rssItem.title) : "No Title";
+		var listItem = rssItemListBox.appendItem(itemLabel, i);
+		
+		if(isVisited(rssItem.link)){
+			listItem.setAttribute("visited", "true");
+		}		
+	}
+}
+
+
+ // URL ���K��ς݂����ׂ�
+function isVisited(aURL){
+	try{
+		var globalHistory = Components.classes["@mozilla.org/rdf/datasource;1?name=history"]
+							.getService(Components.interfaces.nsIGlobalHistory);
+			// �h���C���̏��������� nsIURI �ɔC���� 
+		var URI = Components.classes['@mozilla.org/network/standard-url;1']
+						.createInstance(Components.interfaces.nsIURI);
+		URI.spec = aURL;
+		return globalHistory.isVisited(URI.spec);
+	}catch(e){}
+	return false;
+}
+
+function getCheckboxCheck(aID){
+	var checkboxNode = document.getElementById(aID);
+	return checkboxNode.getAttribute("checked") == "true";
+}
+
+function showRssItemListPopup(aEvent){
+	if(aEvent.originalTarget.localName != "listitem"){
+		rssItemListPopup.hidePopup();
+		return;
+	}
+	if(!getCheckboxCheck("chkShowTooltip")){
+		rssItemListPopup.hidePopup();
+		return;
+	}
+	
+	var description = rssObject.items[aEvent.originalTarget.value].description;
+		// �܂�Ԃ����邽�߂� URL�� / �̑O�Ƀ[�����X�y�[�X��lj�
+	if(description.indexOf("/") != -1){
+		description = description.replace(/\//gm, "/\u200B");
+	}
+		// description ��400�����ȓ�ɂ���
+	if(description.length > 400){
+		description = description.substring(0,400) + "...";
+	}
+
+	var popX = aEvent.screenX + 10;
+	var popY = aEvent.screenY + 20;
+
+	rssItemListPopup.title = aEvent.originalTarget.label;
+	rssItemListPopup.description = description;
+	rssItemListPopup.autoPosition = false;
+	rssItemListPopup.moveTo(popX, popY);
+	popupTimeoutId = setTimeout("rssItemListPopup.showPopup(rssItemListBox)", 150);
+}
+
+function hideRssItemListPopup(aEvent){
+	clearTimeout(popupTimeoutId);
+	rssItemListPopup.hidePopup();
+}
+
+
+function htmlToText(aStr){
+	var	formatConverter = Components.classes["@mozilla.org/widget/htmlformatconverter;1"]
+								.createInstance(Components.interfaces.nsIFormatConverter);
+	var fromStr = Components.classes["@mozilla.org/supports-string;1"]
+								.createInstance(Components.interfaces.nsISupportsString);
+	fromStr.data = aStr;
+	var toStr = { value: null };
+
+	try{
+		formatConverter.convert("text/html", fromStr, fromStr.toString().length,
+									"text/unicode", toStr, {});
+	}catch(e){
+		return aStr;
+	}
+	if(toStr.value){
+		toStr = toStr.value.QueryInterface(Components.interfaces.nsISupportsString);
+		return toStr.toString();
+	}
+	return aStr;
+}
+
+
+ // ++++++++++ +++++++++  HTTP	++++++++++ +++++++++ 
+
+function httpGet(aURL){
+	if(rssLoading){
+		httpReq.abort();
+		rssLoading = false;
+	}
+
+	responseXML = null;
+
+	httpReq = new XMLHttpRequest();
+	httpReq.onload = httpLoaded;	
+	httpReq.onerror = httpError;
+	httpReq.onreadystatechange = httpReadyStateChange;
+
+
+	try{
+		httpReq.open("GET" , aURL);
+		httpReq.setRequestHeader("User-Agent", USER_AGENT);
+		httpReq.overrideMimeType("application/xml");
+	}catch(e){
+		httpGetResult(RESULT_ERROR_FAILURE);
+	}
+
+	try{
+		httpReq.send(null);
+		rssLoading = true;
+	}catch(e){
+		httpGetResult(RESULT_ERROR_FAILURE);
+	}
+}
+
+function httpError(e){}
+function httpReadyStateChange(){
+
+	if(httpReq.readyState == 2){
+		try{
+			if(httpReq.status == 404){
+				httpGetResult(RESULT_NOT_FOUND);
+			}
+		}catch(e){
+			httpGetResult(RESULT_NOT_AVAILABLE);
+			return;
+		}
+	}else if(httpReq.readyState == 3){}
+}
+
+function httpLoaded(e){
+	responseXML = httpReq.responseXML;
+	var rootNodeName = responseXML.documentElement.localName.toLowerCase();
+
+	switch(rootNodeName){
+		case "parsererror":
+			// XML Parse Error
+			httpGetResult(RESULT_PARSE_ERROR);
+			break;
+		case "rss":
+		case "rdf":
+		case "feed":
+			httpGetResult(RESULT_OK);
+			break;
+		default:
+			// Not RSS or ATOM
+			httpGetResult(RESULT_NOT_RSS);
+			break;
+	}
+}
+
+function httpGetResult(aResultCode){
+	httpReq.abort();
+	rssLoading = false;
+
+	if(aResultCode == RESULT_OK){
+		createRssObject();
+
+		if(lastResource.res){
+			BMSVC.updateLastVisitedDate(rssObject.rssURL, rssObject.charSet);
+			CommonFunc.setBMDSProperty(lastResource.res, CommonFunc.BM_DESCRIPTION, CommonFunc.STATUS_NO_UPDATE);
+		}
+		setStatusDone();
+		setRssItemListBox();
+		
+		if(getCheckboxCheck("chkOpenHTML")){
+			CreateHTML.openHTML(rssObject);
+		}
+	}else{
+		setStatusError(resultStrArray[aResultCode]);
+	}
+}
\ No newline at end of file
diff --git a/src/sage/content/sage.xul b/src/sage/content/sage.xul
new file mode 100755
index 0000000..855ccb2
--- /dev/null
+++ b/src/sage/content/sage.xul
@@ -0,0 +1,132 @@
+<?xml version="1.0"?>
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/bookmarks/bookmarks.css" type="text/css"?>
+<?xml-stylesheet href="chrome://sage/skin/sage.css" type="text/css"?>
+
+<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
+
+<!DOCTYPE page SYSTEM "chrome://sage/locale/sage.dtd">
+<page id="pageSagePanel" title="&sage.label;"
+	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	onload="init();" onunload="done()">
+
+<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
+<script type="application/x-javascript" src="chrome://browser/content/bookmarks/bookmarks.js"/>
+<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
+<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
+
+<script type="application/x-javascript" src="chrome://sage/content/commonfunc.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/sage.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/updatechecker.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/createhtml.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/getrsstitle.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/search/feedsearch.js"/>
+
+	<!-- bookmarks & edit commands -->
+<commandset id="editMenuCommands"/>
+<command id="cmd_bm_open" 		   oncommand="goDoCommand('cmd_bm_open');"/>
+<command id="cmd_bm_openinnewwindow" disabled="true"/>
+<command id="cmd_bm_openinnewtab"	 disabled="true"/>
+<command id="cmd_bm_expandfolder"	 oncommand="goDoCommand('cmd_bm_expandfolder');"/>
+<command id="cmd_bm_openfolder"	   oncommand="goDoCommand('cmd_bm_openfolder');"/>
+<command id="cmd_bm_managefolder"	 oncommand="goDoCommand('cmd_bm_managefolder');"/>
+<command id="cmd_bm_newfolder"	   oncommand="goDoCommand('cmd_bm_newfolder');"/>
+<command id="cmd_bm_newbookmark"	   oncommand="goDoCommand('cmd_bm_newbookmark');"/>
+<command id="cmd_bm_newseparator"	 oncommand="goDoCommand('cmd_bm_newseparator');"/>
+<command id="cmd_bm_find" 		   oncommand="goDoCommand('cmd_bm_find');"/>
+<command id="cmd_bm_properties"	   oncommand="goDoCommand('cmd_bm_properties');"/>
+
+
+
+
+
+
+
+
+<stringbundleset>
+	<stringbundle id="strRes" src="chrome://sage/locale/sage.properties"/>
+</stringbundleset>
+
+<toolbox class="plain">
+	<toolbar class="plain">
+		<button label="&menu.checkUpdate;" oncommand="updateCheck()" style="padding: 0px; font-size: x-small"/>
+		<spacer flex="1"/>
+		<toolbarbutton type="menu" label="&menu.tools;">
+			<menupopup>
+				<menuitem id="chkOpenHTML" type="checkbox" persist="checked" label="&menu.openHTML;"/>
+				<menuitem id="chkShowSearchBar" type="checkbox" persist="checked" label="&menu.showSearchBar;" oncommand="toggleShowSearchBar()"/>
+				<menuitem id="chkShowTooltip" type="checkbox" persist="checked" checked="true" label="&menu.showDescTooltip;"/>
+				<menuitem id="chkShowFeedItemList" type="checkbox" persist="checked" label="&menu.showFeedItemList;" oncommand="toggleShowFeedItemList()"/>
+				<menuseparator/>
+				<menuitem label="&menu.manageRSSList;" oncommand="manageRSSList()"/>
+				<menuitem label="&menu.opmlImportExport;" oncommand="openOPMLWizard()"/>
+				<menuseparator/>
+				<menuitem label="&menu.setting;" oncommand="openSettingDialog()"/>
+			</menupopup>
+		</toolbarbutton>
+	</toolbar>
+	<toolbar id="barSearch" class="plain" align="center">
+		<textbox id="txtSearchValue" type="autocomplete" flex="1"
+			ontextentered="FeedSearch.search()"
+			autocompletesearch="form-history"
+			autocompletesearchparam="q"
+			searchengine="" persist="searchengine">
+			<image id="imgSearchEngine" popup="popSearchEngine"/>
+		</textbox>
+		<toolbarbutton id="btnSearchSubmit" oncommand="FeedSearch.search()"/>
+	</toolbar>
+</toolbox>
+
+<vbox>
+	<sidebarheader id="rssStatusBar" align="center">
+		<hbox align="center" flex="1">
+			<image id="rssStatusImage" loading="false"/>
+			<label id="rssStatusLabel" flex="1" crop="end" value=""/>
+		</hbox>
+  </sidebarheader>
+</vbox>
+
+<vbox flex="1">
+
+<vbox id="bookmarksTreeBox" flex="1" persist="height">
+	<bookmarks-tree id="bookmarksTree" type="single-column" flex="1"
+		onkeypress="if(event.keyCode == 13) bookmarksTreeClick(event)"
+		ondraggesture="if(event.originalTarget.localName == 'treechildren') nsDragAndDrop.startDrag(event, this.DNDObserver);"
+		onclick="bookmarksTreeClick(event)"/>
+</vbox>
+
+<splitter id="sage-splitter"/>
+
+<vbox id="rssItemListBoxBox" flex="1" persist="height">
+	<sidebarheader id="feedTitleBar" align="center">
+		<hbox align="center" flex="1">
+			<label id="rssTitleLabel" flex="1" crop="end" value="" onclick="rssTitleLabelClick(this, event)"/>
+		</hbox>
+	</sidebarheader>
+
+	<listbox id="rssItemListBox" class="plain" flex="1"
+		onmouseout="hideRssItemListPopup()"
+		onmouseover="showRssItemListPopup(event)"
+		onkeypress="if(event.keyCode == 13) rssItemListBoxClick(event)"
+		onclick="rssItemListBoxClick(event)"/>
+</vbox>
+
+</vbox>
+
+<popupset>
+	<popup id="rssItemListPopup" class="popupex"/>
+	
+	<popup id="popSearchEngine" datasources="rdf:null"
+			ref="urn:rrp:searchengine:root">
+		<template>
+			<menuitem type="checkbox" uri="..." value="..."
+				oncommand="FeedSearch.popSearchEngineClick(event)"
+				label="rdf:http://fls.moo.jp/moz/rssreader/#name"
+				image="rdf:http://fls.moo.jp/moz/rssreader/#icon"/>
+		</template>
+	</popup>
+</popupset>
+
+</page> 
\ No newline at end of file
diff --git a/src/sage/content/search/blogdigger.png b/src/sage/content/search/blogdigger.png
new file mode 100755
index 0000000..d049594
Binary files /dev/null and b/src/sage/content/search/blogdigger.png differ
diff --git a/src/sage/content/search/bulkfeeds.png b/src/sage/content/search/bulkfeeds.png
new file mode 100755
index 0000000..10b0f64
Binary files /dev/null and b/src/sage/content/search/bulkfeeds.png differ
diff --git a/src/sage/content/search/daypop.png b/src/sage/content/search/daypop.png
new file mode 100755
index 0000000..3a24cec
Binary files /dev/null and b/src/sage/content/search/daypop.png differ
diff --git a/src/sage/content/search/feedback.png b/src/sage/content/search/feedback.png
new file mode 100755
index 0000000..f23ab83
Binary files /dev/null and b/src/sage/content/search/feedback.png differ
diff --git a/src/sage/content/search/feedsearch.js b/src/sage/content/search/feedsearch.js
new file mode 100755
index 0000000..733927f
--- /dev/null
+++ b/src/sage/content/search/feedsearch.js
@@ -0,0 +1,104 @@
+var FeedSearch = {
+	RRP_NS: "http://fls.moo.jp/moz/rssreader/#",
+	SEARCH_ENGINE_RDF: "chrome://sage/content/search/searchEngine.rdf",
+
+	RDF:Components.classes['@mozilla.org/rdf/rdf-service;1']
+			.getService(Components.interfaces.nsIRDFService),
+
+	txtSearchValue: null,
+	imgSearchEngine: null,
+	popSearchEngine: null,
+	
+	rdfDS: null,
+	searchEngine: "",
+	searchEngineName: "",
+	query: "",
+	charset: "",
+	
+	init: function(){
+		this.txtSearchValue = document.getElementById("txtSearchValue");
+		this.imgSearchEngine = document.getElementById("imgSearchEngine");		
+		this.popSearchEngine = document.getElementById("popSearchEngine");
+		
+			// init Search Engine RDF DataSource
+		this.rdfDS = this.RDF.GetDataSource(this.SEARCH_ENGINE_RDF);
+		var remote = this.rdfDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
+		if(remote.loaded){
+			this.initRdfDataSource();
+		}else{
+			var sink = this.rdfDS.QueryInterface(Components.interfaces.nsIRDFXMLSink);
+			sink.addXMLSinkObserver(this.sinkObserver);
+		}
+	},
+	
+	initRdfDataSource: function(){
+		this.popSearchEngine.database.AddDataSource(this.rdfDS);
+		this.popSearchEngine.builder.rebuild();
+		var tmpSearchEngine = this.txtSearchValue.getAttribute("searchengine");
+		if(!tmpSearchEngine)
+			tmpSearchEngine = this.getRdfProperty("urn:rrp:searchengine:default", this.RRP_NS + "site");
+		this.setSearchEngine(tmpSearchEngine);	
+	},
+	
+	search: function(){
+		var searchValue = this.txtSearchValue.value;
+		if(searchValue == "") return;
+
+		var searchName = this.searchEngineName + " - " + searchValue;
+
+			// ��������Ɍ����������lj�
+		var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
+							.getService(Components.interfaces.nsIFormHistory);
+		formHistory.addEntry("q", searchValue);
+
+			// ��������������G���W���̕����R�[�h�ɍ��킹�ăG�X�P�[�v
+		var textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
+								.getService(Components.interfaces.nsITextToSubURI);
+		searchValue = textToSubURI.ConvertAndEscape(this.charset, searchValue);
+
+		lastResource = {
+			res: null,
+			db: null,
+			name: searchName,
+			url: this.query + searchValue
+		};
+		setStatusLoading();
+		httpGet(lastResource.url);
+	},
+	
+	setSearchEngine: function(aSearchEngine){
+		this.searchEngine = aSearchEngine;
+		this.searchEngineName = this.getRdfProperty(aSearchEngine, this.RRP_NS + "name");
+		this.query = this.getRdfProperty(aSearchEngine, this.RRP_NS + "query");
+		this.charset = this.getRdfProperty(aSearchEngine, this.RRP_NS + "charset");
+
+		this.txtSearchValue.setAttribute("searchengine", this.searchEngine);
+		this.imgSearchEngine.src = this.getRdfProperty(aSearchEngine, this.RRP_NS + "icon");
+	},
+	
+	popSearchEngineClick: function(aEvent){
+		var menuitemNode = aEvent.originalTarget;
+		if(menuitemNode.nodeName != "menuitem") return;
+		
+		this.setSearchEngine(menuitemNode.value);
+	},
+	
+	getRdfProperty: function(aRes, aProperty){
+		if(typeof(aRes) == "string") aRes = this.RDF.GetResource(aRes);
+		if(typeof(aProperty) == "string") aProperty = this.RDF.GetResource(aProperty);
+		var target = this.rdfDS.GetTarget(aRes, aProperty, true);
+		try{
+			return target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
+		}catch(e){
+			return target.QueryInterface(Components.interfaces.nsIRDFResource).Value;
+		}
+	},
+	
+	sinkObserver: {
+		onBeginLoad: function(aSink){},
+		onInterrupt: function(aSink){},
+		onResume: function(aSink){},
+		onEndLoad: function(aSink){ FeedSearch.initRdfDataSource() },
+		onError: function(aSink, aStatus, aErrorMsg){}
+	}
+}
\ No newline at end of file
diff --git a/src/sage/content/search/feedster.png b/src/sage/content/search/feedster.png
new file mode 100755
index 0000000..9a1677b
Binary files /dev/null and b/src/sage/content/search/feedster.png differ
diff --git a/src/sage/content/search/searchEngine.rdf b/src/sage/content/search/searchEngine.rdf
new file mode 100755
index 0000000..161d013
--- /dev/null
+++ b/src/sage/content/search/searchEngine.rdf
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+			xmlns:rrp="http://fls.moo.jp/moz/rssreader/#">
+
+		<!-- Search Engine List-->
+	<rdf:Seq rdf:about="urn:rrp:searchengine:root">
+		<rdf:li rdf:resource="http://feedster.com/"/>
+		<rdf:li rdf:resource="http://www.blogdigger.com/"/>
+		<rdf:li rdf:resource="http://www.daypop.com/"/>
+		<rdf:li rdf:resource="http://bulkfeeds.net/"/>
+		<rdf:li rdf:resource="http://naoya.dyndns.org/feedback/"/>
+	</rdf:Seq>
+
+		<!-- Default Search Engine -->
+	<rdf:Description rdf:about="urn:rrp:searchengine:default">
+		<rrp:site rdf:resource="http://feedster.com/"/>
+	</rdf:Description>
+
+
+		<!-- Search Engine Data -->
+	<rdf:Description rdf:about="http://feedster.com/">
+		<rrp:name>Feedster</rrp:name>
+		<rrp:query rdf:resource="http://feedster.com/search.php?sort=date&ie=UTF-8&limit=15&type=rss&q="/>
+		<rrp:icon rdf:resource="chrome://sage/content/search/feedster.png"/>
+		<rrp:charset>UTF-8</rrp:charset>
+	</rdf:Description>
+
+	<rdf:Description rdf:about="http://www.blogdigger.com/">
+		<rrp:name>Blogdigger</rrp:name>
+		<rrp:query rdf:resource="http://www.blogdigger.com/rss.jsp?sortby=date&days=20&queryString="/>
+		<rrp:icon rdf:resource="chrome://sage/content/search/blogdigger.png"/>
+		<rrp:charset>UTF-8</rrp:charset>
+	</rdf:Description>
+
+	<rdf:Description rdf:about="http://www.daypop.com/">
+		<rrp:name>DAYPOP</rrp:name>
+		<rrp:query rdf:resource="http://www.daypop.com/search?s=1&c=15&ext=true&t=a&o=rss&q="/>
+		<rrp:icon rdf:resource="chrome://sage/content/search/daypop.png"/>
+		<rrp:charset>UTF-8</rrp:charset>
+	</rdf:Description>
+
+	<rdf:Description rdf:about="http://bulkfeeds.net/">
+		<rrp:name>Bulkfeeds:ja</rrp:name>
+		<rrp:query rdf:resource="http://bulkfeeds.net/app/search2.rdf?q="/>
+		<rrp:icon rdf:resource="chrome://sage/content/search/bulkfeeds.png"/>
+		<rrp:charset>UTF-8</rrp:charset>
+	</rdf:Description>
+
+	<rdf:Description rdf:about="http://naoya.dyndns.org/feedback/">
+		<rrp:name>FeedBack:ja</rrp:name>
+		<rrp:query rdf:resource="http://naoya.dyndns.org/feedback/app/rss?keyword="/>
+		<rrp:icon rdf:resource="chrome://sage/content/search/feedback.png"/>
+		<rrp:charset>UTF-8</rrp:charset>
+	</rdf:Description>
+</rdf:RDF>
\ No newline at end of file
diff --git a/src/sage/content/settings/bookmarkfoldermenulist.js b/src/sage/content/settings/bookmarkfoldermenulist.js
new file mode 100755
index 0000000..ca43cad
--- /dev/null
+++ b/src/sage/content/settings/bookmarkfoldermenulist.js
@@ -0,0 +1,72 @@
+function BookmarkFolderMenuList(aMenulistID, aRootFolderID){
+	this.menuList = document.getElementById(aMenulistID);
+	this.menupopup = this.menuList.menupopup;
+	this.rootFolder = aRootFolderID ? aRootFolderID : "NC:BookmarksRoot";
+	this.init();
+}
+BookmarkFolderMenuList.prototype = {
+	RDF: Components.classes["@mozilla.org/rdf/rdf-service;1"]
+				.getService(Components.interfaces.nsIRDFService),
+	RDFC: Components.classes["@mozilla.org/rdf/container;1"]
+				.getService(Components.interfaces.nsIRDFContainer),
+	RDFCU: Components.classes["@mozilla.org/rdf/container-utils;1"]
+				.getService(Components.interfaces.nsIRDFContainerUtils),
+	BMDS: null,
+
+
+	set rootFolderID(aValue){
+		this.rootFolder = aValue;
+		this.init();
+		return this.rootFolder;
+	},
+	get rootFolderID(){
+		return this.rootFolder;
+	},
+
+	set currentFolderID(aValue){
+		return this.menuList.value = aValue;
+	},
+	get currentFolderID(){
+		return this.menuList.value;
+	},
+
+	init: function(){
+		this.BMDS = this.RDF.GetDataSource("rdf:bookmarks");
+		
+		while (this.menupopup.hasChildNodes()){
+			this.menupopup.removeChild(this.menupopup.firstChild);
+		}
+
+		var menuitemNode = document.createElement("menuitem");
+		menuitemNode.setAttribute("label", "Root");
+		menuitemNode.setAttribute("value", this.rootFolder);
+		this.menupopup.appendChild(menuitemNode);
+		this.createMenuItem(this.RDF.GetResource(this.rootFolder), 1);
+		
+		this.menuList.selectedIndex = 0;
+	},
+
+	createMenuItem: function(aFolder, aDepth){
+		this.RDFC.Init(this.BMDS, aFolder);
+		var children = this.RDFC.GetElements();
+		while (children.hasMoreElements()){
+			var item = children.getNext();
+			if(!this.RDFCU.IsContainer(this.BMDS, item)) continue;
+			
+			item = item.QueryInterface(Components.interfaces.nsIRDFResource);
+			var property = this.RDF.GetResource("http://home.netscape.com/NC-rdf#Name");
+			var name = this.BMDS.GetTarget(item, property, true);
+			name = name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
+
+			var Indentation = new Array(aDepth + 1).join("   ");
+
+			var menuitemNode = document.createElement("menuitem");
+			menuitemNode.setAttribute("label", Indentation + name);
+			menuitemNode.setAttribute("value", item.Value);
+			this.menupopup.appendChild(menuitemNode);
+			
+			this.createMenuItem(item, ++aDepth);
+			--aDepth;
+		}
+	}
+}
diff --git a/src/sage/content/settings/exUnregisterer.js b/src/sage/content/settings/exUnregisterer.js
new file mode 100755
index 0000000..4a55ec6
--- /dev/null
+++ b/src/sage/content/settings/exUnregisterer.js
@@ -0,0 +1,540 @@
+/*
+"exUnregisterer", the automatic unregisterer (Ver.0.4.2003041301) 
+
+exapmle:
+
+>var unreg = new exUnregisterer(
+>		'chrome://my_app/content/contents.rdf',
+>		'jar:%chromeFolder%my_app.jar!/locale/en-US/contents.rdf'
+>	);
+>
+>unreg.unregister(); // unregister all files
+>unreg.removePrefs('my_app'); // remove all prefs ('my_app.XXXX.XXXXX', 'my_app.YYYY.ZZZZ', and so on)
+
+
+This class has following properties and methods:
+
+Chrome                   : the URI of the chrome directory in Mozilla
+                           installed.
+UChrome and UChrm        : the URI of the chrome directory in the current
+                           profile.
+unregister()             : executes unregisteration.
+removePrefs(aBranch)     : removes all preferences which include the handled
+                           name.
+readFrom(aFile)          : reads a text file and returns the content as
+                           a string.
+writeTo(aFile, aContent) : writes a text file with a string.
+
+
+When you create an instance of this class, you can use "%chromeFolder%"
+to point two "chrome" folders, in the directory Mozilla was installed in
+and in the profile directory.
+
+
+
+*/
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the exUnregisterer.
+ *
+ * The Initial Developer of the Original Code is SHIMODA Hiroshi.
+ * Portions created by the Initial Developer are Copyright (C) 2002-2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): SHIMODA Hiroshi <piro at p.club.ne.jp>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+function exUnregisterer()
+{
+	this.init(arguments);
+	delete this.mTarget.overlaysTemp;
+}
+
+exUnregisterer.prototype =
+{
+	
+	// properties 
+	
+	mTarget : 
+	{
+		packages : [],
+		locales  : [],
+		skins    : [],
+		overlays : [],
+		overlaysTemp : []
+	},
+ 
+	mEntriesURL : [], 
+ 
+	get Chrome() 
+	{
+		if (!this._Chrome) {
+			this._Chrome = this.getURISpecFromKey('AChrom');
+			if (!this._Chrome.match(/\/$/)) this._Chrome += '/';
+		}
+		return this._Chrome;
+	},
+	_Chrome : null,
+
+	get UChrome()
+	{
+		if (!this._UChrome) {
+			this._UChrome = this.getURISpecFromKey('UChrm');
+			if (!this._UChrome.match(/\/$/)) this._UChrome += '/';
+		}
+		return this._UChrome;
+	},
+	_UChrome : null,
+
+	get UChrm()
+	{
+		return this.UChrome;
+	},
+ 
+	get IOService() 
+	{
+		if (!this._IOService) {
+			this._IOService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
+		}
+		return this._IOService;
+	},
+	_IOService : null,
+ 
+	get RDF() 
+	{
+		if (!this._RDF) {
+			this._RDF = Components.classes['@mozilla.org/rdf/rdf-service;1'].getService(Components.interfaces.nsIRDFService);
+		}
+		return this._RDF;
+	},
+	_RDF : null,
+ 
+	get RDFC() 
+	{
+		if (!this._RDFC) {
+			this._RDFC = Components.classes['@mozilla.org/rdf/container;1'].createInstance(Components.interfaces.nsIRDFContainer);
+		}
+		return this._RDFC;
+	},
+	_RDFC : null,
+  
+	// Initialize 
+	init : function(aDsourcePaths)
+	{
+		var rootnode =
+			{
+				packages : 'urn:mozilla:package:root',
+				locales  : 'urn:mozilla:locale:root',
+				skins    : 'urn:mozilla:skin:root',
+				overlays : 'urn:mozilla:overlays'
+			},
+			dsource,
+			dsourcePaths = [],
+			i,
+			nodes,
+			node,
+			target;
+
+		for (i = 0; i < aDsourcePaths.length; i++)
+		{
+			if (aDsourcePaths[i].match(/%chromeFolder%/i)) {
+				dsourcePaths.push(aDsourcePaths[i].replace(/%chromeFolder%/gi, this.Chrome));
+				dsourcePaths.push(aDsourcePaths[i].replace(/%chromeFolder%/gi, this.UChrome));
+			}
+			else
+				dsourcePaths.push(aDsourcePaths[i]);
+		}
+
+		for (var j = 0; j < dsourcePaths.length; j++)
+		{
+			try {
+				if (this.RDF.GetDataSourceBlocking)
+					dsource = this.RDF.GetDataSourceBlocking(dsourcePaths[j]).QueryInterface(Components.interfaces.nsIRDFDataSource);
+				else
+					dsource = this.RDF.GetDataSource(dsourcePaths[j]);
+			}
+			catch(e) {
+				continue;
+			}
+
+			for (i in rootnode)
+			{
+				try {
+					this.RDFC.Init(dsource, this.RDF.GetResource(rootnode[i]));
+				}
+				catch(e) {
+					continue;
+				}
+
+				nodes = this.RDFC.GetElements();
+				while (nodes.hasMoreElements())
+				{
+					node = nodes.getNext();
+					node = node.QueryInterface(Components.interfaces.nsIRDFResource);
+					target = node.Value;
+					switch(i)
+					{
+						case 'locales':
+						case 'skins':
+							target += ':packages';
+							if (!this.mTarget[i][target])
+								this.mTarget[i][target] = [];
+							break;
+
+						case 'overlays':
+							if (!this.mTarget[i+'Temp'][target])
+								this.mTarget[i+'Temp'][target] = [];
+							break;
+
+						default:
+							this.mTarget[i][target] = true;
+							break;
+					}
+				}
+			}
+
+
+			var targets =
+				[
+					this.mTarget.locales,
+					this.mTarget.skins
+				];
+			for (var k in targets)
+			{
+				for (i in targets[k])
+				{
+					try {
+						this.RDFC.Init(dsource, this.RDF.GetResource(i));
+					}
+					catch(e) {
+						continue;
+					}
+					nodes = this.RDFC.GetElements();
+					while (nodes.hasMoreElements())
+					{
+						node = nodes.getNext();
+						node = node.QueryInterface(Components.interfaces.nsIRDFResource);
+						targets[k][i][node.Value] = true;
+					}
+				}
+			}
+
+			// overlays
+			for (i in this.mTarget.overlaysTemp)
+			{
+				try {
+					this.RDFC.Init(dsource, this.RDF.GetResource(i));
+				}
+				catch(e) {
+					continue;
+				}
+				nodes = this.RDFC.GetElements();
+				while (nodes.hasMoreElements())
+				{
+					node = nodes.getNext();
+					node = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
+					target = i.replace(/[^:]+:\/\/([^\/]+).+/, 'overlayinfo/$1/content/overlays.rdf');
+					if (!this.mTarget.overlays[target])
+						this.mTarget.overlays[target] = [];
+					if (!this.mTarget.overlays[target][i])
+						this.mTarget.overlays[target][i] = [];
+					this.mTarget.overlays[target][i][node.Value] = true;
+				}
+			}
+
+		}
+
+		return;
+	},
+	
+	// Get an URI from an internal keyword 
+	getURISpecFromKey : function(aKeyword)
+	{
+		const DIR = Components.classes['@mozilla.org/file/directory_service;1'].getService(Components.interfaces.nsIProperties);
+		var dir = DIR.get(aKeyword, Components.interfaces.nsIFile),
+			path;
+
+		try {
+			path = this.IOService.newFileURI(dir).spec;
+		}
+		catch(e) { // [[interchangeability for Mozilla 1.1]]
+			path = this.IOService.getURLSpecFromFile(dir);
+		}
+
+		return path;
+	},
+
+	getURI : function(aKeyword) // old implementation
+	{
+		return this.getURISpecFromKey(aKeyword);
+	},
+ 
+	// Convert an URI to a file path 
+	getFilePathFromURLSpec : function(aURL)
+	{
+		var url = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURI);
+			url.spec = aURL;
+
+		if (!url.schemeIs('file')) return '';
+
+		var tempLocalFile;
+		try {
+			var fileHandler = this.IOService.getProtocolHandler('file').QueryInterface(Components.interfaces.nsIFileProtocolHandler);
+			tempLocalFile = fileHandler.getFileFromURLSpec(aURL);
+		}
+		catch(e) { // [[interchangeability for Mozilla 1.1]]
+			try {
+				tempLocalFile = this.IOService.getFileFromURLSpec(aURL);
+			}
+			catch(ex) { // [[interchangeability for Mozilla 1.0.x]]
+				tempLocalFile = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
+				this.IOService.initFileFromURLSpec(tempLocalFile, aURL);
+			}
+		}
+		return tempLocalFile.path;
+	},
+
+	getFilePathFromURI : function(aURI) // old implementation
+	{
+		return this.getFilePathFromURLSpec(aURI);
+	},
+ 
+	// Convert a file path to an URI 
+	getURLSpecFromFilePath : function(aPath)
+	{
+		var tempLocalFile = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
+		tempLocalFile.initWithPath(aPath);
+
+		try {
+			return this.IOService.newFileURI(tempLocalFile).spec;
+		}
+		catch(e) { // [[interchangeability for Mozilla 1.1]]
+			return this.IOService.getURLSpecFromFile(tempLocalFile);
+		}
+	},
+ 
+	// does exist the file? 
+	exists : function(aFilePathOrURL)
+	{
+		if (aFilePathOrURL.match(/^file:/))
+			aFilePathOrURL = this.getFilePathFromURLSpec(aFilePathOrURL);
+
+		var tempLocalFile = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
+		tempLocalFile.initWithPath(aFilePathOrURL);
+		return tempLocalFile.exists();
+	},
+  
+	// Unregister information 
+	unregister : function()
+	{
+
+		// packages unregisteration
+		for (i in this.mTarget.packages)
+		{
+			this.removeResources(this.Chrome+'chrome.rdf', 'urn:mozilla:package:root', this.mTarget.packages);
+			this.removeResources(this.UChrome+'chrome.rdf', 'urn:mozilla:package:root', this.mTarget.packages);
+			this.removeResources(this.Chrome+'all-packages.rdf', 'urn:mozilla:package:root', this.mTarget.packages);
+		}
+
+		// locales unregistration
+		for (i in this.mTarget.locales)
+		{
+			this.removeResources(this.Chrome+'chrome.rdf', i, this.mTarget.locales[i]);
+			this.removeResources(this.UChrome+'chrome.rdf', i, this.mTarget.locales[i]);
+			this.removeResources(this.Chrome+'all-locales.rdf', i, this.mTarget.locales[i]);
+		}
+
+		// skins unregistration
+		for (i in this.mTarget.skins)
+		{
+			this.removeResources(this.Chrome+'chrome.rdf', i, this.mTarget.skins[i]);
+			this.removeResources(this.UChrome+'chrome.rdf', i, this.mTarget.skins[i]);
+			this.removeResources(this.Chrome+'all-skins.rdf', i, this.mTarget.skins[i]);
+		}
+
+		// overlays unregistration
+		for (i in this.mTarget.overlays)
+			for (j in this.mTarget.overlays[i])
+			{
+				this.removeResources(this.Chrome+i, j, this.mTarget.overlays[i][j]);
+				this.removeResources(this.UChrome+i, j, this.mTarget.overlays[i][j]);
+			}
+
+
+
+		// remove entries from installed-chrome.txt
+		var installedChrome = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
+		installedChrome.initWithPath(this.getFilePathFromURLSpec(this.Chrome+'installed-chrome.txt'));
+
+		var entries = this.readFrom(installedChrome);
+		var regexp  = new RegExp();
+		for (i in this.mEntriesURL)
+			entries = entries.replace(regexp.compile('[^\\n\\r]+'+this.mEntriesURL[i]+'[\\n\\r]+', 'g'), '');
+		this.writeTo(installedChrome, entries);
+
+
+		return;
+	},
+	
+	// Remove info from RDF files 
+	removeResources : function(aDsourcePath, aRootURI, aTargets)
+	{
+		var dsource;
+		try {
+			var dsource = this.RDF.GetDataSource(aDsourcePath);
+				dsource = dsource.QueryInterface(Components.interfaces.nsIRDFDataSource);
+		}
+		catch(e) {
+			return;
+		}
+
+		try {
+			this.RDFC.Init(dsource, this.RDF.GetResource(aRootURI));
+		}
+		catch(e) {
+//			dump('ERROR: cannot remove resources in '+rootnode);
+			return;
+		}
+
+		var nodes = this.RDFC.GetElements(),
+			node,
+			removenode,
+			removenodes = [],
+			removename,
+			removenames,
+			removevalue;
+
+		while (nodes.hasMoreElements())
+		{
+			node = nodes.getNext();
+			try {
+				node = node.QueryInterface(Components.interfaces.nsIRDFResource);
+			}
+			catch(e) {
+				node = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
+			}
+
+			if (!node || (aTargets && !aTargets[node.Value])) continue;
+
+			try {
+				removenode = (aDsourcePath.match(/overlays\.rdf$/)) ? this.RDF.GetLiteral(node.Value) : this.RDF.GetResource(node.Value) ;
+
+				removenodes.push(removenode);
+
+				// If the file is "overlays.rdf", then this block is skipped.
+				try {
+					removenames = dsource.ArcLabelsOut(removenode);
+					while (removenames.hasMoreElements())
+					{
+						removename = removenames.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
+						removevalue = dsource.GetTarget(removenode, removename, true);
+						if (removename.Value.match(/#baseURL$/))
+							this.mEntriesURL.push(removevalue.QueryInterface(Components.interfaces.nsIRDFLiteral).Value);
+
+						dsource.Unassert(removenode, removename, removevalue);
+					}
+				}
+				catch(e) {
+				}
+			}
+			catch(e) {
+//				dump('cannot remove '+node.Value+' from '+rooturi);
+			}
+		}
+
+		for (var i in removenodes)
+			this.RDFC.RemoveElement(removenodes[i], true);
+
+		// remove empty container from "overlays.rdf"
+		if (!this.RDFC.GetCount()) {
+			removenames = dsource.ArcLabelsOut(this.RDFC.Resource);
+			while (removenames.hasMoreElements())
+			{
+				removename = removenames.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
+				removevalue = dsource.GetTarget(this.RDFC.Resource, removename, true);
+				dsource.Unassert(this.RDFC.Resource, removename, removevalue);
+			}
+		}
+
+		dsource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush();
+		return;
+	},
+  
+	// Remove all user preferences containing the argument "branch" in the top of the name. 
+	removePrefs : function(aBranch)
+	{
+		//const Prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch(branch+'.');
+		const Prefs = Components.classes['@mozilla.org/preferences;1'].getService(Components.interfaces.nsIPrefBranch);
+
+		try {
+			var prefs = Prefs.getChildList(aBranch+'.', { value: 0 });
+			for (var i in prefs) Prefs.clearUserPref(prefs[i]);
+		}
+		catch(e) {
+//			dump('ERROR: cannot clear user preferences.');
+		}
+
+		return;
+	},
+ 
+	// File I/O 
+	
+	readFrom : function(aFile) 
+	{
+		var stream = Components.classes['@mozilla.org/network/file-input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream);
+		stream.init(aFile, 1, 0, false); // open as "read only"
+
+		var scriptableStream = Components.classes['@mozilla.org/scriptableinputstream;1'].createInstance(Components.interfaces.nsIScriptableInputStream);
+		scriptableStream.init(stream);
+
+		var fileSize = scriptableStream.available();
+		var fileContents = scriptableStream.read(fileSize);
+
+		scriptableStream.close();
+		stream.close();
+
+		return fileContents;
+	},
+ 
+	writeTo : function(aFile, aContent) 
+	{
+		if (aFile.exists()) aFile.remove(true);
+		aFile.create(aFile.NORMAL_FILE_TYPE, 0666);
+
+		var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
+		stream.init(aFile, 2, 0x200, false); // open as "write only"
+
+		stream.write(aContent, aContent.length);
+
+		stream.close();
+	}
+   
+} 
+ 
diff --git a/src/sage/content/settings/settings.js b/src/sage/content/settings/settings.js
new file mode 100755
index 0000000..a7c3053
--- /dev/null
+++ b/src/sage/content/settings/settings.js
@@ -0,0 +1,168 @@
+
+const RSS_READER_FOLDER_ID = CommonFunc.RSS_READER_FOLDER_ID;
+const USER_CSS_ENABLE = "sage.user_css.enable";
+const USER_CSS_PATH = "sage.user_css.path";
+const ALLOW_ENCODED_CONTENT = "sage.allow_encoded_content";
+
+var sageFolderID;
+
+var chkUserCssEnable;
+var txtUserCssPath;
+var chkAllowEContent;
+
+var gList;
+var gNameArc;
+var strRes // stringbundle �I�u�W�F�N�g
+
+function init(){
+	initServices();
+	initBMService();
+	
+	strRes = document.getElementById("strRes");
+	
+  		// �ݒ�̓ǂݍ���
+  	sageFolderID = CommonFunc.getPrefValue(RSS_READER_FOLDER_ID, "str", "NC:BookmarksRoot");
+	gNameArc = RDF.GetResource(NC_NS + "Name");
+	gList = document.getElementById("select-menu");
+
+	chkUserCssEnable = document.getElementById("chkUserCssEnable");
+	chkUserCssEnable.checked = CommonFunc.getPrefValue(USER_CSS_ENABLE, "bool", false);
+
+	txtUserCssPath = document.getElementById("txtUserCssPath");
+	txtUserCssPath.value = CommonFunc.getPrefValue(USER_CSS_PATH, "wstr", "");
+
+	chkAllowEContent = document.getElementById("chkAllowEContent");
+	chkAllowEContent.checked = CommonFunc.getPrefValue(ALLOW_ENCODED_CONTENT, "bool", false);
+
+
+	setDisabled();
+
+	setTimeout(fillSelectFolderMenupopup, 0);
+}
+
+function accept(){
+	// �ݒ�̏�������
+	CommonFunc.setPrefValue(RSS_READER_FOLDER_ID, "str", sageFolderID);
+	CommonFunc.setPrefValue(USER_CSS_ENABLE, "bool", chkUserCssEnable.checked);
+	CommonFunc.setPrefValue(USER_CSS_PATH, "wstr", txtUserCssPath.value);
+	CommonFunc.setPrefValue(ALLOW_ENCODED_CONTENT, "bool", chkAllowEContent.checked);
+}
+
+function uninstall(){
+	var prompt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+
+	var checkValue = { value: true };
+	
+	if(!prompt.confirmCheck(window,
+		strRes.getString("UNINST_TITLE"),
+		strRes.getString("UNINST_TEXT"),
+		strRes.getString("UNINST_CHECKMSG"), checkValue)) {
+		
+		return;
+	}
+
+		// RSS Reader Panel ���J���Ă����ꍇ�͕‚���
+	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
+	var windowEnum = windowManager.getEnumerator("navigator:browser");
+	while(windowEnum.hasMoreElements()) {
+		var browserWin = windowEnum.getNext();
+		browserWin.QueryInterface(Components.interfaces.nsIDOMWindowInternal);
+
+		var elt = browserWin.document.getElementById("viewSageSidebar");
+		if(elt.getAttribute("checked") == "true") {
+			var sidebarTitle = browserWin.document.getElementById("sidebar-title");
+			var sidebarBox = browserWin.document.getElementById("sidebar-box");
+			var sidebarSplitter = browserWin.document.getElementById("sidebar-splitter");
+			elt.removeAttribute("checked");
+			sidebarBox.setAttribute("sidebarcommand", "");
+			sidebarTitle.setAttribute("value", "");
+			sidebarBox.hidden = true;
+			sidebarSplitter.hidden = true;
+		}
+	}
+
+	// Remove preferences if requested
+	if(checkValue.value) {
+		CommonFunc.removePrefs();
+	}
+
+	var unreg = new exUnregisterer(
+		'chrome://sage/content/contents.rdf',
+		'jar:%chromeFolder%sage.jar!/skin/classic/contents.rdf',
+		'jar:%chromeFolder%sage.jar!/locale/en-US/contents.rdf',
+		'jar:%chromeFolder%sage.jar!/locale/ja-JP/contents.rdf');
+
+	unreg.unregister();
+	
+	alert("Uninstall Completed");
+	window.close();
+}
+
+
+function selectFolder(aEvent){
+	sageFolderID = aEvent.target.id;
+}
+
+
+function setDisabled(){
+	txtUserCssPath.disabled = !chkUserCssEnable.checked;
+	document.getElementById("btnBrowseCss").disabled = !chkUserCssEnable.checked;
+}
+
+
+function browseCss(){
+	var fpicker = Components.classes["@mozilla.org/filepicker;1"]
+					.createInstance(Components.interfaces.nsIFilePicker);
+	fpicker.init(window, "Select CSS File", fpicker.modeOpen);
+	fpicker.appendFilter("CSS File(*.css)", "*.css");
+	fpicker.appendFilters(fpicker.filterAll);
+
+	var showResult = fpicker.show();
+	if(showResult == fpicker.returnOK){
+		txtUserCssPath.value = fpicker.file.path;	
+	}
+}
+
+function fillSelectFolderMenupopup (){
+	var popup = document.getElementById("select-folder");
+
+	// clearing the old menupopup
+	while (popup.hasChildNodes()){
+		popup.removeChild(popup.firstChild);
+	}
+
+	// to be removed once I checkin the top folder
+	var element = document.createElementNS(XUL_NS, "menuitem");
+	element.setAttribute("label", "Bookmarks");
+	element.setAttribute("id", "NC:BookmarksRoot");
+	popup.appendChild(element);
+
+	var folder = RDF.GetResource("NC:BookmarksRoot");
+	fillFolder(popup, folder, 1);
+	if(gList.selectedIndex == -1){
+		gList.selectedIndex = 0;
+		sageFolderID = "NC:BookmarksRoot";
+	}
+}
+
+function fillFolder(aPopup, aFolder, aDepth){
+	RDFC.Init(BMDS, aFolder);
+	var children = RDFC.GetElements();
+	while (children.hasMoreElements()){
+		var curr = children.getNext();
+		if (RDFCU.IsContainer(BMDS, curr)) {
+			curr = curr.QueryInterface(Components.interfaces.nsIRDFResource);
+			var element = document.createElementNS(XUL_NS, "menuitem");
+			var name = BMDS.GetTarget(curr, gNameArc, true).QueryInterface(kRDFLITIID).Value;
+			var indentation = new Array(aDepth + 1).join("   ");
+			element.setAttribute("label", indentation + name);
+			element.setAttribute("id", curr.Value);
+			aPopup.appendChild(element);
+			if (curr.Value == sageFolderID){
+				gList.selectedItem = element;
+			}
+			fillFolder(aPopup, curr, ++aDepth);
+			--aDepth;
+		}
+	}
+}
diff --git a/src/sage/content/settings/settings.xul b/src/sage/content/settings/settings.xul
new file mode 100755
index 0000000..29012f1
--- /dev/null
+++ b/src/sage/content/settings/settings.xul
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/bookmarks/bookmarks.css"?>
+
+<!DOCTYPE window SYSTEM "chrome://sage/locale/sage.dtd">
+<dialog id="winMain" title="&settingWindow.title;" style="min-width:400px;"
+		onload="init();" ondialogaccept="accept()"
+		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://browser/content/bookmarks/bookmarks.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/commonfunc.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/settings/exUnregisterer.js"/>
+<script type="application/x-javascript" src="chrome://sage/content/settings/settings.js"/>
+
+
+<dialogheader title="&sage.label;" description="&sage.label; version &sage.version;"/>
+
+<stringbundleset>
+	<stringbundle id="strRes" src="chrome://sage/locale/sage.properties"/>
+</stringbundleset>
+
+<hbox style="padding:5px 0px 10px 0px">
+<groupbox flex="1">
+	<caption label="&selectFolder.label;"/>
+	
+	<menulist id="select-menu" oncommand="selectFolder(event);">
+		<menupopup id="select-folder"/>
+	</menulist>
+</groupbox>
+<groupbox orient="horizontal" align="center">
+	<caption label="&uninstall.label;"/>
+	<button label="&uninstall.label;" oncommand="uninstall()"/>
+</groupbox>
+</hbox>
+
+<groupbox>
+	<caption label="&openInContentsArea.caption;"/>
+	<vbox flex="1">
+		<checkbox id="chkUserCssEnable" label="&enableUserCss.label;" oncommand="setDisabled()"/>
+		<hbox align="center">
+			<spacer width="30"/>
+			<textbox id="txtUserCssPath" flex="1"/>
+			<button id="btnBrowseCss" oncommand="browseCss()" label="&browseCss.label;"/>
+		</hbox>
+	</vbox>
+	<checkbox id="chkAllowEContent" label="&allowEContent.label;"/>
+</groupbox>
+
+</dialog>
+
diff --git a/src/sage/content/updatechecker.js b/src/sage/content/updatechecker.js
new file mode 100755
index 0000000..29fe547
--- /dev/null
+++ b/src/sage/content/updatechecker.js
@@ -0,0 +1,124 @@
+var UpdateChecker = {
+	checking: false,
+	resourceList: null,
+	httpReq: null,
+	lastResource: null,
+
+	startCheck: function(aCheckFolderId){
+		if(this.checking) return;
+	
+		this.resourceList = CommonFunc.getBMDSCChildren(aCheckFolderId);
+		
+			// Delete separator and updeed resource
+		for(var i=0; i<this.resourceList.length; i++){
+			var url = CommonFunc.getBMDSProperty(this.resourceList[i], CommonFunc.BM_URL);
+			var desc = CommonFunc.getBMDSProperty(this.resourceList[i], CommonFunc.BM_DESCRIPTION);
+			if(!url || desc == CommonFunc.STATUS_UPDATE || desc == CommonFunc.STATUS_NO_CHECK){
+				this.resourceList.splice(i,1);
+			}
+		}
+		
+		this.checking = true;
+		this.check();
+	},
+
+	done: function(){
+		if(this.checking){
+			this.httpReq.abort();
+		}
+	},
+
+	check: function(){
+		this.lastResource = this.resourceList.shift();
+		var name = CommonFunc.getBMDSProperty(this.lastResource, CommonFunc.BM_NAME);
+		var url = CommonFunc.getBMDSProperty(this.lastResource, CommonFunc.BM_URL);
+
+		if(!url){
+			this.checkResult(false, 0);
+		}
+
+		if(this.httpReq){
+			this.httpReq.abort();
+		}
+		
+		this.httpReq = new XMLHttpRequest();
+		this.httpReq.parent = this;
+		this.httpReq.onload = this.httpLoaded;
+		this.httpReq.onreadystatechange = this.httpReadyStateChange;
+		this.httpReq.open("HEAD", url);
+		this.httpReq.setRequestHeader("User-Agent", USER_AGENT);
+		this.httpReq.overrideMimeType("application/xml");
+		try{
+			this.httpReq.send(null);
+			this.onCheck(name, url);
+		}catch(e){
+				// FAILURE
+			this.httpReq.abort();
+			this.checkResult(false, 0);
+		}
+	},
+
+
+	httpReadyStateChange: function(){
+		if(UpdateChecker.httpReq.readyState == 2){
+			try{
+				UpdateChecker.httpReq.status;
+			}catch(e){
+					// URL NOT AVAILABLE
+				UpdateChecker.httpReq.abort();
+				UpdateChecker.checkResult(false, 0);
+			}
+		}
+	},
+
+	httpLoaded: function(e) {
+		var lastModified = 0;
+		var gettingLastModified = false;
+		
+		try {
+			lastModified = UpdateChecker.httpReq.getResponseHeader("Last-modified");
+			lastModified = new Date(lastModified).getTime() * 1000;
+		} catch(e) {}
+		
+		UpdateChecker.checkResult(true, lastModified);
+	},
+
+	checkResult: function(aSucceed, aLastModified) {
+		var name = CommonFunc.getBMDSProperty(this.lastResource, CommonFunc.BM_NAME);
+		var url = CommonFunc.getBMDSProperty(this.lastResource, CommonFunc.BM_URL);
+		var status = 0;
+
+		if(aLastModified) {
+			var lastVisit = CommonFunc.getBMDSProperty(this.lastResource, CommonFunc.BM_LAST_VISIT);
+			if(!lastVisit) { lastVisit = 0; }
+	
+			var updated = (aLastModified > lastVisit);
+			if(updated) {
+				status = CommonFunc.STATUS_UPDATE;
+			} else {
+				status = CommonFunc.STATUS_NO_UPDATE;
+			}
+		} else {
+			if(aSucceed) {
+				status = CommonFunc.STATUS_UNKNOWN;
+			} else {
+				status = CommonFunc.STATUS_ERROR;
+			}
+		}
+
+		CommonFunc.setBMDSProperty(this.lastResource, CommonFunc.BM_DESCRIPTION, status);
+		
+		if(this.resourceList.length == 0) {
+			this.checking = false;
+			this.onChecked(name, url);
+			return;
+		} else {
+			this.check();
+		}
+	},
+
+
+	onCheck: function(aName, aURL) {},
+	onChecked: function(aName, aURL) {}
+
+}
\ No newline at end of file
diff --git a/src/sage/locale/en-US/contents.rdf b/src/sage/locale/en-US/contents.rdf
new file mode 100755
index 0000000..8d382cc
--- /dev/null
+++ b/src/sage/locale/en-US/contents.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+		 xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+
+	<RDF:Seq about="urn:mozilla:locale:root">
+		<RDF:li resource="urn:mozilla:locale:en-US"/>
+	</RDF:Seq>
+
+	<RDF:Description about="urn:mozilla:locale:en-US">
+		<chrome:packages>
+			<RDF:Seq about="urn:mozilla:locale:en-US:packages">
+				<RDF:li resource="urn:mozilla:locale:en-US:sage"/>
+			</RDF:Seq>
+		</chrome:packages>
+	</RDF:Description>
+</RDF:RDF>
diff --git a/src/sage/locale/en-US/opml.dtd b/src/sage/locale/en-US/opml.dtd
new file mode 100755
index 0000000..5743af3
--- /dev/null
+++ b/src/sage/locale/en-US/opml.dtd
@@ -0,0 +1,11 @@
+<!ENTITY pageStart.label			"OPML Import/Export Wizard">
+<!ENTITY pageStart.desc				"Choose an action">
+<!ENTITY pageImport.label			"Import OPML">
+<!ENTITY pageImport.desc			"Select Import OPML File">
+<!ENTITY pageExport.label			"Export OPML">
+<!ENTITY pageExport.desc			"Select Export OPML File">
+
+<!ENTITY rdoImport.label			"Import OPML">
+<!ENTITY rdoExport.label			"Export OPML">
+
+<!ENTITY browseButton.label			"Browse...">
diff --git a/src/sage/locale/en-US/sage.dtd b/src/sage/locale/en-US/sage.dtd
new file mode 100755
index 0000000..d6b3f9f
--- /dev/null
+++ b/src/sage/locale/en-US/sage.dtd
@@ -0,0 +1,31 @@
+<!ENTITY sage.label				"Sage">
+<!ENTITY sage.version				"1.0">
+
+<!ENTITY sage.toolbarLabel			"Sage">
+<!ENTITY sage.sidebarTitle			"Sage">
+<!ENTITY sage.tooltip				"Displays Sage">
+
+<!ENTITY menu.view				"View">
+<!ENTITY menu.showSearchBar			"Show Feed Search Bar">
+<!ENTITY menu.showFeedItemList			"Show Feed Item List">
+<!ENTITY menu.showDescTooltip			"Show Description Tooltips">
+<!ENTITY menu.openHTML				"Open Feeds In Contents Area">
+<!ENTITY menu.tools				"Options">
+<!ENTITY menu.checkUpdate			"Check Feeds">
+<!ENTITY menu.manageRSSList			"Manage Feed List...">
+<!ENTITY menu.opmlImportExport			"OPML Import/Export...">
+<!ENTITY menu.setting				"Settings...">
+
+
+<!-- Setting Dialog -->
+<!ENTITY settingWindow.title                    "Sage Settings">
+<!ENTITY selectFolder.label			"Select Feed Folder">
+<!ENTITY uninstall.label			"Uninstall">
+<!ENTITY openInContentsArea.caption		"Open In Contents Area">
+<!ENTITY enableUserCss.label			"Use custom CSS">
+<!ENTITY browseCss.label			"Browse...">
+<!ENTITY allowEContent.label			"Allow HTML Tags">
+
+
+<!ENTITY openSageSidebar.commandkey		"S">
+<!ENTITY openSageSidebar.modifiersKey		"alt">
\ No newline at end of file
diff --git a/src/sage/locale/en-US/sage.properties b/src/sage/locale/en-US/sage.properties
new file mode 100755
index 0000000..ce89f4c
--- /dev/null
+++ b/src/sage/locale/en-US/sage.properties
@@ -0,0 +1,13 @@
+RESULT_OK_STR = OK
+RESULT_PARSE_ERROR_STR = XML Parse Error
+RESULT_NOT_RSS_STR = This XML File Is Not RSS File
+RESULT_NOT_FOUND_STR = File Not Found
+RESULT_NOT_AVAILABLE_STR = Not Available URL
+RESULT_ERROR_FAILURE_STR = Load Failure
+
+CHECK_UPDATE = Check Feeds
+GET_RSS_TITLE= Get Feed Title
+
+UNINST_TITLE = Sage Uninstallation
+UNINST_TEXT = Uninstall Sage?
+UNINST_CHECKMSG = Remove Preferences
\ No newline at end of file
diff --git a/src/sage/locale/ja-JP/contents.rdf b/src/sage/locale/ja-JP/contents.rdf
new file mode 100755
index 0000000..919e538
--- /dev/null
+++ b/src/sage/locale/ja-JP/contents.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+		 xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+
+	<RDF:Seq about="urn:mozilla:locale:root">
+		<RDF:li resource="urn:mozilla:locale:ja-JP"/>
+	</RDF:Seq>
+
+	<RDF:Description about="urn:mozilla:locale:ja-JP">
+		<chrome:packages>
+			<RDF:Seq about="urn:mozilla:locale:ja-JP:packages">
+				<RDF:li resource="urn:mozilla:locale:ja-JP:sage"/>
+			</RDF:Seq>
+		</chrome:packages>
+	</RDF:Description>
+</RDF:RDF>
diff --git a/src/sage/locale/ja-JP/opml.dtd b/src/sage/locale/ja-JP/opml.dtd
new file mode 100755
index 0000000..4d646a8
--- /dev/null
+++ b/src/sage/locale/ja-JP/opml.dtd
@@ -0,0 +1,11 @@
+<!ENTITY pageStart.label			"OPML インポート/エクスポート ウィザード">
+<!ENTITY pageStart.desc				"動作を選択してください">
+<!ENTITY pageImport.label			"OPML のインポート">
+<!ENTITY pageImport.desc			"読み込む OPML ファイルを選択してください">
+<!ENTITY pageExport.label			"OPML のエクスポート">
+<!ENTITY pageExport.desc			"書き込む OPML ファイルを選択してください">
+
+<!ENTITY rdoImport.label			"OPML のインポート">
+<!ENTITY rdoExport.label			"OPML のエクスポート">
+
+<!ENTITY browseButton.label			"参照...">
diff --git a/src/sage/locale/ja-JP/sage.dtd b/src/sage/locale/ja-JP/sage.dtd
new file mode 100755
index 0000000..70eb3bc
--- /dev/null
+++ b/src/sage/locale/ja-JP/sage.dtd
@@ -0,0 +1,32 @@
+<!ENTITY sage.label			"RSS リーダパネル">
+<!ENTITY sage.version			"1.7">
+
+<!ENTITY sage.toolbarLabel		"RSS リーダ">
+<!ENTITY sage.sidebarTitle		"RSS リーダ">
+<!ENTITY sage.tooltip			"RSS リーダパネルを表示">
+
+
+<!ENTITY menu.view					"表示">
+<!ENTITY menu.showSearchBar			"Feed 検索バーの表示">
+<!ENTITY menu.showFeedItemList			"Show Feed Item List">
+<!ENTITY menu.showDescTooltip		"Description ツールチップの表示">
+<!ENTITY menu.openHTML				"コンテンツエリアで開く">
+<!ENTITY menu.tools					"ツール">
+<!ENTITY menu.checkUpdate			"更新チェック">
+<!ENTITY menu.manageRSSList			"RSS リストの管理">
+<!ENTITY menu.opmlImportExport		"OPML インポート/エクスポート...">
+<!ENTITY menu.setting				"設定...">
+
+
+<!-- Setting Dialog -->
+<!ENTITY settingWindow.title		"設定: RSS リーダパネル">
+<!ENTITY selectFolder.label			"RSS リストフォルダの選択">
+<!ENTITY uninstall.label			"アンインストール">
+<!ENTITY openInContentsArea.caption	"コンテンツエリアで開く">
+<!ENTITY enableUserCss.label		"ユーザー CSS を使う">
+<!ENTITY browseCss.label			"参照...">
+<!ENTITY allowEContent.label		"HTML タグを許可する">
+
+
+<!ENTITY openSageSidebar.commandkey	"S">
+<!ENTITY openSageSidebar.modifiersKey	"alt">
\ No newline at end of file
diff --git a/src/sage/locale/ja-JP/sage.properties b/src/sage/locale/ja-JP/sage.properties
new file mode 100755
index 0000000..83d3c49
--- /dev/null
+++ b/src/sage/locale/ja-JP/sage.properties
@@ -0,0 +1,13 @@
+RESULT_OK_STR = OK
+RESULT_PARSE_ERROR_STR = XML \u30d1\u30fc\u30b9\u30a8\u30e9\u30fc
+RESULT_NOT_RSS_STR = \u3053\u306e XML \u30d5\u30a1\u30a4\u30eb\u306f RSS \u3067\u306f\u3042\u308a\u307e\u305b\u3093
+RESULT_NOT_FOUND_STR = \u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+RESULT_NOT_AVAILABLE_STR = \u5b58\u5728\u3057\u306a\u3044 URL \u3067\u3059
+RESULT_ERROR_FAILURE_STR = \u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+
+CHECK_UPDATE = \u66f4\u65b0\u30c1\u30a7\u30c3\u30af
+GET_RSS_TITLE= RSS \u30bf\u30a4\u30c8\u30eb\u306e\u53d6\u5f97
+
+UNINST_TITLE = RSS Reader Panel \u30a2\u30f3\u30a4\u30f3\u30b9\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3
+UNINST_TEXT = RSS Reader Panel \u3092\u30a2\u30f3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u304b?
+UNINST_CHECKMSG = \u8a2d\u5b9a\u3082\u524a\u9664\u3059\u308b
\ No newline at end of file
diff --git a/src/sage/skin/classic/contents.rdf b/src/sage/skin/classic/contents.rdf
new file mode 100755
index 0000000..c768778
--- /dev/null
+++ b/src/sage/skin/classic/contents.rdf
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+		 xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+
+	<RDF:Seq about="urn:mozilla:skin:root">
+		<RDF:li resource="urn:mozilla:skin:classic/1.0" />
+	</RDF:Seq>
+	
+	<RDF:Description about="urn:mozilla:skin:classic/1.0">
+		<chrome:packages>
+			<RDF:Seq about="urn:mozilla:skin:classic/1.0:packages">
+				<RDF:li resource="urn:mozilla:skin:classic/1.0:sage"/>
+			</RDF:Seq>
+		</chrome:packages>
+	</RDF:Description>
+
+
+	<RDF:Seq about="urn:mozilla:stylesheets">
+		<RDF:li resource="chrome://browser/content/browser.xul"/>
+		<RDF:li resource="chrome://global/content/customizeToolbar.xul"/>
+	</RDF:Seq>
+	<RDF:Seq about="chrome://browser/content/browser.xul">
+		<RDF:li>chrome://sage/skin/sage-button.css</RDF:li>
+	</RDF:Seq>
+	<RDF:Seq about="chrome://global/content/customizeToolbar.xul">
+		<RDF:li>chrome://sage/skin/sage-button.css</RDF:li>
+	</RDF:Seq>
+</RDF:RDF>
diff --git a/src/sage/skin/classic/icon/checking.gif b/src/sage/skin/classic/icon/checking.gif
new file mode 100755
index 0000000..c91e58e
Binary files /dev/null and b/src/sage/skin/classic/icon/checking.gif differ
diff --git a/src/sage/skin/classic/icon/error.gif b/src/sage/skin/classic/icon/error.gif
new file mode 100755
index 0000000..f5ce7b5
Binary files /dev/null and b/src/sage/skin/classic/icon/error.gif differ
diff --git a/src/sage/skin/classic/icon/no-updated.png b/src/sage/skin/classic/icon/no-updated.png
new file mode 100755
index 0000000..589266f
Binary files /dev/null and b/src/sage/skin/classic/icon/no-updated.png differ
diff --git a/src/sage/skin/classic/icon/search-submit.gif b/src/sage/skin/classic/icon/search-submit.gif
new file mode 100755
index 0000000..f922ee9
Binary files /dev/null and b/src/sage/skin/classic/icon/search-submit.gif differ
diff --git a/src/sage/skin/classic/icon/unknown.png b/src/sage/skin/classic/icon/unknown.png
new file mode 100755
index 0000000..2326691
Binary files /dev/null and b/src/sage/skin/classic/icon/unknown.png differ
diff --git a/src/sage/skin/classic/icon/updated.png b/src/sage/skin/classic/icon/updated.png
new file mode 100755
index 0000000..594c9ab
Binary files /dev/null and b/src/sage/skin/classic/icon/updated.png differ
diff --git a/src/sage/skin/classic/sage-button.css b/src/sage/skin/classic/sage-button.css
new file mode 100755
index 0000000..b412160
--- /dev/null
+++ b/src/sage/skin/classic/sage-button.css
@@ -0,0 +1,9 @@
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#sage-button {
+  list-style-image: url("chrome://sage/skin/sage.png");
+}
+
+toolbar[iconsize="small"] #sage-button {
+  list-style-image: url("chrome://sage/skin/sage-small.png");
+}
\ No newline at end of file
diff --git a/src/sage/skin/classic/sage-small.png b/src/sage/skin/classic/sage-small.png
new file mode 100644
index 0000000..355e368
Binary files /dev/null and b/src/sage/skin/classic/sage-small.png differ
diff --git a/src/sage/skin/classic/sage.css b/src/sage/skin/classic/sage.css
new file mode 100755
index 0000000..8b7ec84
--- /dev/null
+++ b/src/sage/skin/classic/sage.css
@@ -0,0 +1,108 @@
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#bookmarksTree {
+  -moz-binding: url("chrome://sage/content/bookmarksTree.xml#bookmarks-tree-name");
+}
+
+treechildren::-moz-tree-image(rss, updated) {
+  -moz-image-region: auto !important;
+  list-style-image: url("chrome://sage/skin/icon/updated.png") !important;
+}
+treechildren::-moz-tree-image(rss, no-updated),
+treechildren::-moz-tree-image(rss, no-check) {
+  -moz-image-region: auto !important;
+  list-style-image: url("chrome://sage/skin/icon/no-updated.png") !important;
+}
+treechildren::-moz-tree-image(rss, unknown) {
+  -moz-image-region: auto !important;
+  list-style-image: url("chrome://sage/skin/icon/unknown.png") !important;
+}
+treechildren::-moz-tree-image(rss, error) {
+  -moz-image-region: auto !important;
+  list-style-image: url("chrome://sage/skin/icon/error.gif") !important;
+}
+
+#bookmarksTreeBox,
+#rssItemListBoxBox {
+  min-height: 90px;
+}
+
+#rssItemListBox > listitem {
+}
+
+#rssItemListBox > listitem[visited="true"] {
+  color: #39A;
+}
+
+
+#sage-splitter {
+  border: none;
+  border-bottom: 1px solid ThreeDLightShadow;
+}
+
+#rssStatusImage {
+  margin-left: 4px;
+  width: 16px;
+  height: 16px;
+}
+#rssStatusImage[loading="true"] {
+  list-style-image: url("chrome://sage/skin/icon/checking.gif");
+}
+#rssStatusImage[loading="error"] {
+  list-style-image: url("chrome://sage/skin/icon/error.gif");
+}
+
+#rssTitleLabel[href]:hover{
+  text-decoration: underline;
+  cursor: pointer;
+}
+
+
+/* ++++++++++ Search ++++++++++ */
+#barSearch {
+  padding-bottom: 2px;
+}
+
+#imgSearchEngine {
+  width: 16px;
+  height: 16px;
+}
+
+#btnSearchSubmit {
+  -moz-appearance: none;
+  margin: 2px 2px 2px 0px;
+  min-width: 0px;
+  min-height: 0px;
+  list-style-image: url("chrome://sage/skin/icon/search-submit.gif");
+}
+
+/* ++++++++++ popupEX ++++++++++ */
+
+.popupex {
+  -moz-binding : url(chrome://sage/content/popupex.xml#popupex);
+  -moz-appearance: tooltip;
+  display: -moz-popup;
+
+  border: 1px solid InfoText;
+  width: 26em;
+  max-width: 26em;
+  background-color: InfoBackground;
+  color: InfoText;
+  font: message-box;
+
+  margin: 0px !important;
+  padding: 0px !important;
+}
+
+.popupex-title {
+  font-weight: bold;
+  margin: 0px !important;
+  padding: 3px !important;
+  -moz-box-flex: 1;
+}
+
+.popupex-description {
+  margin: 0px !important;
+  padding: 5px 5px 5px 20px !important;
+  -moz-box-flex: 1;
+}
\ No newline at end of file
diff --git a/src/sage/skin/classic/sage.png b/src/sage/skin/classic/sage.png
new file mode 100644
index 0000000..ee8e7e7
Binary files /dev/null and b/src/sage/skin/classic/sage.png differ

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/sage-extension.git



More information about the Pkg-mozext-commits mailing list