зеркало из https://github.com/mozilla/pjs.git
Bug #281237 --> start landing the new RSS subscription manager UI.
This commit is contained in:
Родитель
c6ed0e4d26
Коммит
28af173c29
|
@ -73,9 +73,10 @@ var FeedCache =
|
|||
}
|
||||
};
|
||||
|
||||
function Feed(aResource)
|
||||
function Feed(aResource, aRSSServer)
|
||||
{
|
||||
this.resource = aResource.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
this.server = aRSSServer;
|
||||
}
|
||||
|
||||
Feed.prototype =
|
||||
|
@ -347,15 +348,15 @@ Feed.prototype =
|
|||
cleanupParsingState: function(aFeed)
|
||||
{
|
||||
// now that we are done parsing the feed, remove the feed from our feed cache
|
||||
FeedCache.removeFeed(feed.url);
|
||||
FeedCache.removeFeed(aFeed.url);
|
||||
aFeed.removeInvalidItems();
|
||||
|
||||
// let's be sure to flush any feed item changes back to disk
|
||||
var ds = getItemsDS(feed.server);
|
||||
var ds = getItemsDS(aFeed.server);
|
||||
ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
|
||||
|
||||
if (aFeed.downloadCallback)
|
||||
aFeed.downloadCallback.downloaded(feed, kNewsBlogSuccess);
|
||||
aFeed.downloadCallback.downloaded(aFeed, kNewsBlogSuccess);
|
||||
|
||||
this.request = null; // force the xml http request to go away. This helps reduce some nasty assertions on shut down.
|
||||
this.itemsToStore = "";
|
||||
|
|
|
@ -45,6 +45,7 @@ function onLoad()
|
|||
document.getElementById('selectFolder').setAttribute('ref', window.arguments[0].serverURI);
|
||||
|
||||
SetFolderPicker(window.arguments[0].folderURI ? window.arguments[0].folderURI : window.arguments[0].serverURI, 'selectFolder');
|
||||
document.getElementById('selectFolder').setInitialSelection();
|
||||
|
||||
document.getElementById('rssAccountMenuItem').label = window.arguments[0].serverPrettyName;
|
||||
document.getElementById('rssAccountMenuItem').value = window.arguments[0].serverURI;
|
||||
|
@ -53,7 +54,7 @@ function onLoad()
|
|||
document.getElementById('quickMode').checked = window.arguments[0].quickMode;
|
||||
|
||||
// if we are editing an existing feed, disable the top level account
|
||||
if (window.arguments[0].folderURI)
|
||||
if (!window.arguments[0].newFeed)
|
||||
document.getElementById('rssAccountMenuItem').setAttribute('disabled', 'true');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,41 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- ***** 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 News and Blogs Feed Properties UI.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- The Mozilla Foundation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2004
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Scott MacGregor <mscott@mozilla.org>
|
||||
-
|
||||
- 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 ***** -->
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Feed Properties UI
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/" type="text/css"?>
|
||||
|
||||
|
|
|
@ -0,0 +1,733 @@
|
|||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Subscription Manager
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
const MSG_FOLDER_FLAG_TRASH = 0x0100;
|
||||
const IPS = Components.interfaces.nsIPromptService;
|
||||
|
||||
var gFeedSubscriptionsWindow = {
|
||||
mFeedContainers : [],
|
||||
mTree : null,
|
||||
mBundle : null,
|
||||
mRSSServer : null,
|
||||
|
||||
init: function ()
|
||||
{
|
||||
// extract the server argument
|
||||
if (window.arguments[0].server)
|
||||
this.mRSSServer = window.arguments[0].server;
|
||||
|
||||
var docshell = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
docshell.allowAuth = true;
|
||||
|
||||
this.mTree = document.getElementById("rssSubscriptionsList");
|
||||
this.mBundle = document.getElementById("bundle_newsblog");
|
||||
|
||||
this.loadSubscriptions();
|
||||
this.mTree.treeBoxObject.view = this.mView;
|
||||
if (this.mView.rowCount > 0)
|
||||
this.mTree.view.selection.select(0);
|
||||
},
|
||||
|
||||
uninit: function ()
|
||||
{
|
||||
var dismissDialog = true;
|
||||
|
||||
// if we are in the middle of subscribing to a feed, inform the user that
|
||||
// dismissing the dialog right now will abort the feed subscription.
|
||||
// cheat and look at the disabled state of the add button to determine if we are in the middle of a new subscription
|
||||
if (document.getElementById('addFeed').getAttribute('disabled'))
|
||||
{
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(IPS);
|
||||
var newsBlogBundle = document.getElementById("bundle_newsblog");
|
||||
dismissDialog = !(promptService.confirmEx(window, newsBlogBundle.getString('subscribe-cancelSubscriptionTitle'),
|
||||
newsBlogBundle.getString('subscribe-cancelSubscription'),
|
||||
(IPS.BUTTON_TITLE_YES * IPS.BUTTON_POS_0) + (IPS.BUTTON_TITLE_NO * IPS.BUTTON_POS_1),
|
||||
null, null, null, null, { }));
|
||||
}
|
||||
return dismissDialog;
|
||||
},
|
||||
|
||||
mView:
|
||||
{
|
||||
mRowCount : 0,
|
||||
|
||||
get rowCount()
|
||||
{
|
||||
return this.mRowCount;
|
||||
},
|
||||
|
||||
getItemAtIndex: function (aIndex)
|
||||
{
|
||||
return gFeedSubscriptionsWindow.mFeedContainers[aIndex];
|
||||
},
|
||||
|
||||
removeItemAtIndex: function (aIndex, aCount)
|
||||
{
|
||||
var itemToRemove = this.getItemAtIndex(aIndex);
|
||||
if (!itemToRemove)
|
||||
return;
|
||||
|
||||
var parentIndex = this.getParentIndex(aIndex);
|
||||
if (parentIndex != -1)
|
||||
{
|
||||
var parent = this.getItemAtIndex(parentIndex);
|
||||
if (parent)
|
||||
{
|
||||
for (var index = 0; index < parent.children.length; index++)
|
||||
if (parent.children[index] == itemToRemove)
|
||||
{
|
||||
parent.children.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now remove it from our view
|
||||
gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex, 1);
|
||||
|
||||
// now invalidate the correct tree rows
|
||||
var tbo = gFeedSubscriptionsWindow.mTree.treeBoxObject;
|
||||
|
||||
this.mRowCount--;
|
||||
tbo.rowCountChanged(aIndex, -1);
|
||||
tbo.invalidateRow(aIndex);
|
||||
|
||||
// now update the selection position
|
||||
if (aIndex < gFeedSubscriptionsWindow.mFeedContainers.length)
|
||||
this.selection.select(aIndex);
|
||||
else
|
||||
this.selection.clearSelection();
|
||||
|
||||
// now refocus the tree
|
||||
gFeedSubscriptionsWindow.mTree.focus();
|
||||
},
|
||||
|
||||
getCellText: function (aIndex, aColumn)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (!item)
|
||||
return "";
|
||||
else if (aColumn.id == "folderNameCol")
|
||||
return item.name;
|
||||
},
|
||||
|
||||
_selection: null,
|
||||
get selection () { return this._selection; },
|
||||
set selection (val) { this._selection = val; return val; },
|
||||
getRowProperties: function (aIndex, aProperties) {},
|
||||
getCellProperties: function (aIndex, aColumn, aProperties) {},
|
||||
getColumnProperties: function (aColumn, aProperties) {},
|
||||
|
||||
isContainer: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
return item ? item.container : false;
|
||||
},
|
||||
|
||||
isContainerOpen: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
return item ? item.open : false;
|
||||
},
|
||||
|
||||
isContainerEmpty: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (!item)
|
||||
return false;
|
||||
return item.children.length == 0;
|
||||
},
|
||||
|
||||
isSeparator: function (aIndex) { return false; },
|
||||
isSorted: function (aIndex) { return false; },
|
||||
|
||||
canDrop: function (aIndex, aOrientation)
|
||||
{
|
||||
var dropResult = this.extractURLAndVerifyFlavour();
|
||||
return (aOrientation == Components.interfaces.nsITreeView.DROP_ON) && dropResult.canDrop && dropResult.url;
|
||||
},
|
||||
|
||||
mDropUrl: "",
|
||||
mDropFolderUrl: "",
|
||||
drop: function (aIndex, aOrientation)
|
||||
{
|
||||
var results = this.extractURLAndVerifyFlavour();
|
||||
if (results.canDrop && results.url)
|
||||
{
|
||||
var folderItem = this.getItemAtIndex(aIndex);
|
||||
|
||||
// don't freeze the app that initiaed the drop just because we are in a loop waiting for the user
|
||||
// to dimisss the add feed dialog....
|
||||
this.mDropUrl = results.url;
|
||||
this.mDropFolderUrl = folderItem.url;
|
||||
setTimeout(processDrop, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// helper function for drag and drop
|
||||
extractURLAndVerifyFlavour: function()
|
||||
{
|
||||
var canDrop = false;
|
||||
var urlToDrop;
|
||||
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(Components.interfaces.nsIDragService);
|
||||
var dragSession = dragService.getCurrentSession();
|
||||
|
||||
var transfer = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
transfer.addDataFlavor("text/x-moz-url");
|
||||
|
||||
dragSession.getData (transfer, 0);
|
||||
var dataObj = new Object();
|
||||
var flavor = new Object();
|
||||
var len = new Object();
|
||||
|
||||
try {
|
||||
transfer.getAnyTransferData(flavor, dataObj, len);
|
||||
} catch (ex) { return { canDrop: false, url: "" }; }
|
||||
|
||||
if (dataObj.value)
|
||||
{
|
||||
dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
sourceUri = dataObj.data.substring(0, len.value); // pull the URL out of the data object
|
||||
|
||||
if (sourceUri)
|
||||
{
|
||||
var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURI);
|
||||
uri.spec = sourceUri.split("\n")[0];
|
||||
|
||||
if (uri.schemeIs("http") || uri.schemeIs("https"))
|
||||
{
|
||||
urlToDrop = uri.spec;
|
||||
canDrop = true;
|
||||
}
|
||||
} // if sourceUri
|
||||
} // if dataObj.value
|
||||
|
||||
return { canDrop: canDrop, url: urlToDrop };
|
||||
},
|
||||
|
||||
getParentIndex: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
|
||||
if (item)
|
||||
{
|
||||
for (var index = aIndex; index >= 0; index--)
|
||||
if (gFeedSubscriptionsWindow.mFeedContainers[index].level < item.level)
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
},
|
||||
hasNextSibling: function (aParentIndex, aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (item)
|
||||
{
|
||||
// if the next node in the view has the same level as us, then we must have a next sibling...
|
||||
if (aIndex + 1 < gFeedSubscriptionsWindow.mFeedContainers.length )
|
||||
return this.getItemAtIndex(aIndex + 1).level == item.level;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
hasPreviousSibling: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (item && aIndex)
|
||||
return this.getItemAtIndex(aIndex - 1).level == item.level;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
getLevel: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (!item)
|
||||
return 0;
|
||||
return item.level;
|
||||
},
|
||||
getImageSrc: function (aIndex, aColumn) {},
|
||||
getProgressMode: function (aIndex, aColumn) {},
|
||||
getCellValue: function (aIndex, aColumn) {},
|
||||
setTree: function (aTree) {},
|
||||
toggleOpenState: function (aIndex)
|
||||
{
|
||||
var item = this.getItemAtIndex(aIndex);
|
||||
if (!item) return;
|
||||
var multiplier = item.open ? -1 : 1;
|
||||
var delta = multiplier * item.children.length;
|
||||
this.mRowCount += delta;
|
||||
|
||||
if (multiplier < 0)
|
||||
gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex + 1, item.children.length);
|
||||
else
|
||||
for (var i = 0; i < item.children.length; i++)
|
||||
gFeedSubscriptionsWindow.mFeedContainers.splice(aIndex + 1, 0, item.children[i]);
|
||||
|
||||
// add or remove the children from our view
|
||||
item.open = !item.open;
|
||||
gFeedSubscriptionsWindow.mTree.treeBoxObject.rowCountChanged(aIndex + 1, delta);
|
||||
gFeedSubscriptionsWindow.mTree.treeBoxObject.invalidateRow(aIndex);
|
||||
},
|
||||
cycleHeader: function (aColumn) {},
|
||||
selectionChanged: function () {},
|
||||
cycleCell: function (aIndex, aColumn) {},
|
||||
isEditable: function (aIndex, aColumn)
|
||||
{
|
||||
return false;
|
||||
},
|
||||
setCellValue: function (aIndex, aColumn, aValue) {},
|
||||
setCellText: function (aIndex, aColumn, aValue) {},
|
||||
performAction: function (aAction) {},
|
||||
performActionOnRow: function (aAction, aIndex) {},
|
||||
performActionOnCell: function (aAction, aindex, aColumn) {}
|
||||
},
|
||||
|
||||
makeFolderObject: function (aFolder, aCurrentLevel)
|
||||
{
|
||||
var folderObject = { children : [],
|
||||
name : aFolder.prettiestName,
|
||||
level : aCurrentLevel,
|
||||
url : aFolder.QueryInterface(Components.interfaces.nsIRDFResource).Value,
|
||||
open : false,
|
||||
container: true };
|
||||
|
||||
// if a feed has any sub folders, we should add them to the list of children
|
||||
if (aFolder.hasSubFolders)
|
||||
{
|
||||
var folderEnumerator = aFolder.GetSubFolders();
|
||||
var done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
var folder = folderEnumerator.currentItem().QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
folderObject.children.push(this.makeFolderObject(folder, aCurrentLevel + 1));
|
||||
|
||||
try {
|
||||
folderEnumerator.next();
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var msgdb = aFolder.QueryInterface(Components.interfaces.nsIMsgFolder).getMsgDatabase(null);
|
||||
var folderInfo = msgdb.dBFolderInfo;
|
||||
var feedurls = folderInfo.getCharPtrProperty("feedUrl");
|
||||
var feedUrlArray = feedurls.split("|");
|
||||
|
||||
for (url in feedUrlArray)
|
||||
{
|
||||
if (!feedUrlArray[url])
|
||||
continue;
|
||||
var feedResource = rdf.GetResource(feedUrlArray[url]);
|
||||
var feed = new Feed(feedResource, this.mRSSServer);
|
||||
|
||||
// Special case, if a folder only has a single feed associated with it, then just use the feed
|
||||
// in the view and don't show the folder at all.
|
||||
// if (feedUrlArray.length <= 2 && !aFolder.hasSubFolders) // Note: split always adds an empty element to the array...
|
||||
// this.mFeedContainers[aCurrentLength] = this.makeFeedObject(feed, aCurrentLevel);
|
||||
// else // now add any feed urls for the folder
|
||||
folderObject.children.push(this.makeFeedObject(feed, aCurrentLevel + 1));
|
||||
}
|
||||
|
||||
return folderObject;
|
||||
},
|
||||
|
||||
makeFeedObject: function (aFeed, aLevel)
|
||||
{
|
||||
// look inside the data source for the feed properties
|
||||
var feed = { children : [],
|
||||
name : aFeed.title,
|
||||
url : aFeed.url,
|
||||
level : aLevel,
|
||||
open : false,
|
||||
container : false };
|
||||
return feed;
|
||||
},
|
||||
|
||||
loadSubscriptions: function ()
|
||||
{
|
||||
// put together an array of folders
|
||||
var numFolders = 0;
|
||||
this.mFeedContainers = [];
|
||||
|
||||
if (this.mRSSServer.rootFolder.hasSubFolders)
|
||||
{
|
||||
var folderEnumerator = this.mRSSServer.rootFolder.GetSubFolders();
|
||||
var done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
var folder = folderEnumerator.currentItem().QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
if (folder && !folder.getFlag(MSG_FOLDER_FLAG_TRASH))
|
||||
{
|
||||
this.mFeedContainers.push(this.makeFolderObject(folder, 0));
|
||||
numFolders++;
|
||||
}
|
||||
|
||||
try {
|
||||
folderEnumerator.next();
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.mView.mRowCount = numFolders;
|
||||
},
|
||||
|
||||
updateFeedData: function (aItem)
|
||||
{
|
||||
var ids = ['nameLabel', 'nameValue', 'locationLabel', 'locationValue'];
|
||||
if (aItem && !aItem.container)
|
||||
{
|
||||
// set the feed location and title info
|
||||
document.getElementById('nameValue').value = aItem.name;
|
||||
document.getElementById('locationValue').value = aItem.url;
|
||||
}
|
||||
else
|
||||
{
|
||||
var noneSelected = this.mBundle.getString("subscribe-noFeedSelected");
|
||||
document.getElementById('nameValue').value = noneSelected;
|
||||
document.getElementById('locationValue').value = "";
|
||||
}
|
||||
|
||||
for (i = 0; i < ids.length; ++i)
|
||||
document.getElementById(ids[i]).disabled = !aItem || aItem.container;
|
||||
},
|
||||
|
||||
onRSSFeedSelected: function ()
|
||||
{
|
||||
var properties, item;
|
||||
var seln = this.mTree.view.selection;
|
||||
item = this.mView.getItemAtIndex(seln.currentIndex);
|
||||
|
||||
this.updateFeedData(item);
|
||||
|
||||
document.getElementById("removeFeed").disabled = !item || item.container;
|
||||
},
|
||||
|
||||
removeFeed: function ()
|
||||
{
|
||||
var seln = this.mView.selection;
|
||||
if (seln.count != 1) return;
|
||||
|
||||
var itemToRemove = this.mView.getItemAtIndex(seln.currentIndex);
|
||||
|
||||
if (!itemToRemove)
|
||||
return;
|
||||
|
||||
// ask the user if he really wants to unsubscribe from the feed
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(IPS);
|
||||
var abortRemoval = promptService.confirmEx(window, this.mBundle.getString('subsribe-confirmFeedDeletionTitle'),
|
||||
this.mBundle.getFormattedString('subsribe-confirmFeedDeletion', [itemToRemove.name], 1),
|
||||
(IPS.BUTTON_TITLE_YES * IPS.BUTTON_POS_0) + (IPS.BUTTON_TITLE_NO * IPS.BUTTON_POS_1),
|
||||
null, null, null, null, { });
|
||||
if (abortRemoval)
|
||||
return;
|
||||
|
||||
var resource = rdf.GetResource(itemToRemove.url);
|
||||
var feed = new Feed(resource);
|
||||
var ds = getSubscriptionsDS(this.mRSSServer);
|
||||
|
||||
if (feed && ds)
|
||||
{
|
||||
// remove the feed from the subscriptions ds
|
||||
var feeds = getSubscriptionsList(this.mRSSServer);
|
||||
var index = feeds.IndexOf(resource);
|
||||
if (index != -1)
|
||||
feeds.RemoveElementAt(index, false);
|
||||
|
||||
// remove the feed property string from the folder data base
|
||||
var currentFolder = ds.GetTarget(resource, FZ_DESTFOLDER, true);
|
||||
if (currentFolder)
|
||||
{
|
||||
var currentFolderURI = currentFolder.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
||||
currentFolder = rdf.GetResource(currentFolderURI).QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
var feedUrl = ds.GetTarget(resource, DC_IDENTIFIER, true);
|
||||
ds.Unassert(resource, DC_IDENTIFIER, feedUrl, true);
|
||||
|
||||
feedUrl = feedUrl ? feedUrl.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
|
||||
|
||||
updateFolderFeedUrl(currentFolder, feedUrl, true); // remove the old url
|
||||
}
|
||||
|
||||
// Remove all assertions about the feed from the subscriptions database.
|
||||
removeAssertions(ds, resource);
|
||||
ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
|
||||
|
||||
// Remove all assertions about items in the feed from the items database.
|
||||
var itemds = getItemsDS(this.mRSSServer);
|
||||
feed.invalidateItems();
|
||||
feed.removeInvalidItems();
|
||||
itemds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
|
||||
}
|
||||
|
||||
// Now that we have removed the feed from the datasource, it is time to update our
|
||||
// view layer. Start by removing the child from its parent folder object
|
||||
this.mView.removeItemAtIndex(seln.currentIndex);
|
||||
|
||||
// If we don't have any more subscriptions pointing into
|
||||
// this folder, then I think we should offer to delete it...
|
||||
// Cheat and look at the feed url property to see if anyone else is still using the feed...
|
||||
// you could also accomplish this by looking at some properties in the data source...
|
||||
|
||||
// var msgdb = currentFolder.QueryInterface(Components.interfaces.nsIMsgFolder).getMsgDatabase(null);
|
||||
// var folderInfo = msgdb.dBFolderInfo;
|
||||
// var oldFeedUrl = folderInfo.getCharPtrProperty("feedUrl");
|
||||
|
||||
// if (!oldFeedUrl) // no more feeds pointing to the folder?
|
||||
// {
|
||||
// try {
|
||||
// var openerResource = this.mRSSServer.rootMsgFolder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
// var folderResource = currentFolder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
// window.opener.messenger.DeleteFolders(window.opener.GetFolderDatasource(), openerResource, folderResource);
|
||||
// } catch (e) { }
|
||||
// }
|
||||
},
|
||||
|
||||
// aRootFolderURI --> optional argument. The folder to initially create the new feed under.
|
||||
addFeed: function(aFeedLocation, aRootFolderURI)
|
||||
{
|
||||
var userAddedFeed = false;
|
||||
var defaultQuickMode = this.mRSSServer.getBoolAttribute('quickMode');
|
||||
var feedProperties = { feedName: "", feedLocation: aFeedLocation,
|
||||
serverURI: this.mRSSServer.serverURI,
|
||||
serverPrettyName: this.mRSSServer.prettyName,
|
||||
folderURI: aRootFolderURI,
|
||||
quickMode: this.mRSSServer.getBoolAttribute('quickMode'),
|
||||
newFeed: true,
|
||||
result: userAddedFeed};
|
||||
|
||||
feedProperties = openFeedEditor(feedProperties);
|
||||
|
||||
// if the user hit cancel, exit without doing anything
|
||||
if (!feedProperties.result)
|
||||
return;
|
||||
|
||||
if (!feedProperties.feedLocation)
|
||||
return;
|
||||
|
||||
// before we go any further, make sure the user is not already subscribed to this feed.
|
||||
if (feedAlreadyExists(feedProperties.feedLocation, this.mRSSServer))
|
||||
{
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(IPS);
|
||||
promptService.alert(window, null, this.mBundle.getString("subscribe-feedAlreadySubscribed"));
|
||||
return;
|
||||
}
|
||||
|
||||
var itemResource = rdf.GetResource(feedProperties.feedLocation);
|
||||
feed = new Feed(itemResource);
|
||||
|
||||
// if the user specified a specific folder to add the feed too, then set it here
|
||||
if (feedProperties.folderURI)
|
||||
{
|
||||
var folderResource = rdf.GetResource(feedProperties.folderURI);
|
||||
if (folderResource)
|
||||
{
|
||||
var folder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
if (folder && !folder.isServer)
|
||||
feed.folder = folder;
|
||||
}
|
||||
}
|
||||
|
||||
// set the server for the feed
|
||||
feed.server = this.mRSSServer;
|
||||
feed.quickMode = feedProperties.quickMode;
|
||||
|
||||
// update status text
|
||||
updateStatusItem('statusText', document.getElementById("bundle_newsblog").getString('subscribe-validating'));
|
||||
updateStatusItem('progressMeter', 0);
|
||||
|
||||
// validate the feed and download the articles
|
||||
// we used to pass false which caused us to skip parsing then we'd
|
||||
// turn around and download the feed again so we could actually parse the items...
|
||||
// But now that this operation is asynch, just kick it off once...if we change this back
|
||||
// modify feedDownloadCallback.downloaded to parse the feed...
|
||||
// Also, disable the Add button while we are subscribing.
|
||||
document.getElementById('addFeed').setAttribute('disabled', 'true');
|
||||
feed.download(true, this.mFeedDownloadCallback);
|
||||
},
|
||||
|
||||
mFeedDownloadCallback:
|
||||
{
|
||||
downloaded: function(feed, aErrorCode)
|
||||
{
|
||||
// feed is null if our attempt to parse the feed failed
|
||||
if (aErrorCode == kNewsBlogSuccess)
|
||||
{
|
||||
updateStatusItem('progressMeter', 100);
|
||||
|
||||
// if we get here...we should always have a folder by now...either
|
||||
// in feed.folder or FeedItems created the folder for us....
|
||||
var folder = feed.folder ? feed.folder : gFeedSubscriptionsWindow.mRSSServer.rootMsgFolder.getChildNamed(feed.name);
|
||||
|
||||
updateFolderFeedUrl(folder, feed.url, false);
|
||||
|
||||
// add feed just adds the feed we have validated and downloaded to our datasource
|
||||
// it also flushes the subscription datasource
|
||||
addFeed(feed.url, feed.name, folder);
|
||||
|
||||
// now add the feed to our view
|
||||
gFeedSubscriptionsWindow.loadSubscriptions();
|
||||
gFeedSubscriptionsWindow.mTree.treeBoxObject.invalidate();
|
||||
if (gFeedSubscriptionsWindow.mView.rowCount > 0)
|
||||
gFeedSubscriptionsWindow.mTree.view.selection.select(0);
|
||||
}
|
||||
else if (aErrorCode == kNewsBlogInvalidFeed) // the feed was bad...
|
||||
window.alert(gFeedSubscriptionsWindow.mBundle.getFormattedString('newsblog-invalidFeed', [feed.url]));
|
||||
else if (aErrorCode == kNewsBlogRequestFailure)
|
||||
window.alert(gFeedSubscriptionsWindow.mBundle.getFormattedString('newsblog-networkError', [feed.url]));
|
||||
|
||||
// re-enable the add button now that we are done subscribing
|
||||
document.getElementById('addFeed').removeAttribute('disabled');
|
||||
|
||||
// our operation is done...clear out the status text and progressmeter
|
||||
setTimeout(clearStatusInfo, 1000);
|
||||
},
|
||||
|
||||
// this gets called after the RSS parser finishes storing a feed item to disk
|
||||
// aCurrentFeedItems is an integer corresponding to how many feed items have been downloaded so far
|
||||
// aMaxFeedItems is an integer corresponding to the total number of feed items to download
|
||||
onFeedItemStored: function (feed, aCurrentFeedItems, aMaxFeedItems)
|
||||
{
|
||||
updateStatusItem('statusText', gFeedSubscriptionsWindow.mBundle.getFormattedString("subscribe-fetchingFeedItems",
|
||||
[aCurrentFeedItems, aMaxFeedItems]));
|
||||
this.onProgress(feed, aCurrentFeedItems, aMaxFeedItems);
|
||||
},
|
||||
|
||||
onProgress: function(feed, aProgress, aProgressMax)
|
||||
{
|
||||
updateStatusItem('progressMeter', (aProgress * 100) / aProgressMax);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// opens the feed properties dialog
|
||||
function openFeedEditor(aFeedProperties)
|
||||
{
|
||||
window.openDialog('chrome://messenger-newsblog/content/feed-properties.xul', 'feedproperties', 'modal,titlebar,chrome,center', aFeedProperties);
|
||||
return aFeedProperties;
|
||||
}
|
||||
|
||||
function processDrop()
|
||||
{
|
||||
gFeedSubscriptionsWindow.addFeed(gFeedSubscriptionsWindow.mView.mDropUrl, gFeedSubscriptionsWindow.mView.mDropFolderUrl);
|
||||
}
|
||||
|
||||
// status helper routines
|
||||
|
||||
function updateStatusItem(aID, aValue)
|
||||
{
|
||||
var el = document.getElementById(aID);
|
||||
if (el.getAttribute('collapsed'))
|
||||
el.removeAttribute('collapsed');
|
||||
|
||||
el.value = aValue;
|
||||
}
|
||||
|
||||
function clearStatusInfo()
|
||||
{
|
||||
document.getElementById('statusText').value = "";
|
||||
document.getElementById('progressMeter').collapsed = true;
|
||||
}
|
||||
|
||||
function doEdit() {
|
||||
// XXX There should be some way of correlating feed RDF resources
|
||||
// with their corresponding Feed objects. Perhaps in the end much
|
||||
// of this code could hang off methods of the Feed object.
|
||||
var ds = getSubscriptionsDS(this.mRSSServer);
|
||||
var tree = document.getElementById('subscriptions');
|
||||
var item = tree.view.getItemAtIndex(tree.view.selection.currentIndex);
|
||||
var resource = rdf.GetResource(item.id);
|
||||
var old_url = ds.GetTarget(resource, DC_IDENTIFIER, true);
|
||||
old_url = old_url ? old_url.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
|
||||
var feed = new Feed(resource);
|
||||
|
||||
var currentFolder = ds.GetTarget(resource, FZ_DESTFOLDER, true);
|
||||
var currentFolderURI = currentFolder.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
||||
|
||||
currentFolder = rdf.GetResource(currentFolderURI).QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
var userModifiedFeed = false;
|
||||
var feedProperties = { feedLocation: old_url, serverURI: this.mRSSServer.serverURI,
|
||||
serverPrettyName: this.mRSSServer.prettyName, folderURI: currentFolderURI,
|
||||
quickMode: feed.quickMode, result: userModifiedFeed};
|
||||
|
||||
feedProperties = openFeedEditor(feedProperties);
|
||||
if (!feedProperties.result) // did the user cancel?
|
||||
return;
|
||||
|
||||
// did the user change the folder URI for storing the feed?
|
||||
if (feedProperties.folderURI && feedProperties.folderURI != currentFolderURI)
|
||||
{
|
||||
// unassert the older URI, add an assertion for the new URI...
|
||||
ds.Change(resource, FZ_DESTFOLDER, currentFolder, rdf.GetResource(feedProperties.folderURI));
|
||||
|
||||
// we need to update the feed url attributes on the databases for each folder
|
||||
var folderResource = rdf.GetResource(feedProperties.folderURI);
|
||||
var newFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
currentFolder = rdf.GetResource(currentFolderURI).QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
updateFolderFeedUrl(currentFolder, old_url, true); // remove our feed url property from the current folder
|
||||
updateFolderFeedUrl(newFolder, feedProperties.feedLocation, false); // add our feed url property to the new folder
|
||||
|
||||
currentFolder = newFolder; // the folder has changed
|
||||
}
|
||||
|
||||
// check to see if the location changed
|
||||
if (feedProperties.feedLocation && feedProperties.feedLocation != old_url)
|
||||
{
|
||||
ds.Change(resource, DC_IDENTIFIER, rdf.GetLiteral(old_url), rdf.GetLiteral(feedProperties.feedLocation));
|
||||
// now update our feed url property on the destination folder
|
||||
updateFolderFeedUrl(currentFolder, old_url, false); // remove the old url
|
||||
updateFolderFeedUrl(currentFolder, feedProperties.feedLocation, true); // add the new one
|
||||
}
|
||||
|
||||
// check to see if the quickMode value changed
|
||||
if (feed.quickMode != feedProperties.quickMode)
|
||||
feed.quickMode = feedProperties.quickMode;
|
||||
|
||||
ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0"?>
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Subscription Manager
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger-newsblog/skin/feed-subscriptions.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://messenger-newsblog/locale/feed-subscriptions.dtd">
|
||||
|
||||
<window id="subscriptionsDialog"
|
||||
title="&newsBlogSubscriptions.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 30em; height: 25em;"
|
||||
persist="width height"
|
||||
onload="gFeedSubscriptionsWindow.init();"
|
||||
onunload="return gFeedSubscriptionsWindow.uninit();"
|
||||
windowtype="Mail:News-BlogSubscriptions"
|
||||
flex="1">
|
||||
|
||||
<script type="application/x-javascript" src="utils.js"/>
|
||||
<script type="application/x-javascript" src="file-utils.js"/>
|
||||
<script type="application/x-javascript" src="debug-utils.js"/>
|
||||
<script type="application/x-javascript" src="feed-subscriptions.js"/>
|
||||
<script type="application/x-javascript" src="Feed.js"/>
|
||||
<script type="application/x-javascript" src="FeedItem.js"/>
|
||||
<script type="application/x-javascript" src="feed-parser.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
|
||||
|
||||
|
||||
<keyset id="extensionsKeys">
|
||||
<key id="key_close" key="&cmd.close.commandKey;" modifiers="accel" oncommand="window.close();"/>
|
||||
<key id="key_close2" keycode="VK_ESCAPE" oncommand="window.close();"/>
|
||||
</keyset>
|
||||
|
||||
<stringbundle id="bundle_newsblog" src="chrome://messenger-newsblog/locale/newsblog.properties"/>
|
||||
<description>&subscriptionDesc.label;</description>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<tree id="rssSubscriptionsList" flex="1" style="height: 10em;"
|
||||
hidecolumnpicker="true"
|
||||
onselect="gFeedSubscriptionsWindow.onRSSFeedSelected();"
|
||||
seltype="single">
|
||||
<treecols>
|
||||
<treecol id="folderNameCol" flex="2" primary="true" hideheader="true"/>
|
||||
# <splitter class="tree-splitter"/>
|
||||
# <treecol id="nameCol" label="&cookiename.label;" flex="1" persist="width"/>
|
||||
</treecols>
|
||||
<treechildren id="subscriptionChildren"/>
|
||||
</tree>
|
||||
|
||||
<hbox id="rssFeedInfoBox">
|
||||
<stack flex="1">
|
||||
<hbox id="backgroundBox" flex="1"/>
|
||||
<grid flex="1">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row align="center">
|
||||
<hbox pack="end"><label id="nameLabel" value="&feedTitle.label;"/></hbox>
|
||||
<textbox id="nameValue" readonly="true" class="plain"/>
|
||||
</row>
|
||||
<row align="center">
|
||||
<hbox pack="end"><label id="locationLabel" value="&location.label;"/></hbox>
|
||||
<textbox id="locationValue" readonly="true" class="plain"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</stack>
|
||||
</hbox>
|
||||
|
||||
|
||||
<hbox id="statusContainerBox" align="center">
|
||||
<label id="statusText" class="statusbarpanel-text" crop="right" flex="1"/>
|
||||
<progressmeter id="progressMeter" collapsed="true" class="progressmeter-statusbar" style="margin-right: 5px;" mode="normal" value="0"/>
|
||||
</hbox>
|
||||
|
||||
<hbox align="end">
|
||||
<hbox class="actionButtons" flex="1">
|
||||
<button id="addFeed"
|
||||
label="&button.addFeed.label;" accesskey="&button.addFeed.accesskey;"
|
||||
oncommand="gFeedSubscriptionsWindow.addFeed();"/>
|
||||
|
||||
<button id="removeFeed" disabled="true"
|
||||
label="&button.removeFeed.label;" accesskey="&button.removeFeed.accesskey;"
|
||||
oncommand="gFeedSubscriptionsWindow.removeFeed();"/>
|
||||
</hbox>
|
||||
|
||||
<resizer dir="bottomright"/>
|
||||
</hbox>
|
||||
|
||||
</window>
|
|
@ -17,8 +17,8 @@
|
|||
if (lastSubscriptionWindow)
|
||||
lastSubscriptionWindow.focus();
|
||||
else
|
||||
window.openDialog("chrome://messenger-newsblog/content/subscriptions.xul", "",
|
||||
"centerscreen,resizable=yes", { server: aRSSServer});
|
||||
window.openDialog("chrome://messenger-newsblog/content/feed-subscriptions.xul", "",
|
||||
"centerscreen,chrome,dialog=no,resizable", { server: aRSSServer});
|
||||
}
|
||||
|
||||
function openSubscriptionsDialogFromFolderPane()
|
||||
|
|
|
@ -1,4 +1,41 @@
|
|||
// XXX Rename this to global.js
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Utils
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
// Whether or not to dump debugging messages to the console.
|
||||
const DEBUG = false;
|
||||
|
@ -8,10 +45,7 @@ if (DEBUG)
|
|||
else
|
||||
debug = function() {}
|
||||
|
||||
var rdf =
|
||||
Components
|
||||
.classes["@mozilla.org/rdf/rdf-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFService);
|
||||
var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
|
||||
|
||||
const RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
const RDF_TYPE = rdf.GetResource(RDF_NS + "type");
|
||||
|
@ -47,40 +81,44 @@ const RDF_LITERAL_TRUE = rdf.GetLiteral("true");
|
|||
const RDF_LITERAL_FALSE = rdf.GetLiteral("false");
|
||||
|
||||
// XXX There's a containerutils in forumzilla.js that this should be merged with.
|
||||
var containerUtils =
|
||||
Components
|
||||
.classes["@mozilla.org/rdf/container-utils;1"]
|
||||
.getService(Components.interfaces.nsIRDFContainerUtils);
|
||||
var containerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]
|
||||
.getService(Components.interfaces.nsIRDFContainerUtils);
|
||||
|
||||
var fileHandler =
|
||||
Components
|
||||
.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService)
|
||||
.getProtocolHandler("file")
|
||||
.QueryInterface(Components.interfaces.nsIFileProtocolHandler);
|
||||
var fileHandler = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService)
|
||||
.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler);
|
||||
|
||||
function addFeed(url, title, destFolder) {
|
||||
var ds = getSubscriptionsDS(destFolder.server);
|
||||
var feeds = getSubscriptionsList(destFolder.server);
|
||||
// helper routine that checks our subscriptions list array and returns true if the url
|
||||
// is already in our list. This is used to prevent the user from subscribing to the same
|
||||
// feed multiple times for the same server...
|
||||
function feedAlreadyExists(aUrl, aServer)
|
||||
{
|
||||
var feeds = getSubscriptionsList(aServer);
|
||||
return feeds.IndexOf(rdf.GetResource(aUrl)) != -1;
|
||||
}
|
||||
|
||||
// Generate a unique ID for the feed.
|
||||
var id = url;
|
||||
var i = 1;
|
||||
while (feeds.IndexOf(rdf.GetResource(id)) != -1 && ++i < 1000)
|
||||
id = url + i;
|
||||
if (id == 1000)
|
||||
throw("couldn't generate a unique ID for feed " + url);
|
||||
function addFeed(url, title, destFolder)
|
||||
{
|
||||
var ds = getSubscriptionsDS(destFolder.server);
|
||||
var feeds = getSubscriptionsList(destFolder.server);
|
||||
|
||||
// Add the feed to the list.
|
||||
id = rdf.GetResource(id);
|
||||
feeds.AppendElement(id);
|
||||
ds.Assert(id, RDF_TYPE, FZ_FEED, true);
|
||||
ds.Assert(id, DC_IDENTIFIER, rdf.GetLiteral(url), true);
|
||||
if (title)
|
||||
ds.Assert(id, DC_TITLE, rdf.GetLiteral(title), true);
|
||||
ds.Assert(id, FZ_DESTFOLDER, destFolder, true);
|
||||
ds = ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
ds.Flush();
|
||||
// Generate a unique ID for the feed.
|
||||
var id = url;
|
||||
var i = 1;
|
||||
while (feeds.IndexOf(rdf.GetResource(id)) != -1 && ++i < 1000)
|
||||
id = url + i;
|
||||
if (id == 1000)
|
||||
throw("couldn't generate a unique ID for feed " + url);
|
||||
|
||||
// Add the feed to the list.
|
||||
id = rdf.GetResource(id);
|
||||
feeds.AppendElement(id);
|
||||
ds.Assert(id, RDF_TYPE, FZ_FEED, true);
|
||||
ds.Assert(id, DC_IDENTIFIER, rdf.GetLiteral(url), true);
|
||||
if (title)
|
||||
ds.Assert(id, DC_TITLE, rdf.GetLiteral(title), true);
|
||||
ds.Assert(id, FZ_DESTFOLDER, destFolder, true);
|
||||
ds = ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
ds.Flush();
|
||||
}
|
||||
|
||||
// updates the "feedUrl" property in the message database for the folder in question.
|
||||
|
@ -106,12 +144,15 @@ function updateFolderFeedUrl(aFolder, aFeedUrl, aRemoveUrl)
|
|||
msgdb.Close(true);
|
||||
}
|
||||
|
||||
function getNodeValue(node) {
|
||||
function getNodeValue(node)
|
||||
{
|
||||
if (node && node.textContent)
|
||||
return node.textContent;
|
||||
else if (node && node.firstChild) {
|
||||
else if (node && node.firstChild)
|
||||
{
|
||||
var ret = "";
|
||||
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||||
for (var child = node.firstChild; child; child = child.nextSibling)
|
||||
{
|
||||
var value = getNodeValue(child);
|
||||
if (value)
|
||||
ret += value;
|
||||
|
@ -124,9 +165,11 @@ function getNodeValue(node) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function getRDFTargetValue(ds, source, property) {
|
||||
function getRDFTargetValue(ds, source, property)
|
||||
{
|
||||
var node = ds.GetTarget(source, property, true);
|
||||
if (node) {
|
||||
if (node)
|
||||
{
|
||||
node = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if (node)
|
||||
return node.Value;
|
||||
|
@ -135,31 +178,34 @@ function getRDFTargetValue(ds, source, property) {
|
|||
}
|
||||
|
||||
var gFzSubscriptionsDS; // cache
|
||||
function getSubscriptionsDS(server) {
|
||||
if (gFzSubscriptionsDS)
|
||||
return gFzSubscriptionsDS;
|
||||
|
||||
var file = getSubscriptionsFile(server);
|
||||
var url = fileHandler.getURLSpecFromFile(file);
|
||||
|
||||
gFzSubscriptionsDS = rdf.GetDataSourceBlocking(url);
|
||||
|
||||
if (!gFzSubscriptionsDS)
|
||||
throw("can't get subscriptions data source");
|
||||
|
||||
function getSubscriptionsDS(server)
|
||||
{
|
||||
if (gFzSubscriptionsDS)
|
||||
return gFzSubscriptionsDS;
|
||||
|
||||
var file = getSubscriptionsFile(server);
|
||||
var url = fileHandler.getURLSpecFromFile(file);
|
||||
|
||||
gFzSubscriptionsDS = rdf.GetDataSourceBlocking(url);
|
||||
|
||||
if (!gFzSubscriptionsDS)
|
||||
throw("can't get subscriptions data source");
|
||||
|
||||
return gFzSubscriptionsDS;
|
||||
}
|
||||
|
||||
function getSubscriptionsList(server) {
|
||||
var ds = getSubscriptionsDS(server);
|
||||
var list = ds.GetTarget(FZ_ROOT, FZ_FEEDS, true);
|
||||
//list = feeds.QueryInterface(Components.interfaces.nsIRDFContainer);
|
||||
list = list.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
list = containerUtils.MakeSeq(ds, list);
|
||||
return list;
|
||||
function getSubscriptionsList(server)
|
||||
{
|
||||
var ds = getSubscriptionsDS(server);
|
||||
var list = ds.GetTarget(FZ_ROOT, FZ_FEEDS, true);
|
||||
//list = feeds.QueryInterface(Components.interfaces.nsIRDFContainer);
|
||||
list = list.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
list = containerUtils.MakeSeq(ds, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
function getSubscriptionsFile(server) {
|
||||
function getSubscriptionsFile(server)
|
||||
{
|
||||
server.QueryInterface(Components.interfaces.nsIRssIncomingServer);
|
||||
var file = server.subscriptionsDataSourcePath;
|
||||
|
||||
|
@ -170,7 +216,8 @@ function getSubscriptionsFile(server) {
|
|||
return file;
|
||||
}
|
||||
|
||||
function createSubscriptionsFile(file) {
|
||||
function createSubscriptionsFile(file)
|
||||
{
|
||||
file = new LocalFile(file, MODE_WRONLY | MODE_CREATE);
|
||||
file.write('\
|
||||
<?xml version="1.0"?>\n\
|
||||
|
@ -189,31 +236,32 @@ function createSubscriptionsFile(file) {
|
|||
}
|
||||
|
||||
var gFzItemsDS; // cache
|
||||
function getItemsDS(server) {
|
||||
if (gFzItemsDS)
|
||||
return gFzItemsDS;
|
||||
|
||||
var file = getItemsFile(server);
|
||||
var url = fileHandler.getURLSpecFromFile(file);
|
||||
|
||||
gFzItemsDS = rdf.GetDataSourceBlocking(url);
|
||||
if (!gFzItemsDS)
|
||||
throw("can't get subscriptions data source");
|
||||
|
||||
// Note that it this point the datasource may not be loaded yet.
|
||||
// You have to QueryInterface it to nsIRDFRemoteDataSource and check
|
||||
// its "loaded" property to be sure. You can also attach an observer
|
||||
// which will get notified when the load is complete.
|
||||
|
||||
function getItemsDS(server)
|
||||
{
|
||||
if (gFzItemsDS)
|
||||
return gFzItemsDS;
|
||||
|
||||
var file = getItemsFile(server);
|
||||
var url = fileHandler.getURLSpecFromFile(file);
|
||||
gFzItemsDS = rdf.GetDataSourceBlocking(url);
|
||||
if (!gFzItemsDS)
|
||||
throw("can't get subscriptions data source");
|
||||
|
||||
// Note that it this point the datasource may not be loaded yet.
|
||||
// You have to QueryInterface it to nsIRDFRemoteDataSource and check
|
||||
// its "loaded" property to be sure. You can also attach an observer
|
||||
// which will get notified when the load is complete.
|
||||
return gFzItemsDS;
|
||||
}
|
||||
|
||||
function getItemsFile(server) {
|
||||
function getItemsFile(server)
|
||||
{
|
||||
server.QueryInterface(Components.interfaces.nsIRssIncomingServer);
|
||||
var file = server.feedItemsDataSourcePath;
|
||||
|
||||
// If the file doesn't exist, create it.
|
||||
if (!file.exists()) {
|
||||
if (!file.exists())
|
||||
{
|
||||
var newfile = new LocalFile(file, MODE_WRONLY | MODE_CREATE);
|
||||
newfile.write('\
|
||||
<?xml version="1.0"?>\n\
|
||||
|
@ -227,51 +275,57 @@ function getItemsFile(server) {
|
|||
return file;
|
||||
}
|
||||
|
||||
function removeAssertions(ds, resource) {
|
||||
var properties = ds.ArcLabelsOut(resource);
|
||||
var property;
|
||||
while (properties.hasMoreElements()) {
|
||||
property = properties.getNext();
|
||||
var values = ds.GetTargets(resource, property, true);
|
||||
var value;
|
||||
while (values.hasMoreElements()) {
|
||||
value = values.getNext();
|
||||
ds.Unassert(resource, property, value, true);
|
||||
}
|
||||
function removeAssertions(ds, resource)
|
||||
{
|
||||
var properties = ds.ArcLabelsOut(resource);
|
||||
var property;
|
||||
while (properties.hasMoreElements())
|
||||
{
|
||||
property = properties.getNext();
|
||||
var values = ds.GetTargets(resource, property, true);
|
||||
var value;
|
||||
while (values.hasMoreElements())
|
||||
{
|
||||
value = values.getNext();
|
||||
ds.Unassert(resource, property, value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Date validator for RSS feeds
|
||||
const FZ_RFC822_RE = "^(((Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)), *)?\\d\\d?"
|
||||
+ " +((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec))"
|
||||
+ " +\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? +(([+-]?\\d\\d\\d\\d)|(UT)|(GMT)"
|
||||
+ "|(EST)|(EDT)|(CST)|(CDT)|(MST)|(MDT)|(PST)|(PDT)|\\w)$";
|
||||
|
||||
function isValidRFC822Date(pubDate){
|
||||
var regex = new RegExp(FZ_RFC822_RE);
|
||||
return regex.test(pubDate);
|
||||
function isValidRFC822Date(pubDate)
|
||||
{
|
||||
var regex = new RegExp(FZ_RFC822_RE);
|
||||
return regex.test(pubDate);
|
||||
}
|
||||
|
||||
function dateRescue(dateString){
|
||||
function dateRescue(dateString)
|
||||
{
|
||||
// Deal with various kinds of invalid dates
|
||||
// Just timestamps for now.
|
||||
if(!isNaN(parseInt(dateString))) {//It's an integer, so maybe it's a timestamp
|
||||
if(!isNaN(parseInt(dateString)))
|
||||
{ //It's an integer, so maybe it's a timestamp
|
||||
var d = new Date(parseInt(dateString)*1000);
|
||||
var now = new Date();
|
||||
var yeardiff = now.getFullYear()-d.getFullYear();
|
||||
debug("Rescue Timestamp date: " + d.toString() + "\nYear diff:" + yeardiff + "\n");
|
||||
if((yeardiff >= 0) && (yeardiff<3)){
|
||||
if((yeardiff >= 0) && (yeardiff<3))
|
||||
{
|
||||
//it's quite likely the correct date
|
||||
return d.toString();
|
||||
}
|
||||
}
|
||||
// Can't help. Set to current time.
|
||||
return (new Date()).toString();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Could be a prototype on String, but I don't know the policy on that
|
||||
function trimString(s){
|
||||
return(s.replace(/^\s+/,'').replace(/\s+$/,''));
|
||||
function trimString(s)
|
||||
{
|
||||
return(s.replace(/^\s+/,'').replace(/\s+$/,''));
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
newsblog.jar:
|
||||
* content/messenger-newsblog/toolbar-icon.xul (content/toolbar-icon.xul)
|
||||
* content/messenger-newsblog/subscriptions.xul (content/subscriptions.xul)
|
||||
* content/messenger-newsblog/edittree.xml (content/edittree.xml)
|
||||
* content/messenger-newsblog/debug-utils.js (content/debug-utils.js)
|
||||
* content/messenger-newsblog/Feed.js (content/Feed.js)
|
||||
* content/messenger-newsblog/FeedItem.js (content/FeedItem.js)
|
||||
* content/messenger-newsblog/feed-parser.js (content/feed-parser.js)
|
||||
* content/messenger-newsblog/file-utils.js (content/file-utils.js)
|
||||
* content/messenger-newsblog/subscriptions.js (content/subscriptions.js)
|
||||
* content/messenger-newsblog/utils.js (content/utils.js)
|
||||
* content/messenger-newsblog/feed-properties.xul (content/feed-properties.xul)
|
||||
* content/messenger-newsblog/feed-properties.js (content/feed-properties.js)
|
||||
* content/messenger-newsblog/feed-subscriptions.js (content/feed-subscriptions.js)
|
||||
* content/messenger-newsblog/feed-subscriptions.xul (content/feed-subscriptions.xul)
|
||||
* content/messenger-newsblog/am-newsblog.xul (content/am-newsblog.xul)
|
||||
* content/messenger-newsblog/am-newsblog.js (content/am-newsblog.js)
|
||||
* content/messenger-newsblog/contents.rdf (content/contents.rdf)
|
||||
|
|
|
@ -95,9 +95,8 @@ var nsNewsBlogFeedDownloader =
|
|||
if (feedUrlArray[url])
|
||||
{
|
||||
id = rdf.GetResource(feedUrlArray[url]);
|
||||
feed = new Feed(id);
|
||||
feed = new Feed(id, aFolder.server);
|
||||
feed.folder = aFolder;
|
||||
feed.server = aFolder.server;
|
||||
gNumPendingFeedDownloads++; // bump our pending feed download count
|
||||
feed.download(true, progressNotifier);
|
||||
}
|
||||
|
@ -109,21 +108,27 @@ var nsNewsBlogFeedDownloader =
|
|||
if (!gExternalScriptsLoaded)
|
||||
loadScripts();
|
||||
|
||||
// we don't support the ability to subscribe to several feeds at once yet...
|
||||
// for now, abort the subscription if we are already in the middle of subscribing to a feed
|
||||
// via drag and drop.
|
||||
if (gNumPendingFeedDownloads)
|
||||
{
|
||||
debug('Aborting RSS subscription. Feed downloads already in progress\n');
|
||||
return;
|
||||
}
|
||||
// we don't support the ability to subscribe to several feeds at once yet...
|
||||
// for now, abort the subscription if we are already in the middle of subscribing to a feed
|
||||
// via drag and drop.
|
||||
if (gNumPendingFeedDownloads)
|
||||
{
|
||||
debug('Aborting RSS subscription. Feed downloads already in progress\n');
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we aren't already subscribed to this feed before we attempt to subscribe to it.
|
||||
if (feedAlreadyExists(aUrl, aFolder.server))
|
||||
{
|
||||
aMsgWindow.statusFeedback.showStatusString(GetNewsBlogStringBundle().GetStringFromName('subscribe-feedAlreadySubscribed'));
|
||||
return;
|
||||
}
|
||||
|
||||
var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFService);
|
||||
|
||||
var itemResource = rdf.GetResource(aUrl);
|
||||
var feed = new Feed(itemResource);
|
||||
feed.server = aFolder.server;
|
||||
var feed = new Feed(itemResource, aFolder.server);
|
||||
feed.quickMode = feed.server.getBoolAttribute('quickMode');
|
||||
|
||||
if (!aFolder.isServer) // if the root server, create a new folder for the feed
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Subscription CSS
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
/* ::::: Feed Subscription UI icons :::::: */
|
||||
|
||||
#subscriptionsDialog {
|
||||
padding: 8px 10px 10px 8px;
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol) {
|
||||
margin-right: 2px;
|
||||
list-style-image: url("chrome://messenger-newsblog/skin/icons/rss-feed.png");
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol, container) {
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-closed.png");
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol, container, open) {
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-open.png");
|
||||
}
|
||||
|
||||
#rssFeedInfoBox {
|
||||
border: 1px solid ThreeDShadow;
|
||||
-moz-border-radius: 0px;
|
||||
margin: 4px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#rssFeedInfoBox textbox {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#backgroundBox {
|
||||
background-color: #FFFFFF;
|
||||
opacity: 0.5;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
classic.jar:
|
||||
skin/classic/messenger-newsblog/subscriptions.css (subscriptions.css)
|
||||
skin/classic/messenger-newsblog/newsBlogOverlay.css (newsBlogOverlay.css)
|
||||
* skin/classic/messenger-newsblog/feed-subscriptions.css (feed-subscriptions.css)
|
||||
* skin/classic/messenger-newsblog/newsBlogOverlay.css (newsBlogOverlay.css)
|
||||
skin/classic/messenger-newsblog/icons/rss-feed.png (rss-feed.png )
|
||||
skin/classic/messenger-newsblog/icons/rss-feed-new.png (rss-feed-new.png)
|
||||
skin/classic/messenger-newsblog/icons/server-rss.png (server-rss.png)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Subscription CSS
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
/* ::::: Feed Subscription UI icons :::::: */
|
||||
|
||||
#subscriptionsDialog {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol) {
|
||||
margin-right: 2px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-newsgroup.png");
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol, container) {
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-closed.png");
|
||||
}
|
||||
|
||||
#subscriptionChildren::-moz-tree-image(folderNameCol, container, open) {
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-open.png");
|
||||
}
|
||||
|
||||
#rssFeedInfoBox {
|
||||
border: 1px solid ThreeDShadow;
|
||||
-moz-border-radius: 0px;
|
||||
margin: 4px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#rssFeedInfoBox textbox {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#backgroundBox {
|
||||
background-color: #FFFFFF;
|
||||
opacity: 0.5;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
classic.jar:
|
||||
skin/classic/messenger-newsblog/subscriptions.css (subscriptions.css)
|
||||
skin/classic/messenger-newsblog/newsBlogOverlay.css (newsBlogOverlay.css)
|
||||
* skin/classic/messenger-newsblog/feed-subscriptions.css (feed-subscriptions.css)
|
||||
* skin/classic/messenger-newsblog/newsBlogOverlay.css (newsBlogOverlay.css)
|
||||
skin/classic/messenger-newsblog/icons/folder-search-rss.png (folder-search-rss.png)
|
||||
skin/classic/messenger-newsblog/contents.rdf
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
/* ***** 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 RSS News & Blogs CSS Overlay style rules.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@melez.com>
|
||||
* Scott MacGregor <mscott@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 ***** */
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS Subscription CSS
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
/* ::::: Folder Pane icons :::::: */
|
||||
|
||||
|
|
|
@ -1,40 +1,41 @@
|
|||
/* ***** 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 RSS News & Blogs CSS Overlay style rules.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@melez.com>
|
||||
* Scott MacGregor <mscott@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 ***** */
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# ***** 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 Thunderbird RSS News & Blogs CSS Overlay style rules.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Myk Melez <myk@melez.com>
|
||||
# Scott MacGregor <mscott@mozilla.org>
|
||||
#
|
||||
# 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 ******
|
||||
|
||||
/* ::::: Folder Pane icons :::::: */
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<!-- Feed Properties Dialog -->
|
||||
<!ENTITY window.title "News Feed Properties">
|
||||
<!ENTITY window.title "Feed Properties">
|
||||
|
||||
<!ENTITY feedFolder.label "Store Feed Articles in: ">
|
||||
<!ENTITY feedFolder.label "Store Articles in: ">
|
||||
<!ENTITY feedFolder.accesskey "S">
|
||||
|
||||
<!ENTITY choosethisfolder.label "choose this folder">
|
||||
|
||||
<!ENTITY feedLocation.label "Feed URL: ">
|
||||
<!ENTITY feedLocation.accesskey "F">
|
||||
|
||||
<!ENTITY choosethisfolder.label "choose this folder">
|
||||
|
||||
<!ENTITY quickMode.label "Show the article summary instead of loading the web page">
|
||||
<!ENTITY quickMode.accesskey "h">
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!-- Subscription Dialog -->
|
||||
<!ENTITY newsBlogSubscriptions.label "RSS Subscriptions">
|
||||
<!ENTITY subscriptionDesc.label "Note: Removing or changing the folder for a feed will not effect previously downloaded articles.">
|
||||
<!ENTITY feedTitle.label "Title:">
|
||||
<!ENTITY location.label "Location:">
|
||||
|
||||
<!ENTITY button.addFeed.label "Add Feed">
|
||||
<!ENTITY button.addFeed.accesskey "A">
|
||||
<!ENTITY editButton.label "Edit">
|
||||
<!ENTITY editButton.accesskey "E">
|
||||
<!ENTITY button.removeFeed.label "Remove Feed">
|
||||
<!ENTITY button.removeFeed.accesskey "R">
|
||||
|
||||
<!ENTITY cmd.close.commandKey "w">
|
|
@ -2,17 +2,4 @@
|
|||
<!ENTITY folderContextRSSSubscribe.label "Manage Subscriptions...">
|
||||
<!ENTITY folderContextRSSSubscribe.accesskey "M">
|
||||
|
||||
<!-- Subscription Dialog -->
|
||||
<!ENTITY newsBlogSubscriptions.label "RSS Subscriptions">
|
||||
<!ENTITY subscriptionDesc.label "Manage your RSS Subscriptions.">
|
||||
<!ENTITY feedNameTreeCol.label "Name">
|
||||
<!ENTITY locationTreeCol.label "Location">
|
||||
<!ENTITY addButton.label "Add">
|
||||
<!ENTITY addButton.accesskey "A">
|
||||
<!ENTITY editButton.label "Edit">
|
||||
<!ENTITY editButton.accesskey "E">
|
||||
<!ENTITY deleteButton.label "Delete">
|
||||
<!ENTITY deleteButton.accesskey "D">
|
||||
|
||||
<!ENTITY feedNameTreeCol.label "Name">
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
subscribe-validating=Verifying the RSS feed...
|
||||
subscribe-cancelSubscription=Are you sure you wish to cancel subscribing to the current feed?
|
||||
subscribe-cancelSubscriptionTitle=Subscribing to a Feed...
|
||||
subscribe-noFeedSelected=<no RSS feed selected>
|
||||
subscribe-feedAlreadySubscribed=You already have a subscription for this feed.
|
||||
|
||||
#LOCALIZATION NOTE: %S is the name of the feed the user wants to unsubscribe from.
|
||||
subsribe-confirmFeedDeletionTitle=Remove Feed
|
||||
subsribe-confirmFeedDeletion=Are you sure you want to unsubscribe from the feed: \n %S?
|
||||
|
||||
# when downloading new feed items from the subscribe dialog.
|
||||
# LOCALIZATION NOTE: Do not translate %d in the following line.
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
* locale/@AB_CD@/messenger-newsblog/contents.rdf (generic/chrome/messenger-newsblog/contents.rdf)
|
||||
locale/@AB_CD@/messenger-newsblog/newsblog.dtd (@AB_CD@/chrome/messenger-newsblog/newsblog.dtd)
|
||||
locale/@AB_CD@/messenger-newsblog/newsblog.properties (@AB_CD@/chrome/messenger-newsblog/newsblog.properties)
|
||||
locale/@AB_CD@/messenger-newsblog/feed-subscriptions.dtd (@AB_CD@/chrome/messenger-newsblog/feed-subscriptions.dtd)
|
||||
locale/@AB_CD@/messenger-newsblog/feed-properties.dtd (@AB_CD@/chrome/messenger-newsblog/feed-properties.dtd)
|
||||
locale/@AB_CD@/messenger-newsblog/am-newsblog.properties (@AB_CD@/chrome/messenger-newsblog/am-newsblog.properties)
|
||||
locale/@AB_CD@/messenger-newsblog/am-newsblog.dtd (@AB_CD@/chrome/messenger-newsblog/am-newsblog.dtd)
|
||||
|
|
Загрузка…
Ссылка в новой задаче