Bug 583677 - Fix so custom tags (keywords) are visble to all users. r=jorgk
See Bug 583677 comment 85 for basic description of the fix.
This commit is contained in:
Родитель
6bf07a5bdf
Коммит
b81da8a541
|
@ -70,5 +70,7 @@ interface nsIImapFlagAndUidState : nsISupports
|
|||
*/
|
||||
ACString getCustomAttribute(in unsigned long aUid,
|
||||
in ACString aCustomAttributeName);
|
||||
void setOtherKeywords(in unsigned short index, in AUTF8String otherKeyword);
|
||||
AUTF8String getOtherKeywords(in unsigned short index);
|
||||
};
|
||||
|
||||
|
|
|
@ -110,6 +110,27 @@ nsImapFlagAndUidState::GetSupportedUserFlags(uint16_t *aFlags)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapFlagAndUidState::SetOtherKeywords(uint16_t index, const nsACString &otherKeyword)
|
||||
{
|
||||
if (index == 0)
|
||||
fOtherKeywords.Clear();
|
||||
nsAutoCString flag(otherKeyword);
|
||||
ToLowerCase(flag);
|
||||
fOtherKeywords.AppendElement(flag);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapFlagAndUidState::GetOtherKeywords(uint16_t index, nsACString &aKeyword)
|
||||
{
|
||||
if (index < fOtherKeywords.Length())
|
||||
aKeyword = fOtherKeywords[index];
|
||||
else
|
||||
aKeyword = EmptyCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// we need to reset our flags, (re-read all) but chances are the memory allocation needed will be
|
||||
// very close to what we were already using
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ private:
|
|||
bool fPartialUIDFetch;
|
||||
uint32_t fNumAdded;
|
||||
bool fStartCapture;
|
||||
// Keywords (aka, tags) in FLAGS response to SELECT defined by other clients
|
||||
nsTArray<nsCString> fOtherKeywords;
|
||||
mozilla::Mutex mLock;
|
||||
};
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID);
|
|||
extern mozilla::LazyLogModule gAutoSyncLog; // defined in nsAutoSyncManager.cpp
|
||||
extern mozilla::LazyLogModule IMAP; // defined in nsImapProtocol.cpp
|
||||
extern mozilla::LazyLogModule IMAP_CS; // For CONDSTORE, defined in nsImapProtocol.cpp
|
||||
mozilla::LazyLogModule IMAP_KW("IMAP_KW"); // for logging keyword (tag) processing
|
||||
|
||||
#define MAILNEWS_CUSTOM_HEADERS "mailnews.customHeaders"
|
||||
|
||||
|
@ -4440,7 +4441,7 @@ void nsImapMailFolder::TweakHeaderFlags(nsIImapProtocol* aProtocol, nsIMsgDBHdr
|
|||
if (newFlags)
|
||||
tweakMe->OrFlags(newFlags, &dbHdrFlags);
|
||||
if (!customFlags.IsEmpty())
|
||||
(void) HandleCustomFlags(m_curMsgUid, tweakMe, userFlags, customFlags);
|
||||
(void) HandleCustomFlags(m_curMsgUid, tweakMe, userFlags, customFlags, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4751,7 +4752,8 @@ nsImapMailFolder::BeginMessageUpload()
|
|||
nsresult nsImapMailFolder::HandleCustomFlags(nsMsgKey uidOfMessage,
|
||||
nsIMsgDBHdr *dbHdr,
|
||||
uint16_t userFlags,
|
||||
nsCString &keywords)
|
||||
nsCString &keywords,
|
||||
nsIImapFlagAndUidState *flagState)
|
||||
{
|
||||
nsresult rv = GetDatabase();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -4785,6 +4787,71 @@ nsresult nsImapMailFolder::HandleCustomFlags(nsMsgKey uidOfMessage,
|
|||
if (existingProperty.IsEmpty())
|
||||
dbHdr->SetStringProperty("junkscoreorigin", "imapflag");
|
||||
}
|
||||
|
||||
if (flagState && !(userFlags & kImapMsgSupportUserFlag))
|
||||
{
|
||||
nsCString localKeywords;
|
||||
if (!(userFlags & kImapMsgSupportUserFlag))
|
||||
{
|
||||
dbHdr->GetStringProperty("keywords", getter_Copies(localKeywords));
|
||||
MOZ_LOG(IMAP_KW, mozilla::LogLevel::Debug, ("UID=%" PRIu32 ", localKeywords=|%s| rcvdKeyword=|%s|",
|
||||
uidOfMessage, localKeywords.get(), keywords.get()));
|
||||
}
|
||||
nsTArray<nsCString> localKeywordArray;
|
||||
nsTArray<nsCString> rcvdKeywordArray;
|
||||
ParseString(localKeywords, ' ', localKeywordArray);
|
||||
ParseString(keywords, ' ', rcvdKeywordArray);
|
||||
|
||||
nsAutoCString mozLogDefinedKWs;
|
||||
if (MOZ_LOG_TEST(IMAP_KW, mozilla::LogLevel::Debug))
|
||||
mozLogDefinedKWs.AppendLiteral("Defined keywords = |");
|
||||
uint32_t i = 0;
|
||||
while (true)
|
||||
{
|
||||
nsAutoCString definedKeyword;
|
||||
flagState->GetOtherKeywords(i++, definedKeyword);
|
||||
if (definedKeyword.IsEmpty())
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAP_KW, mozilla::LogLevel::Debug))
|
||||
{
|
||||
mozLogDefinedKWs.Append('|');
|
||||
MOZ_LOG(IMAP_KW, mozilla::LogLevel::Debug, ("%s", mozLogDefinedKWs.get()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (MOZ_LOG_TEST(IMAP_KW, mozilla::LogLevel::Debug))
|
||||
{
|
||||
mozLogDefinedKWs.Append(definedKeyword.get());
|
||||
mozLogDefinedKWs.Append(' ');
|
||||
}
|
||||
|
||||
bool inLocal = localKeywordArray.Contains(definedKeyword);
|
||||
bool inRcvd = rcvdKeywordArray.Contains(definedKeyword);
|
||||
if (inLocal && inRcvd)
|
||||
rcvdKeywordArray.RemoveElement(definedKeyword);
|
||||
if (inLocal && !inRcvd)
|
||||
localKeywordArray.RemoveElement(definedKeyword);
|
||||
}
|
||||
// Combine local and rcvd keyword arrays into a single string
|
||||
// so it can be passed to SetStringProperty(). If element of
|
||||
// local already in rcvd, avoid duplicates in combined string.
|
||||
nsAutoCString combinedKeywords;
|
||||
for (i = 0; i < localKeywordArray.Length(); i++)
|
||||
{
|
||||
if (!rcvdKeywordArray.Contains(localKeywordArray[i]))
|
||||
{
|
||||
combinedKeywords.Append(localKeywordArray[i]);
|
||||
combinedKeywords.Append(' ');
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rcvdKeywordArray.Length(); i++)
|
||||
{
|
||||
combinedKeywords.Append(rcvdKeywordArray[i]);
|
||||
combinedKeywords.Append(' ');
|
||||
}
|
||||
return dbHdr->SetStringProperty("keywords", combinedKeywords.get());
|
||||
}
|
||||
return (userFlags & kImapMsgSupportUserFlag) ?
|
||||
dbHdr->SetStringProperty("keywords", keywords.get()) : NS_OK;
|
||||
}
|
||||
|
@ -4830,7 +4897,7 @@ nsresult nsImapMailFolder::SyncFlags(nsIImapFlagAndUidState *flagState)
|
|||
|
||||
nsCString keywords;
|
||||
if (NS_SUCCEEDED(flagState->GetCustomFlags(uidOfMessage, getter_Copies(keywords))))
|
||||
HandleCustomFlags(uidOfMessage, dbHdr, supportedUserFlags, keywords);
|
||||
HandleCustomFlags(uidOfMessage, dbHdr, supportedUserFlags, keywords, flagState);
|
||||
|
||||
NotifyMessageFlagsFromHdr(dbHdr, uidOfMessage, flags);
|
||||
}
|
||||
|
@ -4935,7 +5002,7 @@ nsImapMailFolder::NotifyMessageFlags(uint32_t aFlags,
|
|||
GetSupportedUserFlags(&supportedUserFlags);
|
||||
NotifyMessageFlagsFromHdr(dbHdr, aMsgKey, aFlags);
|
||||
nsCString keywords(aKeywords);
|
||||
HandleCustomFlags(aMsgKey, dbHdr, supportedUserFlags, keywords);
|
||||
HandleCustomFlags(aMsgKey, dbHdr, supportedUserFlags, keywords, nullptr);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -354,7 +354,8 @@ protected:
|
|||
|
||||
nsresult SyncFlags(nsIImapFlagAndUidState *flagState);
|
||||
nsresult HandleCustomFlags(nsMsgKey uidOfMessage, nsIMsgDBHdr *dbHdr,
|
||||
uint16_t userFlags, nsCString& keywords);
|
||||
uint16_t userFlags, nsCString& keywords,
|
||||
nsIImapFlagAndUidState *flagState);
|
||||
nsresult NotifyMessageFlagsFromHdr(nsIMsgDBHdr *dbHdr, nsMsgKey msgKey,
|
||||
uint32_t flags);
|
||||
|
||||
|
|
|
@ -782,7 +782,7 @@ void nsImapServerResponseParser::mailbox_data()
|
|||
if (fGotPermanentFlags)
|
||||
skip_to_CRLF();
|
||||
else
|
||||
parse_folder_flags();
|
||||
parse_folder_flags(true);
|
||||
}
|
||||
else if (!PL_strcasecmp(fNextToken, "LIST") ||
|
||||
!PL_strcasecmp(fNextToken, "XLIST"))
|
||||
|
@ -1850,20 +1850,19 @@ void nsImapServerResponseParser::text()
|
|||
skip_to_CRLF();
|
||||
}
|
||||
|
||||
void nsImapServerResponseParser::parse_folder_flags()
|
||||
void nsImapServerResponseParser::parse_folder_flags(bool calledForFlags)
|
||||
{
|
||||
uint16_t labelFlags = 0;
|
||||
bool storeUserFlags = !(fSupportsUserDefinedFlags & kImapMsgSupportUserFlag) &&
|
||||
calledForFlags && fFlagState;
|
||||
uint16_t numOtherKeywords = 0;
|
||||
|
||||
do
|
||||
{
|
||||
AdvanceToNextToken();
|
||||
if (*fNextToken == '(')
|
||||
fNextToken++;
|
||||
if (!PL_strncasecmp(fNextToken, "$MDNSent", 8))
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportMDNSentFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Forwarded", 10))
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportForwardedFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "\\Seen", 5))
|
||||
if (!PL_strncasecmp(fNextToken, "\\Seen", 5))
|
||||
fSettablePermanentFlags |= kImapMsgSeenFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "\\Answered", 9))
|
||||
fSettablePermanentFlags |= kImapMsgAnsweredFlag;
|
||||
|
@ -1873,23 +1872,52 @@ void nsImapServerResponseParser::parse_folder_flags()
|
|||
fSettablePermanentFlags |= kImapMsgDeletedFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "\\Draft", 6))
|
||||
fSettablePermanentFlags |= kImapMsgDraftFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label1", 7))
|
||||
labelFlags |= 1;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label2", 7))
|
||||
labelFlags |= 2;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label3", 7))
|
||||
labelFlags |= 4;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label4", 7))
|
||||
labelFlags |= 8;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label5", 7))
|
||||
labelFlags |= 16;
|
||||
else if (!PL_strncasecmp(fNextToken, "\\*", 2))
|
||||
{
|
||||
// User defined and special keywords (tags) can be defined and set for
|
||||
// mailbox. Should only occur in PERMANENTFLAGS response.
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportUserFlag;
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportForwardedFlag;
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportMDNSentFlag;
|
||||
fSupportsUserDefinedFlags |= kImapMsgLabelFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Treat special and built-in $LabelX's as user defined if a
|
||||
// save occurs below.
|
||||
if (!PL_strncasecmp(fNextToken, "$MDNSent", 8))
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportMDNSentFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Forwarded", 10))
|
||||
fSupportsUserDefinedFlags |= kImapMsgSupportForwardedFlag;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label1", 7))
|
||||
labelFlags |= 1;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label2", 7))
|
||||
labelFlags |= 2;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label3", 7))
|
||||
labelFlags |= 4;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label4", 7))
|
||||
labelFlags |= 8;
|
||||
else if (!PL_strncasecmp(fNextToken, "$Label5", 7))
|
||||
labelFlags |= 16;
|
||||
|
||||
// Save user keywords defined for mailbox, usually by other clients.
|
||||
// But only do this for FLAGS response, not PERMANENTFLAGS response
|
||||
// and if '\*' has not appeared in a PERMANENTFLAGS response.
|
||||
if (storeUserFlags && *fNextToken != '\r')
|
||||
{
|
||||
if (*(fNextToken + strlen(fNextToken) - 1) != ')')
|
||||
{
|
||||
// Token doesn't end in ')' so save it as is.
|
||||
fFlagState->SetOtherKeywords(numOtherKeywords++, nsDependentCString(fNextToken));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Token ends in ')' so end of list. Change ')' to null and save.
|
||||
fFlagState->SetOtherKeywords(numOtherKeywords++,
|
||||
nsDependentCSubstring(fNextToken, strlen(fNextToken) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!fAtEndOfLine && ContinueParse());
|
||||
|
||||
if (labelFlags == 31)
|
||||
|
@ -1947,7 +1975,7 @@ void nsImapServerResponseParser::resp_text_code()
|
|||
uint32_t saveSettableFlags = fSettablePermanentFlags;
|
||||
fSupportsUserDefinedFlags = 0; // assume no unless told
|
||||
fSettablePermanentFlags = 0; // assume none, unless told otherwise.
|
||||
parse_folder_flags();
|
||||
parse_folder_flags(false);
|
||||
// if the server tells us there are no permanent flags, we're
|
||||
// just going to pretend that the FLAGS response flags, if any, are
|
||||
// permanent in case the server is broken. This will allow us
|
||||
|
|
|
@ -137,7 +137,7 @@ protected:
|
|||
virtual void resp_cond_state(bool isTagged);
|
||||
virtual void text_mime2();
|
||||
virtual void text();
|
||||
virtual void parse_folder_flags();
|
||||
virtual void parse_folder_flags(bool calledForFlags);
|
||||
virtual void enable_data();
|
||||
virtual void language_data();
|
||||
virtual void authChallengeResponse_data();
|
||||
|
|
Загрузка…
Ссылка в новой задаче