home *** CD-ROM | disk | FTP | other *** search
- /* ***** 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 NewsFox.
- *
- * The Initial Developer of the Original Code is
- * Andy Frank <andy@andyfrank.com>.
- * Portions created by the Initial Developer are Copyright (C) 2005-2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Andrey Gromyko <andrey@gromyko.name>
- * Ron Pruitt <wa84it@gmail.com>
- *
- * 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 LGPL or the GPL. 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 ***** */
-
- var scKeyList = new Array();
-
- ////////////////////////////////////////////////////////////////
- // Text view
- ////////////////////////////////////////////////////////////////
-
- function getTextView(art)
- {
- if (gOptions.copyToClip)
- {
- var trans = Components.classes["@mozilla.org/widget/transferable;1"]
- .createInstance(Components.interfaces.nsITransferable);
- trans.addDataFlavor("text/html");
- trans.addDataFlavor("text/unicode");
-
- var htmlStr = Components.classes["@mozilla.org/supports-string;1"]
- .createInstance(Components.interfaces.nsISupportsString);
- htmlStr.data = art.body;
-
- trans.setTransferData("text/html",htmlStr, htmlStr.toString().length);
- trans.setTransferData("text/unicode",htmlStr, htmlStr.toString().length);
-
- var clipId = Components.interfaces.nsIClipboard;
- var clipB = Components.classes["@mozilla.org/widget/clipboard;1"]
- .getService(clipId);
- clipB.setData(trans,null,clipId.kGlobalClipboard);
- }
-
- var iframe = document.getElementById("buildContent");
- var doc = iframe.contentDocument;
- iframe.docShell.allowJavascript = false;
-
- while (doc.body.childNodes.length > 0) doc.body.removeChild(doc.body.childNodes[0]);
-
- var div = doc.createElement("div");
- div.setAttribute("id","newsfox-box");
- var s = doc.createElement("span");
- s.setAttribute("class","newsfox-mail");
- var a = doc.createElement("a");
- a.setAttribute("href",makeMailto(art.title,art.link));
- var img = doc.createElement("img");
- img.setAttribute("src","chrome://newsfox/skin/images/mail.png");
- img.setAttribute("style","border: 0px; padding-right: 7px;");
- a.appendChild(img);
- s.appendChild(a);
- div.appendChild(s);
- var b = getXhtmlBody(art.title,"b",doc);
- b.setAttribute("class","newsfox-title");
- b.appendChild(doc.createElement("br"));
- div.appendChild(b);
- var p = doc.createElement("span");
- p.setAttribute("class","newsfox-category");
- p.innerHTML = "";
- if (art.category != "") p.innerHTML += emphsrch(art.category) + ": ";
- div.appendChild(p);
- var p2 = doc.createElement("span");
- p2.setAttribute("class","newsfox-date");
- p2.innerHTML = displayDate(art.date, LONG_DATE_STYLE) + "<br/>";
- div.appendChild(p2);
- if (art.link)
- {
- var a = doc.createElement("a");
- a.setAttribute("href", art.link);
- a.setAttribute("target", "_blank");
- a.setAttribute("class","newsfox-link");
- a.innerHTML = art.link + "<br/>";
- div.appendChild(a);
- }
-
- if (art.enclosures.length > 0)
- {
- var s = doc.createElement("span");
- s.setAttribute("class","newsfox-enclosures");
- for (var i=0; i<art.enclosures.length; i++)
- {
- var artenc = art.enclosures[i];
- var nobr = doc.createElement("span"); // xhtml equivalent of <nobr>
- nobr.setAttribute("style","white-space: nowrap;");
- var a = doc.createElement("a");
- a.setAttribute("class","newsfox-encl");
- a.setAttribute("href", artenc.url);
- a.setAttribute("target","_blank");
- var img = doc.createElement("img");
- var imgsrc;
- var encltype = artenc.type.substring(0,5);
- if (encltype == "video")
- imgsrc = "chrome://newsfox/skin/images/encl-video.png";
- else if (encltype == "audio")
- imgsrc = "chrome://newsfox/skin/images/encl-audio.png";
- else
- imgsrc = "chrome://newsfox/skin/images/encl-other.png";
- img.setAttribute("src",imgsrc);
- img.setAttribute("style","border: 0px; padding-right: 2px;");
- var p = doc.createElement("span");
- p.innerHTML = artenc.type;
- a.appendChild(img);
- a.appendChild(p);
- nobr.appendChild(a);
- var p = doc.createElement("span");
- var sz = Math.round(artenc.length/1024);
- if (sz == 0 || isNaN(sz)) sz = "----";
- sz += "Kb";
- p.innerHTML = ": " + sz + " ";
- nobr.appendChild(p);
- s.appendChild(nobr);
- }
- s.appendChild(doc.createElement("br"));
- div.appendChild(s);
- }
-
- var p = getXhtmlBody(art.body,"p",doc);
-
- doc.body.appendChild(div);
- doc.body.appendChild(p);
- }
-
- function makeMailto(title,link)
- {
- var uri = encodeURI("mailto:?subject=" + entityDecode(title) + "&body=" + link);
- uri = uri.replace(/\?/g,"%3F");
- uri = uri.replace(/=/g,"%3D");
- uri = uri.replace(/&/g,"%26");
- uri = uri.replace("%3Fsubject%3D","?subject=");
- uri = uri.replace("%26body%3D","&body=");
- return(uri);
- }
-
- function getXhtmlBody(body,tag,doc)
- {
- if (body.substring(0,7) == "<xhtml>")
- {
- var p = doc.createElementNS("http://www.w3.org/1999/xhtml",tag);
- var body2 = body.replace(/^<xhtml>|<\/xhtml>$/g,"");
- var xmlBody = new DOMParser().parseFromString(emphsrch(body2),"text/xml");
- // Atom specification guarantees a single <div> element, now a <span>
- p.appendChild(xmlBody.childNodes[0]);
- }
- else
- {
- var p = doc.createElement(tag);
- p.innerHTML = emphsrch(body);
- }
- return p;
- }
-
- function emphsrch(html)
- {
- if (gCollect.type == 3) // search
- {
- var st = gCollect.getSrchText();
- for (var i=0; i<st.length; i++)
- html = hilite(st[i],html);
- }
- return html;
- }
-
- function hilite(srchtext, html)
- {
- var srchdat = gFdGroup[gCollect.grpindex].srchdat;
- var textflags = srchdat.textflags;
- if (srchtext.length > 0)
- {
- var caseSen = ((textflags & 0x04) == 0);
- var text = html;
- var repltext = srchtext;
- if (!caseSen)
- {
- text = text.toLowerCase();
- repltext = repltext.toLowerCase();
- }
- var todo = new Array();
- var startpos = 0;
- var newpos = text.indexOf(repltext,startpos);
- while (newpos > -1)
- {
- // check if in <tag> or in html
- if (text.lastIndexOf(">",newpos) >= text.lastIndexOf("<",newpos))
- todo.push(newpos);
- startpos = newpos + 1;
- newpos = text.indexOf(repltext,startpos);
- }
- var pos;
- var len = srchtext.length;
- for (var i=todo.length-1; i>=0; i--)
- {
- pos = todo[i];
- html = html.substring(0,pos)+"<span class='srch'>"+html.substring(pos,pos+len)+"</span>"+html.substring(pos+len);
- }
- }
- return html;
- }
-
- function resetIframe()
- {
- var iframe = document.getElementById("buildContent");
- var doc = iframe.contentDocument;
-
- // doesn't work, need to keep node with name='html' if it exists
- // while (doc.childNodes.length > 0) doc.removeChild(doc.childNodes[0]);
-
- var docHEAD = null;
- for (var i=0; i<doc.childNodes.length; i++)
- if (doc.childNodes[i].localName == "HTML")
- {
- var docHTML = doc.childNodes[i];
- for (i=0; i<docHTML.childNodes.length; i++)
- if (docHTML.childNodes[i].localName == "HEAD")
- {
- docHEAD = docHTML.childNodes[i];
- while (docHEAD.childNodes.length > 0)
- docHEAD.removeChild(docHEAD.childNodes[0]);
- }
- else if (docHTML.childNodes[i].localName == "BODY")
- {
- var docBODY = docHTML.childNodes[i];
- while (docBODY.childNodes.length > 0)
- docBODY.removeChild(docBODY.childNodes[0]);
- }
- else
- docHTML.removeChild(docHTML.childNodes[i]);
- }
-
- var meta = doc.createElement("meta");
- meta.setAttribute("http-equiv", "content-type");
- meta.setAttribute("content", "text/html");
- meta.setAttribute("charset", "utf-8");
-
- var sty = doc.createElement("style");
- sty.setAttribute("type","text/css");
- sty.innerHTML = getCss();
-
- docHEAD.appendChild(meta);
- docHEAD.appendChild(sty);
- }
-
- ////////////////////////////////////////////////////////////////
- // CSS file
- ////////////////////////////////////////////////////////////////
-
- function getCss()
- {
- var file = getProfileDir();
- file.append("textview.css");
- var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance( Components.interfaces.nsIFileInputStream );
- inputStream.init( file,0x01,00004,null);
- var scInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance( Components.interfaces.nsIScriptableInputStream );
- scInputStream.init(inputStream);
- var output = scInputStream.read(-1);
- scInputStream.close();
- inputStream.close();
- return output;
- }
-
- function makeCss()
- {
- var file, out;
- file = getProfileDir();
- file.append("textview.css");
- if (!file.exists())
- {
- out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "body { font:10pt Verdana,sans-serif; background:white; }\n");
- println(out, "#newsfox-box { background: #e3dfd9; padding:10px; overflow:hidden; }\n");
- println(out, ".srch { color: red; font-weight: bold; }\n");
- out.close();
- }
- else
- {
- var cssTxt = getCss();
- var saveIt = false;
- if (cssTxt.indexOf(".srch") == -1)
- {
- cssTxt += "\n.srch { color: red; font-weight: bold; }\n";
- saveIt = true;
- }
- if (saveIt)
- {
- file.remove(false);
- out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, cssTxt);
- out.close();
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////
- // Keyboard shortcuts
- ////////////////////////////////////////////////////////////////
-
- function updateShortcuts(index)
- {
- var keySet = document.getElementById("shortcut-keys");
- while (keySet.firstChild != null) keySet.removeChild(keySet.firstChild);
-
- for (var i=0; i<scKeyList.length; i++)
- {
- var idkey = scKeyList[i];
- idkey.setAttribute("modifiers", idkey.getAttribute("mod"+index));
- idkey.setAttribute("key", idkey.getAttribute("key"+index));
- if (index != 0) keySet.appendChild(idkey);
- }
-
- var feedTree = document.getElementById("newsfox.feedTree");
- if (index != 0)
- feedTree.setAttribute("disableKeyNavigation", true);
- else
- feedTree.removeAttribute("disableKeyNavigation");
-
- makeAccel();
- }
-
- function makeAccel()
- {
- var file, out;
- file = getProfileDir();
- file.append("accel.xml");
- if (file.exists()) file.remove(false);
-
- out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\"?>\n<body>\n");
- const NF_SB = document.getElementById("newsfox-string-bundle");
- var feedKeyNav = NF_SB.getString('feedKeyNav');
- println(out, "\t<info val=\"" + feedKeyNav + "\" />");
- var feedTree = document.getElementById("newsfox.feedTree");
- var dKNvalue = "true";
- if (feedTree.getAttribute("disableKeyNavigation") != "true") dKNvalue = "false";
- println(out, "\t<feedtree disableKeyNavigation=\"" + dKNvalue + "\"/>\n");
-
- var keySet = document.getElementById("shortcut-keys");
- for (var i=keySet.firstChild; i != null; i=i.nextSibling)
- {
- println(out, "\t<key id=\"" + i.id + "\" modifiers=\"" + i.getAttribute("modifiers") + "\" key=\"" + i.getAttribute("key") + "\"/>");
- }
- println(out, "</body>");
- out.close();
- }
-
- function getAccel()
- {
- var file = getProfileDir();
- file.append("accel.xml");
-
- if (!file.exists())
- makeAccel();
- else
- {
- var xml = document.implementation.createDocument("","",null);
- xml.async = false;
- xml.load("file:///" + file.path);
-
- var keyNav = xml.getElementsByTagName("feedtree");
- if (keyNav.length != 0)
- {
- var feedTree = document.getElementById("newsfox.feedTree");
- if (keyNav[0].getAttribute("disableKeyNavigation") != "false")
- feedTree.setAttribute("disableKeyNavigation", true);
- else
- feedTree.removeAttribute("disableKeyNavigation");
- }
-
- var kids = xml.getElementsByTagName("key");
- for (var i=0; i<kids.length; i++)
- {
- var idkey = document.getElementById(kids[i].getAttribute("id"));
- idkey.setAttribute("modifiers", kids[i].getAttribute("modifiers"));
- idkey.setAttribute("key", kids[i].getAttribute("key"));
- }
- }
-
- var keySet = document.getElementById("shortcut-keys");
- var idkey = keySet.firstChild;
- while (idkey != null)
- {
- scKeyList.push(idkey);
- var mods = idkey.getAttribute("modifiers");
- var keys = idkey.getAttribute("key");
- var tmp = idkey.nextSibling;
- if (mods=="" && keys=="") keySet.removeChild(idkey);
- idkey = tmp;
- }
- }
-
- ////////////////////////////////////////////////////////////////
- // File Util
- ////////////////////////////////////////////////////////////////
-
- function openOutputStream(file, flags)
- {
- var out = Components.classes["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Components.interfaces.nsIFileOutputStream);
- out.init(file, flags, 0664, 0);
- return out;
- }
-
- function print(out, data)
- {
- out.write(data, data.length);
- }
-
- function println(out, data)
- {
- data += "\n";
- out.write(data, data.length);
- }
-
- ////////////////////////////////////////////////////////////////
- // Create new feed
- ////////////////////////////////////////////////////////////////
-
- function createNewFeed(model, url, isExcluded, rmArtfile)
- {
- var feed;
- try
- {
- var uid = model.makeUniqueUid(url); //makeUid(model, url);
- feed = new Feed();
- feed.uid = uid;
- feed.url = url;
- feed.defaultName = uid;
- feed.exclude = isExcluded;
- model.add(feed, isExcluded);
- if (rmArtfile) deleteFeedFromDisk(feed);
- if (!isExcluded)
- {
- var feedtree = document.getElementById("newsfox.feedTree");
- if (gFdGroup[0].expanded == true) feedtree.view.toggleOpenState(0);
- var index = model.size();
- gFdGroup[0].list.push(index-1);
- feedtree.view.toggleOpenState(0);
- }
- }
- catch (err)
- {
- var msg = "createNewFeed(): [" + uid + "] " + err
- alert(msg);
- }
- return feed;
- }
-
- ////////////////////////////////////////////////////////////////
- // Load feeds from disk
- ////////////////////////////////////////////////////////////////
-
- function loadIndices()
- {
- try
- {
- var file = getProfileDir();
- file.append("master_index.xml");
-
- var xml = document.implementation.createDocument("","",null);
- xml.async = false;
- xml.load("file:///" + file.path);
-
- // Get file version
- var root = xml.getElementsByTagName("newsfox-index")[0];
- var version = root.getAttribute("version");
-
- var fdgpidxstr = xml.getElementsByTagName("fdgpidx")[0].childNodes[0].nodeValue;
- var tmp = fdgpidxstr.split(",");
- for (var i=0; i < tmp.length; i++)
- tmp[i] = parseInt(tmp[i]);
- gIdx.fdgp = tmp;
-
- var feedidxstr = xml.getElementsByTagName("feedidx")[0].childNodes[0].nodeValue;
- tmp = feedidxstr.split(",");
- for (i=0; i < tmp.length; i++)
- tmp[i] = parseInt(tmp[i]);
- gIdx.feed = tmp;
-
- var catgidxstr = xml.getElementsByTagName("catgidx")[0].childNodes[0].nodeValue;
- tmp = catgidxstr.split(",");
- for (i=0; i < tmp.length; i++)
- {
- tmp[i] = parseInt(tmp[i]);
- if (tmp[i] > 0)
- {
- var feed = gFmodel.get(gIdx.feed[i]);
- loadFeed(feed);
- }
- }
- gIdx.catg = tmp;
-
- var openidxstr = xml.getElementsByTagName("openidx")[0].childNodes[0].nodeValue;
- tmp = openidxstr.split(",");
- for (i=0; i < tmp.length; i++)
- tmp[i] = (tmp[i] == 1);
- gIdx.open = tmp;
- }
- catch (err) { alert("loadIndices(): " + err); }
- }
-
- function loadGroupModel()
- {
- try
- {
- var file = getProfileDir();
- file.append("master_group.xml");
-
- var xml = document.implementation.createDocument("","",null);
- xml.async = false;
- xml.load("file:///" + file.path);
-
- // Get file version
- var root = xml.getElementsByTagName("newsfox-grouplist")[0];
- var version = root.getAttribute("version");
-
- var tmp = new Array();
- var kids = xml.getElementsByTagName("group");
- for (var i=0; i<kids.length; i++)
- {
- gFdGroup[i] = new FeedGroup();
- //check empty string
- gFdGroup[i].title = child(kids[i], "title").childNodes[0].nodeValue;
- gFdGroup[i].expanded = child(kids[i], "expanded").childNodes[0].nodeValue;
- gFdGroup[i].expanded = (gFdGroup[i].expanded == "true");
- var v = child(kids[i], "list");
- if (v != null && v.childNodes.length > 0)
- {
- var tmpstr = v.childNodes[0].nodeValue;
- var tmp = tmpstr.split(",");
- for (var j=0; j < tmp.length; j++)
- gFdGroup[i].list[j] = parseInt(tmp[j]);
- }
- v = child(kids[i], "search");
- if (v != null && v.childNodes.length > 0)
- gFdGroup[i].search = (v.childNodes[0].nodeValue == "true");
- if (gFdGroup[i].search)
- {
- v = child(kids[i], "flagged");
- if (v != null && v.childNodes.length > 0) gFdGroup[i].srchdat.flagged = parseInt(v.childNodes[0].nodeValue);
- v = child(kids[i], "unread");
- if (v != null && v.childNodes.length > 0) gFdGroup[i].srchdat.unread = parseInt(v.childNodes[0].nodeValue);
- gFdGroup[i].srchdat.text = child(kids[i], "text").childNodes[0].nodeValue;
- v = child(kids[i], "textflags");
- if (v != null && v.childNodes.length > 0) gFdGroup[i].srchdat.textflags = parseInt(v.childNodes[0].nodeValue);
- v = child(kids[i], "startTime");
- if (v != null && v.childNodes.length > 0) gFdGroup[i].srchdat.startTime = parseInt(v.childNodes[0].nodeValue);
- v = child(kids[i], "endTime");
- if (v != null && v.childNodes.length > 0) gFdGroup[i].srchdat.endTime = parseInt(v.childNodes[0].nodeValue);
- }
-
- // Version 1.1 encoded strings, version 1.2 uses UTF-8 encoding
- if (version == 1.1)
- {
- gFdGroup[i].title = entityDecode(gFdGroup[i].title);
- if (gFdGroup[i].search)
- gFdGroup[i].srchdat.text = entityDecode(gFdGroup[i].srchdat.text);
- }
-
- }
- gFdGroup.length = kids.length;
- }
- catch (err) { alert("loadGroupModel(): " + err); }
- }
-
- function loadFeedModel()
- {
- gFmodel = new FdModel();
- try
- {
- var file = getProfileDir();
- file.append("master.xml");
-
- var xml = document.implementation.createDocument("","",null);
- xml.async = false;
- xml.load("file:///" + file.path);
-
- // Get file version
- var root = xml.getElementsByTagName("newsfox-feedlist")[0];
- var version = root.getAttribute("version");
-
- var iconfile, leafName;
- var kids = xml.getElementsByTagName("feed");
- for (var i=0; i<kids.length; i++)
- {
- var feed = new Feed();
- feed.exclude = (kids[i].getAttribute("exclude") == "true");
- feed.uid = child(kids[i], "uid").childNodes[0].nodeValue;
- feed.url = child(kids[i], "url").childNodes[0].nodeValue;
- feed.defaultName = feed.uid;
- var v = child(kids[i], "dname");
- if (v != null) feed.defaultName = v.childNodes[0].nodeValue;
-
- v = child(kids[i], "home");
- if (v != null && v.childNodes.length > 0) feed.homepage = v.childNodes[0].nodeValue;
-
- iconfile = getProfileDir();
- leafName = feed.uid + ".ico";
- iconfile.append(leafName);
- if (!gOptions.favicons || !iconfile.exists() || !isImg(iconfile))
- feed.icon.src = ICON_OK;
- else
- feed.icon.src = "file:///" + iconfile.path;
-
- v = child(kids[i], "style");
- if (v != null && v.childNodes.length > 0) feed.style = parseInt(v.childNodes[0].nodeValue);
-
- v = child(kids[i], "deleteOld");
- if (v != null && v.childNodes.length > 0)
- feed.deleteOld = (v.childNodes[0].nodeValue == "true");
-
- v = child(kids[i], "daysToKeep");
- if (v != null && v.childNodes.length > 0)
- feed.daysToKeep = parseInt(v.childNodes[0].nodeValue);
-
- v = child(kids[i], "autoCheck");
- if (v != null && v.childNodes.length > 0)
- feed.autoCheck = (v.childNodes[0].nodeValue == "true");
- else feed.autoCheck = true;
-
- v = child(kids[i], "customName");
- if (v != null && v.childNodes.length > 0) feed.customName = v.childNodes[0].nodeValue;
-
- v = child(kids[i], "dontDeleteUnread");
- if (v != null && v.childNodes.length > 0) feed.dontDeleteUnread = (v.childNodes[0].nodeValue == "true");
-
- var elem = child(kids[i], "flags");
- if (elem != null && elem.childNodes.length > 0)
- {
- var flags = elem.childNodes[0].nodeValue;
- for (var j=0; j<flags.length; j++)
- feed.flags.push(parseInt(flags.charAt(j)));
- }
-
- // Version 1.1-2 encoded strings, version 1.3 uses UTF-8 encoding
- if (version == 1.1 || version == 1.2)
- {
- feed.defaultName = entityDecode(feed.defaultName);
- feed.customName = entityDecode(feed.customName);
- }
-
- // Version 1.0 tried to encode body text. Version 1.1
- // just uses CDATA, so decode not necessary
- if (version == 1.0)
- {
- feed.url = decodeHTML(feed.url);
- feed.defaultName = decodeHTML(feed.defaultName);
- feed.homepage = decodeHTML(feed.homepage);
- }
-
- gFmodel.add(feed);
- }
- }
- catch (err)
- {
- var msg = "loadFeedModel(): " + "[" + feed.uid + "," + elem + "]\n" + err;
- alert(msg);
- }
- }
-
- function loadFeed(feed)
- {
- if (feed.loaded) return;
- try
- {
- var file = getProfileDir();
- file.append(feed.uid + ".xml");
- checkFeedFile(file);
-
- var xml = document.implementation.createDocument("","",null);
- xml.async = false;
- xml.load("file:///" + file.path);
-
- // Get file version
- var root = xml.getElementsByTagName("newsfox-feed")[0];
- var version = root.getAttribute("version");
-
- var flags = feed.flags;
- feed.flags = new Array();
- var kids = xml.getElementsByTagName("article");
- for (var i=0; i<kids.length; i++)
- {
- var id = child(kids[i], "id");
- // versions up until 1.2 used link as id
- if (id || version <= 1.2)
- {
- if (id) id = id.childNodes[0];
- var link = child(kids[i], "link");
- if (link) link = link.childNodes[0];
- var title = child(kids[i], "title").childNodes[0];
- var date = child(kids[i], "date").childNodes[0];
- var body = child(kids[i], "body").childNodes[0];
- // AG: added category
- var category = child(kids[i], "category");
- if (category != null) category = category.childNodes[0];
- var encls = new Array();
- var enc = kids[i].getElementsByTagName("enclosure");
- for (var j=0; j<enc.length; j++)
- encls.push(newEncl(enc[j],"url"));
-
- var art = new Article();
- art.link = (link == null) ? null : link.nodeValue;
- art.title = (title == null) ? "" : title.nodeValue;
- art.body = (body == null) ? "" : body.nodeValue;
- art.date = new Date();
- if (date != null) art.date.setTime(Date.parse(date.nodeValue));
- // AG: added category
- art.category = (category == null) ? "" : category.nodeValue;
- art.id = (id) ? id.nodeValue : null;
- art.enclosures = encls;
-
- // Version 1.1-2 encoded strings, version 1.3 uses UTF-8 encoding
- if (version == 1.1 || version == 1.2)
- {
- art.category = entityDecode(art.category);
- art.id = (art.id) ? art.id : art.link;
- }
-
- // Version 1.0 tried to encode body text. Version 1.1
- // just uses CDATA, so decode not necessary
- if (version == 1.0)
- {
- art.link = decodeHTML(art.link);
- art.title = decodeHTML(art.title);
- art.body = decodeHTML(art.body);
- }
-
- // Add feed
- feed.add(art,flags[i]);
- }
- }
- feed.sortCategories();
-
- // load deleted articles
- var kids = xml.getElementsByTagName("deletedarticle");
- for (var i=0; i<kids.length; i++)
- {
- var link = child(kids[i], "link").childNodes[0];
- var date = child(kids[i], "date").childNodes[0];
-
- var art = new Article();
- art.link = (link == null) ? "" : link.nodeValue;
- art.date = new Date();
- if (date != null) art.date.setTime(Date.parse(date.nodeValue));
- var id = child(kids[i], "id");
- if (id != null) id = id.childNodes[0];
- art.id = (id) ? id.nodeValue : art.link;
-
- feed.deletedAdd(art);
- }
- // some articles deleted
- if (flags.length != feed.flags.length) saveFeed(feed);
- feed.loaded = true;
- }
- catch (err) { alert("loadFeed(): " + feed.uid + "\n\n" + err); }
- }
-
- function checkFeedFile(file)
- {
- try
- {
- if (!file.exists())
- {
- var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println(out, "<newsfox-feed version=\"1.3\">");
- println(out, "</newsfox-feed>");
- out.close();
- }
- }
- catch (err) { alert(err); }
- }
-
- ////////////////////////////////////////////////////////////////
- // Save feeds to disk
- ////////////////////////////////////////////////////////////////
-
- function saveIndices()
- {
- try
- {
- var file = getProfileDir();
- file.append("master_index.xml");
-
- var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println(out, "<newsfox-index version=\"1.0\">");
- var fdgpidxstr = gIdx.fdgp.join();
- println(out, " <fdgpidx>" + fdgpidxstr + "</fdgpidx>");
- var feedidxstr = gIdx.feed.join();
- println(out, " <feedidx>" + feedidxstr + "</feedidx>");
- var catgidxstr = gIdx.catg.join();
- println(out, " <catgidx>" + catgidxstr + "</catgidx>");
- var tmp = new Array();
- for (var i=0; i<gIdx.open.length; i++)
- tmp[i] = 1*(gIdx.open[i] == true);
- var openidxstr = tmp.join();
- println(out, " <openidx>" + openidxstr + "</openidx>");
- println(out, "</newsfox-index>");
- out.close();
- }
- catch (err) { alert("saveIndices(): " + err); }
- }
-
- function saveGroupModel()
- {
- try
- {
- var file = getProfileDir();
- file.append("master_group.xml");
-
- var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println(out, "<newsfox-grouplist version=\"1.2\">");
- for (var i=0; i<gFdGroup.length; i++)
- {
- var grpstr = gFdGroup[i].list.join();
- println(out, " <group>");
- println(out, " <title><![CDATA[" + toUTF8(gFdGroup[i].title) + "]]></title>");
- println(out, " <expanded>" + gFdGroup[i].expanded + "</expanded>");
- println(out, " <search>" + gFdGroup[i].search + "</search>");
- if (gFdGroup[i].search)
- {
- println(out, " <flagged>" + gFdGroup[i].srchdat.flagged + "</flagged>");
- println(out, " <unread>" + gFdGroup[i].srchdat.unread + "</unread>");
- println(out, " <text><![CDATA[" + toUTF8(gFdGroup[i].srchdat.text) + "]]></text>");
- println(out, " <textflags>" + gFdGroup[i].srchdat.textflags + "</textflags>");
- println(out, " <startTime>" + gFdGroup[i].srchdat.startTime + "</startTime>");
- println(out, " <endTime>" + gFdGroup[i].srchdat.endTime + "</endTime>");
- }
- println(out, " <list>" + grpstr + "</list>");
- println(out, " </group>");
- }
- println(out, "</newsfox-grouplist>");
- out.close();
- }
- catch (err) { alert("saveGroupModel(): " + err); }
- }
-
- function saveFeedModel()
- {
- try
- {
- var file = getProfileDir();
- file.append("master.xml");
-
- var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println(out, "<newsfox-feedlist version=\"1.3\">");
- for (var i=0; i<gFmodel.sizeTotal(); i++)
- {
- var feed = gFmodel.get(i);
- println(out, " <feed exclude=\"" + feed.exclude + "\">");
- println(out, " <uid>" + toUTF8(feed.uid) + "</uid>");
- println(out, " <url><![CDATA[" + toUTF8(feed.url) + "]]></url>");
- println(out, " <dname><![CDATA[" + toUTF8(feed.defaultName) + "]]></dname>");
- if (feed.homepage != null)
- println(out, " <home><![CDATA[" + toUTF8(feed.homepage) + "]]></home>");
- // Only save if property overrides global setting
- if (feed.style != 0)
- println(out, " <style>" + feed.style + "</style>");
- println(out, " <deleteOld>" + feed.deleteOld + "</deleteOld>");
- println(out, " <daysToKeep>" + feed.daysToKeep + "</daysToKeep>");
- println(out, " <autoCheck>" + feed.autoCheck + "</autoCheck>");
- if( null != feed.customName )
- println(out, " <customName><![CDATA[" + toUTF8(feed.customName) + "]]></customName>");
- println(out, " <dontDeleteUnread>" + feed.dontDeleteUnread + "</dontDeleteUnread>");
- print(out, " <flags>");
- var fdflag;
- for (var j=0; j<feed.flags.length; j++)
- {
- fdflag = 1*((feed.flags[j] & 0x01)!=0) + 4*((feed.flags[j] & 0x04)!=0);
- //RPdebug if (fdflag != feed.flags[j]) alert(feed.getDisplayName() + " j= " + j + " feed.flags[j]= " + feed.flags[j]);
- print(out, "" + fdflag);
- }
- println(out, "</flags>");
- println(out, " </feed>");
- }
- println(out, "</newsfox-feedlist>");
- out.close();
- }
- catch (err) { alert("saveFeedModel(): [" + feed.uid + "] " + err); }
- }
-
- function saveFeed(feed)
- {
- var file = getProfileDir();
- file.append(feed.uid + ".xml");
-
- var out = openOutputStream(file, 0x02 | 0x08 | 0x20);
- println(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println(out, "<newsfox-feed version=\"1.3\">");
- for (var i=0; i<feed.size(); i++)
- {
- var art = feed.get(i);
- println(out, " <article>");
- if (art.link) println(out, " <link><![CDATA[" + toUTF8(art.link) + "]]></link>");
- println(out, " <title><![CDATA[" + toUTF8(art.title) + "]]></title>");
- println(out, " <date>" + toUTF8(art.date) + "</date>");
- println(out, " <body><![CDATA[" + toUTF8(art.body) + "]]></body>");
- // AG: added category
- println(out, " <category><![CDATA[" + toUTF8(art.category) + "]]></category>");
- if (art.id) println(out, " <id><![CDATA[" + toUTF8(art.id) + "]]></id>");
- for (var j=0; j<art.enclosures.length; j++)
- {
- var enc = art.enclosures[j];
- println(out, ' <enclosure url="' + toUTF8(encodeHTML(enc.url)) + '" type="' + toUTF8(encodeHTML(enc.type)) + '" length="' + toUTF8(encodeHTML(enc.length)) + '"/>');
- }
- println(out, " </article>");
- }
- for (var i=0; i<feed.deletedsize(); i++)
- {
- var art = feed.deletedget(i);
- println(out, " <deletedarticle>");
- println(out, " <link><![CDATA[" + toUTF8(art.link) + "]]></link>");
- println(out, " <date>" + toUTF8(art.date) + "</date>");
- println(out, " <id><![CDATA[" + toUTF8(art.id) + "]]></id>");
- println(out, " </deletedarticle>");
- }
- println(out, "</newsfox-feed>");
- out.close();
- }
-
- ////////////////////////////////////////////////////////////////
- // Delete feed
- ////////////////////////////////////////////////////////////////
-
- function deleteFeedFromDisk(feed)
- {
- try
- {
- var file = getProfileDir();
- file.append(feed.uid + ".xml");
- if (file.exists()) file.remove(false);
- var file = getProfileDir();
- file.append(feed.uid + ".ico");
- if (file.exists()) file.remove(false);
- }
- catch (err) {} // TODO sometimes icon file locked, file now checked on creation as well - alert("deleteFeedFromDisk(): [" + feed.uid + "] " + err); }
- }
-
- ////////////////////////////////////////////////////////////////
- // Util
- ////////////////////////////////////////////////////////////////
-
- function child(element, tagName)
- {
- var kids = element.childNodes;
- for (var i=0; i<kids.length; i++)
- if (kids[i].nodeName == tagName)
- return kids[i];
- return null;
- }
-
- ////////////////////////////////////////////////////////////////
- // Encode/Decode
- ////////////////////////////////////////////////////////////////
-
- /**
- * Return XML-friendly HTML encoding.
- */
- function encodeHTML(s)
- {
- if (!s) return "";
- s = s.replace(new RegExp('&','gi'), '&');
- s = s.replace(new RegExp('<','gi'), '<');
- s = s.replace(new RegExp('>','gi'), '>');
- s = s.replace(new RegExp('"','gi'), '"');
- return s;
- }
-
- /**
- * Return original HTML from encoding.
- */
- function decodeHTML(s)
- {
- s = s.replace(new RegExp('&' ,'gi'), '&');
- s = s.replace(new RegExp('<' ,'gi'), '<');
- s = s.replace(new RegExp('>' ,'gi'), '>');
- s = s.replace(new RegExp('"' ,'gi'), '"');
- s = s.replace(new RegExp('´','gi'), '┤');
- return s;
- }
-
- function toUTF8(inVal)
- {
- var uC = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
- uC.charset = "UTF-8";
- return uC.ConvertFromUnicode(inVal);
- }
-
- // from Sage project
- function entityDecode(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;
- }
-