[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