-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathFeedContainer.jsm
243 lines (193 loc) · 5.21 KB
/
FeedContainer.jsm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
const EXPORTED_SYMBOLS = ['Feed', 'Entry', 'EntryList'];
Components.utils.import('resource://digest/common.jsm');
IMPORT_COMMON(this);
/**
* Container for feed properties.
*/
function Feed() { }
Feed.prototype = {
/**
* Unique string identifying an entry in Brief's database.
*/
feedID: '',
/**
* Feed's properties.
*/
feedURL: '',
websiteURL: '',
title: '',
subtitle: '',
dateModified: 0,
/**
* base64-encoded data: URI of the favicon of the site under websiteURL.
*/
favicon: '',
/**
* Date when the feed was last checked for updates.
*/
lastUpdated: 0,
/**
* Date when the feed's favicon was last refreshed.
*/
lastFaviconRefresh: 0,
/**
* ID of the Live Bookmark.
*/
bookmarkID: '',
/**
* Index of the feed's Live Bookmark relative to the Brief's home folder
* (not to the Live Bookmark's direct parent).
*/
rowIndex: 0,
isFolder: false,
/**
* feedID of the parent folder.
*/
parent: '',
/**
* Feed's preferences.
*/
entryAgeLimit: 0,
maxEntries: 0,
updateInterval: 0,
markModifiedEntriesUnread: false,
omitInUnread: 0,
/**
* Date of the oldest entry that was available
* when the feed was checked for updates.
*/
oldestEntryDate: 0,
/**
* Indicates if feed is active, i.e. can be found in the home folder.
* The value is 0 if the feed is active, otherwise it indicates the time
* when it was set to inactive.
*/
hidden: 0,
/**
* The wrapped nsIFeed.
*/
wrappedFeed: null,
}
/**
* Container for feed entry data.
*
* @param aEntry [optional]
* nsIFeedEntry object to wrap.
*/
function Entry(aEntry) {
if (!aEntry)
return;
this.wrappedEntry = aEntry;
if (aEntry.title)
this.title = aEntry.title.text;
if (aEntry.link)
this.entryURL = aEntry.link.spec;
if (aEntry.summary)
this.summary = aEntry.summary.text;
if (aEntry.content)
this.content = aEntry.content.text;
if (aEntry.updated)
this.date = new RFC822Date(aEntry.updated).getTime();
else if (aEntry.published)
this.date = new RFC822Date(aEntry.published).getTime();
try {
if (aEntry.authors) {
let authors = [];
for (let i = 0; i < aEntry.authors.length; i++) {
let author = aEntry.authors.queryElementAt(i, Ci.nsIFeedPerson).name;
authors.push(author);
}
this.authors = authors.join(', ');
}
}
catch (e) {
// With some feeds accessing nsIFeedContainer.authors throws.
}
}
Entry.prototype = {
/**
* Unique number identifying an entry in Brief's database.
*/
id: 0,
/**
* ID of feed to which the entry belongs.
*/
feedID: '',
/**
* Entry's data.
*/
entryURL: '',
title: '',
summary: '',
content: '',
date: 0,
authors: '',
/**
* Status information.
*/
read: false,
starred: false,
updated: false,
/**
* ID if the corresponing bookmark, or -1 if entry isn't bookmarked.
*/
bookmarkID: -1,
/**
* Array of tags associated with the entry's URI.
*/
tags: null,
/**
* Wrapped nsIFeedEntry.
*/
wrappedEntry: null
}
/**
* A simple list of entries.
*/
function EntryList() { }
EntryList.prototype = {
/**
* Number of entries in the list.
*/
get length() this.IDs ? this.IDs.length : 0,
/**
* Array of entry IDs.
*/
IDs: null,
/**
* Array of distinct feeds to which entries in the list belong.
*/
feeds: null,
/**
* Array of distinct tags which entries in the list have.
*/
tags: null
}
function RFC822Date(aDateString) {
let date = new Date(aDateString);
// If the date is invalid, it may be caused by the fact that the built-in date parser
// doesn't handle military timezone codes, even though they are part of RFC822.
// We can fix this by manually replacing the military timezone code with the actual
// timezone.
if (date.toString().match('invalid','i')) {
let timezoneCodes = aDateString.match(/\s[a-ik-zA-IK-Z]$/);
if (timezoneCodes) {
let timezoneCode = timezoneCodes[0];
// Strip whitespace and normalize to upper case.
timezoneCode = timezoneCode.replace(/^\s+/,'')[0].toUpperCase();
let timezone = milTimezoneCodesMap[timezoneCode];
let fixedDateString = aDateString.replace(/\s[a-ik-zA-IK-Z]$/, ' ' + timezone);
date = new Date(fixedDateString);
}
// If the date is still invalid, just use the current date.
if (date.toString().match('invalid','i'))
date = new Date();
}
return date;
}
// Conversion table for military coded timezones.
let milTimezoneCodesMap = {
A: '-1', B: '-2', C: '-3', D: '-4', E: '-5', F: '-6', G: '-7', H: '-8', I: '-9',
K: '-10', L: '-11', M: '-12', N: '+1', O: '+2', P: '+3', Q: '+4', R: '+5',
S: '+6', T: '+7', U: '+8', V: '+9', W: '+10', X: '+11', Y: '+12', Z: 'UT',
}