mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 14:17:30 +09:00
parent
d60003b8d1
commit
f1a3fd9fda
5 changed files with 133 additions and 56 deletions
|
|
@ -400,10 +400,12 @@ nsresult nsMsgDBView::FetchAuthor(nsIMsgDBHdr * aHdr, nsAString &aSenderString)
|
||||||
nsCString headerCharset;
|
nsCString headerCharset;
|
||||||
aHdr->GetEffectiveCharset(headerCharset);
|
aHdr->GetEffectiveCharset(headerCharset);
|
||||||
|
|
||||||
nsCString emailAddress;
|
|
||||||
nsString name;
|
nsString name;
|
||||||
ExtractFirstAddress(EncodedHeader(author, headerCharset.get()), name,
|
nsCString emailAddress;
|
||||||
emailAddress);
|
nsCOMArray<msgIAddressObject> addresses = EncodedHeader(author, headerCharset.get());
|
||||||
|
bool multipleAuthors = addresses.Length() > 1;
|
||||||
|
|
||||||
|
ExtractFirstAddress(addresses, name, emailAddress);
|
||||||
|
|
||||||
if (showCondensedAddresses)
|
if (showCondensedAddresses)
|
||||||
GetDisplayNameInAddressBook(emailAddress, aSenderString);
|
GetDisplayNameInAddressBook(emailAddress, aSenderString);
|
||||||
|
|
@ -429,6 +431,12 @@ nsresult nsMsgDBView::FetchAuthor(nsIMsgDBHdr * aHdr, nsAString &aSenderString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (multipleAuthors)
|
||||||
|
{
|
||||||
|
aSenderString.AppendLiteral(" ");
|
||||||
|
aSenderString.Append(GetString(u"andOthers"));
|
||||||
|
}
|
||||||
|
|
||||||
UpdateCachedName(aHdr, "sender_name", aSenderString);
|
UpdateCachedName(aHdr, "sender_name", aSenderString);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,10 @@ FeedItem.prototype =
|
||||||
content: null,
|
content: null,
|
||||||
enclosures: [],
|
enclosures: [],
|
||||||
title: null,
|
title: null,
|
||||||
author: "anonymous",
|
// Author must be angle bracket enclosed to function as an addr-spec, in the
|
||||||
|
// absence of an addr-spec portion of an RFC5322 email address, as other
|
||||||
|
// functionality (gloda search) depends on this.
|
||||||
|
author: "<anonymous>",
|
||||||
inReplyTo: "",
|
inReplyTo: "",
|
||||||
keywords: [],
|
keywords: [],
|
||||||
mURL: null,
|
mURL: null,
|
||||||
|
|
@ -245,12 +248,10 @@ FeedItem.prototype =
|
||||||
{
|
{
|
||||||
FeedUtils.log.trace("FeedItem.writeToFolder: " + this.identity +
|
FeedUtils.log.trace("FeedItem.writeToFolder: " + this.identity +
|
||||||
" writing to message folder " + this.feed.name);
|
" writing to message folder " + this.feed.name);
|
||||||
// Convert the title to UTF-16 before performing our HTML entity
|
|
||||||
// replacement reg expressions.
|
|
||||||
let title = this.title;
|
|
||||||
|
|
||||||
// The subject may contain HTML entities. Convert these to their unencoded
|
// The subject may contain HTML entities. Convert these to their unencoded
|
||||||
// state. i.e. & becomes '&'.
|
// state. i.e. & becomes '&'.
|
||||||
|
let title = this.title;
|
||||||
title = this.mParserUtils.convertToPlainText(
|
title = this.mParserUtils.convertToPlainText(
|
||||||
title,
|
title,
|
||||||
Ci.nsIDocumentEncoder.OutputSelectionOnly |
|
Ci.nsIDocumentEncoder.OutputSelectionOnly |
|
||||||
|
|
@ -274,32 +275,11 @@ FeedItem.prototype =
|
||||||
("References: " + this.inReplyTo + "\n" +
|
("References: " + this.inReplyTo + "\n" +
|
||||||
"In-Reply-To: " + this.inReplyTo + "\n") : "";
|
"In-Reply-To: " + this.inReplyTo + "\n") : "";
|
||||||
|
|
||||||
// If there are keywords (categories), create the headers. In the case of
|
// Support multiple authors in From.
|
||||||
// a longer than RFC5322 recommended line length, create multiple folded
|
let fromStr = this.createHeaderStrFromArray("From: ", this.author);
|
||||||
// lines (easier to parse than multiple Keywords headers).
|
|
||||||
let keywordsStr = "";
|
// If there are keywords (categories), create the headers.
|
||||||
if (this.keywords.length)
|
let keywordsStr = this.createHeaderStrFromArray("Keywords: ", this.keywords);
|
||||||
{
|
|
||||||
let HEADER = "Keywords: ";
|
|
||||||
let MAXLEN = 78;
|
|
||||||
keywordsStr = HEADER;
|
|
||||||
let keyword;
|
|
||||||
let keywords = [].concat(this.keywords);
|
|
||||||
let lines = [];
|
|
||||||
while (keywords.length)
|
|
||||||
{
|
|
||||||
keyword = keywords.shift();
|
|
||||||
if (keywordsStr.length + keyword.length > MAXLEN)
|
|
||||||
{
|
|
||||||
lines.push(keywordsStr)
|
|
||||||
keywordsStr = " ".repeat(HEADER.length);
|
|
||||||
}
|
|
||||||
keywordsStr += keyword + ",";
|
|
||||||
}
|
|
||||||
keywordsStr = keywordsStr.replace(/,$/,"\n");
|
|
||||||
lines.push(keywordsStr)
|
|
||||||
keywordsStr = lines.join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape occurrences of "From " at the beginning of lines of
|
// Escape occurrences of "From " at the beginning of lines of
|
||||||
// content per the mbox standard, since "From " denotes a new
|
// content per the mbox standard, since "From " denotes a new
|
||||||
|
|
@ -323,7 +303,7 @@ FeedItem.prototype =
|
||||||
'Received: by localhost; ' + FeedUtils.getValidRFC5322Date() + '\n' +
|
'Received: by localhost; ' + FeedUtils.getValidRFC5322Date() + '\n' +
|
||||||
'Date: ' + this.mDate + '\n' +
|
'Date: ' + this.mDate + '\n' +
|
||||||
'Message-Id: ' + this.normalizeMessageID(this.id) + '\n' +
|
'Message-Id: ' + this.normalizeMessageID(this.id) + '\n' +
|
||||||
'From: ' + this.author + '\n' +
|
fromStr +
|
||||||
'MIME-Version: 1.0\n' +
|
'MIME-Version: 1.0\n' +
|
||||||
'Subject: ' + this.title + '\n' +
|
'Subject: ' + this.title + '\n' +
|
||||||
inreplytoHdrsStr +
|
inreplytoHdrsStr +
|
||||||
|
|
@ -368,6 +348,49 @@ FeedItem.prototype =
|
||||||
this.tagItem(msgDBHdr, this.keywords);
|
this.tagItem(msgDBHdr, this.keywords);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a header string from an array. Intended for comma separated headers
|
||||||
|
* like From or Keywords. In the case of a longer than RFC5322 recommended
|
||||||
|
* line length, create multiple folded lines (easier to parse than multiple
|
||||||
|
* headers).
|
||||||
|
*
|
||||||
|
* @param {String} headerName - Name of the header.
|
||||||
|
* @param {String[]} headerItemsArray - An Array of strings to concatenate.
|
||||||
|
*
|
||||||
|
* @returns {String} - The header string.
|
||||||
|
*/
|
||||||
|
createHeaderStrFromArray(headerName, headerItemsArray) {
|
||||||
|
let headerStr = "";
|
||||||
|
if (!headerItemsArray || headerItemsArray.length == 0) {
|
||||||
|
return headerStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HEADER = headerName;
|
||||||
|
const LINELENGTH = 78;
|
||||||
|
const MAXLINELENGTH = 990;
|
||||||
|
let items = [].concat(headerItemsArray);
|
||||||
|
let lines = [];
|
||||||
|
headerStr = HEADER;
|
||||||
|
while (items.length) {
|
||||||
|
let item = items.shift();
|
||||||
|
if (headerStr.length + item.length > LINELENGTH &&
|
||||||
|
headerStr.length > HEADER.length) {
|
||||||
|
lines.push(headerStr);
|
||||||
|
headerStr = " ".repeat(HEADER.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
headerStr += headerStr.length + item.length > MAXLINELENGTH ?
|
||||||
|
item.substr(0, MAXLINELENGTH - headerStr.length) + "…, " :
|
||||||
|
item + ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
headerStr = headerStr.replace(/,\s$/, "\n");
|
||||||
|
lines.push(headerStr);
|
||||||
|
headerStr = lines.join("\n");
|
||||||
|
|
||||||
|
return headerStr;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autotag messages.
|
* Autotag messages.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ var FeedUtils = {
|
||||||
},
|
},
|
||||||
|
|
||||||
DC_NS: "http://purl.org/dc/elements/1.1/",
|
DC_NS: "http://purl.org/dc/elements/1.1/",
|
||||||
|
get DC_PUBLISHER() { return this.rdf.GetResource(this.DC_NS + "publisher"); },
|
||||||
get DC_CREATOR() { return this.rdf.GetResource(this.DC_NS + "creator") },
|
get DC_CREATOR() { return this.rdf.GetResource(this.DC_NS + "creator") },
|
||||||
get DC_SUBJECT() { return this.rdf.GetResource(this.DC_NS + "subject") },
|
get DC_SUBJECT() { return this.rdf.GetResource(this.DC_NS + "subject") },
|
||||||
get DC_DATE() { return this.rdf.GetResource(this.DC_NS + "date") },
|
get DC_DATE() { return this.rdf.GetResource(this.DC_NS + "date") },
|
||||||
|
|
|
||||||
|
|
@ -222,9 +222,10 @@ FeedParser.prototype =
|
||||||
tags = this.childrenByTagNameNS(itemNode, nsURI, "author");
|
tags = this.childrenByTagNameNS(itemNode, nsURI, "author");
|
||||||
if (!tags)
|
if (!tags)
|
||||||
tags = this.childrenByTagNameNS(itemNode, FeedUtils.DC_NS, "creator");
|
tags = this.childrenByTagNameNS(itemNode, FeedUtils.DC_NS, "creator");
|
||||||
item.author = this.getNodeValue(tags ? tags[0] : null) ||
|
let author = this.getNodeValue(tags ? tags[0] : null) ||
|
||||||
aFeed.title ||
|
aFeed.title;
|
||||||
item.author;
|
author = this.cleanAuthorName(author);
|
||||||
|
item.author = author ? ["<" + author + ">"] : item.author;
|
||||||
|
|
||||||
tags = this.childrenByTagNameNS(itemNode, nsURI, "pubDate");
|
tags = this.childrenByTagNameNS(itemNode, nsURI, "pubDate");
|
||||||
if (!tags || !this.getNodeValue(tags[0]))
|
if (!tags || !this.getNodeValue(tags[0]))
|
||||||
|
|
@ -386,10 +387,12 @@ FeedParser.prototype =
|
||||||
item.id = item.url;
|
item.id = item.url;
|
||||||
item.url = this.validLink(item.url);
|
item.url = this.validLink(item.url);
|
||||||
|
|
||||||
item.author = this.getRDFTargetValue(ds, itemResource, FeedUtils.DC_CREATOR) ||
|
let author = this.getRDFTargetValue(ds, itemResource, FeedUtils.DC_CREATOR) ||
|
||||||
this.getRDFTargetValue(ds, channel, FeedUtils.DC_CREATOR) ||
|
this.getRDFTargetValue(ds, channel, FeedUtils.DC_CREATOR) ||
|
||||||
aFeed.title ||
|
aFeed.title;
|
||||||
item.author;
|
author = this.cleanAuthorName(author);
|
||||||
|
item.author = author ? ["<" + author + ">"] : item.author;
|
||||||
|
|
||||||
item.date = this.getRDFTargetValue(ds, itemResource, FeedUtils.DC_DATE) ||
|
item.date = this.getRDFTargetValue(ds, itemResource, FeedUtils.DC_DATE) ||
|
||||||
item.date;
|
item.date;
|
||||||
item.content = this.getRDFTargetValueFormatted(ds, itemResource,
|
item.content = this.getRDFTargetValueFormatted(ds, itemResource,
|
||||||
|
|
@ -608,7 +611,7 @@ FeedParser.prototype =
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Support multiple authors.
|
// Support multiple authors.
|
||||||
tags = this.childrenByTagNameNS(itemNode, FeedUtils.ATOM_IETF_NS, "source");
|
tags = this.childrenByTagNameNS(itemNode, FeedUtils.ATOM_IETF_NS, "source");
|
||||||
let source = tags ? tags[0] : null;
|
let source = tags ? tags[0] : null;
|
||||||
|
|
||||||
|
|
@ -618,22 +621,42 @@ FeedParser.prototype =
|
||||||
if (!tags)
|
if (!tags)
|
||||||
tags = this.childrenByTagNameNS(channel, FeedUtils.ATOM_IETF_NS, "author");
|
tags = this.childrenByTagNameNS(channel, FeedUtils.ATOM_IETF_NS, "author");
|
||||||
|
|
||||||
let authorEl = tags ? tags[0] : null;
|
let authorTags = tags || [];
|
||||||
|
let authors = [];
|
||||||
|
for (let authorTag of authorTags) {
|
||||||
let author = "";
|
let author = "";
|
||||||
if (authorEl)
|
tags = this.childrenByTagNameNS(authorTag, FeedUtils.ATOM_IETF_NS, "name");
|
||||||
{
|
|
||||||
tags = this.childrenByTagNameNS(authorEl, FeedUtils.ATOM_IETF_NS, "name");
|
|
||||||
let name = this.getNodeValue(tags ? tags[0] : null);
|
let name = this.getNodeValue(tags ? tags[0] : null);
|
||||||
tags = this.childrenByTagNameNS(authorEl, FeedUtils.ATOM_IETF_NS, "email");
|
tags = this.childrenByTagNameNS(authorTag, FeedUtils.ATOM_IETF_NS, "email");
|
||||||
let email = this.getNodeValue(tags ? tags[0] : null);
|
let email = this.getNodeValue(tags ? tags[0] : null);
|
||||||
if (name)
|
if (name) {
|
||||||
author = name + (email ? " <" + email + ">" : "");
|
name = this.cleanAuthorName(name);
|
||||||
else if (email)
|
if (email) {
|
||||||
|
if (!email.match(/^<.*>$/)) {
|
||||||
|
email = " <" + email + ">";
|
||||||
|
}
|
||||||
|
author = name + email;
|
||||||
|
} else {
|
||||||
|
author = "<" + name + ">";
|
||||||
|
}
|
||||||
|
} else if (email) {
|
||||||
author = email;
|
author = email;
|
||||||
}
|
}
|
||||||
|
if (author) {
|
||||||
|
authors.push(author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item.author = author || item.author || aFeed.title;
|
if (authors.length == 0) {
|
||||||
|
tags = this.childrenByTagNameNS(channel, FeedUtils.DC_NS, "publisher");
|
||||||
|
let author = this.getNodeValue(tags ? tags[0] : null) ||
|
||||||
|
aFeed.title;
|
||||||
|
author = this.cleanAuthorName(author);
|
||||||
|
item.author = author ? ["<" + author + ">"] : item.author;
|
||||||
|
} else {
|
||||||
|
item.author = authors;
|
||||||
|
}
|
||||||
|
FeedUtils.log.trace("FeedParser.parseAsAtomIETF: author(s) - " + item.author);
|
||||||
|
|
||||||
tags = this.childrenByTagNameNS(itemNode, FeedUtils.ATOM_IETF_NS, "updated");
|
tags = this.childrenByTagNameNS(itemNode, FeedUtils.ATOM_IETF_NS, "updated");
|
||||||
if (!tags || !this.getNodeValue(tags[0]))
|
if (!tags || !this.getNodeValue(tags[0]))
|
||||||
|
|
@ -801,6 +824,29 @@ FeedParser.prototype =
|
||||||
return content ? content : null;
|
return content ? content : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a cleaned up author name value.
|
||||||
|
*
|
||||||
|
* @param {String} authorString - A string.
|
||||||
|
* @returns {String} - A clean string value.
|
||||||
|
*/
|
||||||
|
cleanAuthorName(authorString) {
|
||||||
|
if (!authorString) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
FeedUtils.log.trace("FeedParser.cleanAuthor: author1 - " + authorString);
|
||||||
|
let author = authorString.replace(/[\n\r\t]+/g, " ")
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.trim();
|
||||||
|
// If the name contains special chars, quote it.
|
||||||
|
if (author.match(/[<>@,"]/)) {
|
||||||
|
author = '"' + author + '"';
|
||||||
|
}
|
||||||
|
FeedUtils.log.trace("FeedParser.cleanAuthor: author2 - " + author);
|
||||||
|
|
||||||
|
return author;
|
||||||
|
},
|
||||||
|
|
||||||
getRDFTargetValue: function(ds, source, property)
|
getRDFTargetValue: function(ds, source, property)
|
||||||
{
|
{
|
||||||
let nodeValue = this.getRDFTargetValueRaw(ds, source, property);
|
let nodeValue = this.getRDFTargetValueRaw(ds, source, property);
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,11 @@
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<window id="subscriptionsDialog"
|
<window id="subscriptionsDialog"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
flex="1"
|
flex="1"
|
||||||
title="&feedSubscriptions.label;"
|
title="&feedSubscriptions.label;"
|
||||||
windowtype="Mail:News-BlogSubscriptions"
|
windowtype="Mail:News-BlogSubscriptions"
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:nc="http://home.netscape.com/NC-rdf#"
|
|
||||||
persist="width height screenX screenY sizemode"
|
persist="width height screenX screenY sizemode"
|
||||||
onload="FeedSubscriptions.onLoad();"
|
onload="FeedSubscriptions.onLoad();"
|
||||||
onclose="return FeedSubscriptions.onClose();"
|
onclose="return FeedSubscriptions.onClose();"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue