Closed
Bug 981405
Opened 11 years ago
Closed 11 years ago
"Recent Folders" sorting has switched from case insensitive to case sensitive
Categories
(Thunderbird :: Folder and Message Lists, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
Thunderbird 31.0
People
(Reporter: 52qtuqm9, Assigned: aceman)
References
(Blocks 1 open bug)
Details
(Keywords: regression)
Attachments
(2 files, 6 obsolete files)
5.59 KB,
patch
|
aceman
:
review+
|
Details | Diff | Splinter Review |
1.32 KB,
patch
|
neil
:
review+
|
Details | Diff | Splinter Review |
In thunderbird 24.3, the "Recent Folders" view is sorted case-insensitive, which I think is what people expect in general nowadays and presumably also in particular from this view since it has been that way forever.
In 3.0.a1 (trunk) as of 2014-03-02, the sorting of that view is case-sensitive.
The sorting algorithm got a change from me in bug 845992, but we still intend to have it case insensitive (see the discussion there). I think the new algorithm is more robust in case of accented characters.
Maybe there is something wrong in your locale setting. Can you find out what is your locale (language) of Thunderbird and your Operating system? Try Tools->Error console, type "navigator.language" into the "Code" textbox and Evaluate.
Reporter | ||
Comment 2•11 years ago
|
||
navigator.language evaluates to en-US.
Reporter | ||
Comment 3•11 years ago
|
||
[ec2-user@monitor ~]$ js
js> 'Inbox'.localeCompare('archive')
-24
js>
Reporter | ||
Comment 4•11 years ago
|
||
I have LC_COLLATE set to C. I thought that might be the problem, but even when I run "env -i js" to run the JavaScript interpreter with an empty environment, it still sorts Inbox before archive as shown above.
Similarly, if I run "env -i LANG=en_US DISPLAY=:0 thunderbird" to launch Daily with a nearly empty environment, the recent folders pane still sorts case-sensitive. So I am having a hard time convincing myself that my locale settings are the issue.
Reporter | ||
Comment 5•11 years ago
|
||
Also: "env -i sort" sorts case-sensitive. "env -i LANG=en_US sort" sorts case-insensitive. So by that, "env -i LANG=en_US js" and "env -i LANG=en_US thunderbird" should both sort case-insensitive, but they don't.
Reporter | ||
Comment 6•11 years ago
|
||
Basically, localeCompare appears to be broken.
As per http://stackoverflow.com/questions/8996963/how-to-perform-case-insensitive-sorting-in-javascript , I think you need to do this when trying to do a case insensitive comparison of two strings:
a.toLowerCase().localeCompare(b.toLowerCase())
For me 'Inbox'.localeCompare('archive') returns 1 (so does 'inbox'.localeCompare('Archive')).
So according to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare there are some possible options for case sensitivity (e.g. "caseFirst"). But none look like forcing case-insensivity. Maybe we really need to force it via .toLowerCase(). This would need to be changed at more places where we use localeCompare().
Neil, what do you think?
Flags: needinfo?(neil)
Comment 8•11 years ago
|
||
(In reply to aceman from comment #7)
> Maybe we really need to force it via .toLowerCase().
It looks as if localeCompare seems to be case insensitive on all of my builds too, so I don't know what's going on here either. I wouldn't be against adding .toLocaleLowerCase() though it's a shame because I just discovered stringArray.sort(String.localeCompare). (Alternatively for sorting folders .compareSortKeys might work, although it would sort special folders first.)
Flags: needinfo?(neil)
Reporter | ||
Comment 9•11 years ago
|
||
Is anybody here besides me using Linux? Is this a Linux vs. Windows vs. Mac OS thing?
I just tested on my Linux laptop and got the same results, so that's two different (Fedora 20) Linux machines with this behavior.
As for "(Alternatively for sorting folders .compareSortKeys might work, although it would sort special folders first.)", I personally thin kthat the special folders _should_ sort first, but maybe that's just me.
Assignee | ||
Comment 10•11 years ago
|
||
No, I was developing it under Linux and it was case insensitive too. So it may depend just on the locale.
Is TB also running with the strange setting of LC_COLLATE=C ?
Assignee | ||
Comment 11•11 years ago
|
||
(In reply to Jonathan Kamens from comment #4)
> I have LC_COLLATE set to C. I thought that might be the problem, but even
> when I run "env -i js" to run the JavaScript interpreter with an empty
> environment, it still sorts Inbox before archive as shown above.
>
> Similarly, if I run "env -i LANG=en_US DISPLAY=:0 thunderbird" to launch
> Daily with a nearly empty environment, the recent folders pane still sorts
> case-sensitive. So I am having a hard time convincing myself that my locale
> settings are the issue.
Does LANG override LC_COLLATE? I don't think so. So try LC_COLLATE=en_US .
Reporter | ||
Comment 12•11 years ago
|
||
As I illustrated in my previous examples, this is not an issue of my environment variable settings:
jik2:~!635$ env -i bash --norc
bash-4.2$ set | grep '^L'
LINES=24
bash-4.2$ js
js> "Inbox".localeCompare("archive")
"Inbox".localeCompare("archive")
-24
"inbox".localeCompare("archive")
8
js>
You might think that the command-line JavaScript interpreter might differ from the one in Thunderbird, but I get the same results when I evaluate the same expressions in the error console after invoking Thunderbird from that shell with no locale environment variable settings.
Just for the heck of it, I created a completely new, vanilla user account, with no dot files or other configuration, logged in as that user, and ran the same test as above with the js interpreter, and got the same result.
Finally, I ran "LC_ALL=en_US LC_COLLATE=en_US LANG=en_US thunderbird" and evaluated the expressions above in the error console and got the same result.
I don't know why I am seeing different results from y'all. I'm frankly not sure it matters. If I'm seeing different results, then other people are going to see different results, so if the intention is for the sorting to be case-insensitive, then I think you need to explicitly make it case-insensitive in the code.
Assignee | ||
Comment 13•11 years ago
|
||
OK, so can you try this patch?
Comment 14•11 years ago
|
||
(In reply to Jonathan Kamens from comment #12)
> I don't know why I am seeing different results from y'all. I'm frankly not
> sure it matters. If I'm seeing different results, then other people are
Well it would be good to know what the difference is, and if it's a bug, get it fixed (eventually at least).
Are you using the nightly binaries from mozilla.org?
I'm on ubuntu, and it's not a problem for me either.
Assignee | ||
Comment 15•11 years ago
|
||
Yes, I would also like to know what is wrong here. If it is a problem in localeCompare or something. We can add the .toLocaleLowercase() as in the patch, but it may be wasted CPU cycles.
But as I said, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare does not seem to guarantee case insensitiveness. The default "sensitivity" is "variant" for usage "sort" (but we do not yet request "usage: sort").
Jonathan, can you try:
"Inbox".localeCompare("archive", "", {usage:"sort", sensitivity: "accent"})
"Inbox".localeCompare("archive", "C", {usage:"sort", sensitivity: "accent"})
"Inbox".localeCompare("archive", "en-US", {usage:"sort", sensitivity: "accent"})
Reporter | ||
Comment 16•11 years ago
|
||
(In reply to :aceman from comment #13)
> OK, so can you try this patch?
Patch works, thank you.
(In reply to Magnus Melin from comment #14)
> Well it would be good to know what the difference is, and if it's a bug, get
> it fixed (eventually at least).
I don't disagree that it would be useful to understand why it's behaving differently for me than it is for others. But given that whether or not a locale sorts case-insensitively by default is defined by the locale, if indeed the desired behavior in Thunderbird is for the list to always be sorted insensitively regardless of the locale setting, then that's how it should be coded, independent of figuring out the anomaly we're discussing here..
> Are you using the nightly binaries from mozilla.org?
> I'm on ubuntu, and it's not a problem for me either.
I was using a build I did myself, but I went ahead and downloaded and tested a nightly build yesterday and it has the same problem.
(In reply to :aceman from comment #15)
> Jonathan, can you try:
> "Inbox".localeCompare("archive", "", {usage:"sort", sensitivity: "accent"})
> "Inbox".localeCompare("archive", "C", {usage:"sort", sensitivity: "accent"})
> "Inbox".localeCompare("archive", "en-US", {usage:"sort", sensitivity:
> "accent"})
All of these return -24 when I evaluate them in the error console.
Assignee | ||
Comment 17•11 years ago
|
||
(In reply to Jonathan Kamens from comment #16)
> I don't disagree that it would be useful to understand why it's behaving
> differently for me than it is for others. But given that whether or not a
> locale sorts case-insensitively by default is defined by the locale, if
> indeed the desired behavior in Thunderbird is for the list to always be
> sorted insensitively regardless of the locale setting, then that's how it
> should be coded, independent of figuring out the anomaly we're discussing
> here..
>
> (In reply to :aceman from comment #15)
> > Jonathan, can you try:
> > "Inbox".localeCompare("archive", "", {usage:"sort", sensitivity: "accent"})
> > "Inbox".localeCompare("archive", "C", {usage:"sort", sensitivity: "accent"})
> > "Inbox".localeCompare("archive", "en-US", {usage:"sort", sensitivity:
> > "accent"})
>
> All of these return -24 when I evaluate them in the error console.
But if I read the docs page correctly, we should be using ["Inbox".localeCompare("archive", "", {usage:"sort", sensitivity: "accent"})] instead of forcing .toLocaleLowerCase, but it is still not working for you.
The page says the options arguments are there since Gecko 29 so maybe they are not polished yet.
Neil, do you know who the right people are to look at this? Maybe some more extensive tests should be added to http://mxr.mozilla.org/comm-central/source/mozilla/js/src/jit-test/tests/basic/testLocaleCompare.js .
Flags: needinfo?(neil)
Comment 18•11 years ago
|
||
Adding Norbert from bug 769871. Any ideas, or is it just a bug?
Flags: needinfo?(mozillabugs)
Assignee | ||
Comment 19•11 years ago
|
||
Looking at bug 853301, do we actually have this properly enabled in TB?
Comment 20•11 years ago
|
||
Adding Jeff Walden, the current owner of the ECMAScript Internationalization API in Mozilla. He's more familiar with the current state of the build options for this API than I.
Comment 16 tells me that this functionality is not enabled in the builds you're using: If localeCompare followed the specification for the ECMAScript Internationalization API, it would throw exceptions for the language tags "" and "C" because they're not valid BCP 47 language tags ("en-US" is valid). This means you're using an older implementation.
Also, please check what the file systems you work with do for case-insensitive comparison before relying on localeCompare or localeToUpperCase. I'm not sure whether file systems track locales and, for example, treat i and İ as equivalent, and i and I as different, in Turkish.
Flags: needinfo?(mozillabugs)
Assignee | ||
Comment 21•11 years ago
|
||
(In reply to Norbert Lindenberg from comment #20)
> Comment 16 tells me that this functionality is not enabled in the builds
> you're using: If localeCompare followed the specification for the ECMAScript
> Internationalization API, it would throw exceptions for the language tags ""
> and "C" because they're not valid BCP 47 language tags ("en-US" is valid).
> This means you're using an older implementation.
How should we skip the second argument (meaning use the current app locale). The docs page says to leave it "undefined".
> Also, please check what the file systems you work with do for
> case-insensitive comparison before relying on localeCompare or
> localeToUpperCase. I'm not sure whether file systems track locales and, for
> example, treat i and İ as equivalent, and i and I as different, in Turkish.
Why? The function should be filesystem independent and observe the spec (ICU or something). What would be the point of it depending on the filesystem?
Comment 22•11 years ago
|
||
(In reply to :aceman from comment #21)
> How should we skip the second argument (meaning use the current app locale).
> The docs page says to leave it "undefined".
Depends on what you mean by "app": If you mean the locale of the JavaScript app, it would have to know that by its BCP 47 language tag and pass it in. If you mean the containing app (Thunderbird), pass in undefined, and make sure that the default locale for the ECMAScript Internationalization API is determined by the locale of the containing app (as it is in Firefox).
> > Also, please check what the file systems you work with do for
> > case-insensitive comparison before relying on localeCompare or
> > localeToUpperCase. I'm not sure whether file systems track locales and, for
> > example, treat i and İ as equivalent, and i and I as different, in Turkish.
> Why? The function should be filesystem independent and observe the spec (ICU
> or something). What would be the point of it depending on the filesystem?
I had the impression that you want to achieve behavior that's compatible with that of the file system. If that's not the case, then please ignore my comment. But then the entire discussion of case sensitive vs. case insensitive seems irrelevant - a reasonable locale sensitive sort order will always sort strings next to each other if they only differ in case, and for the user interface that's all that matters.
Reporter | ||
Updated•11 years ago
|
Attachment #8392391 -
Flags: feedback?(jik) → feedback+
Assignee | ||
Comment 23•11 years ago
|
||
(In reply to Norbert Lindenberg from comment #22)
> (In reply to :aceman from comment #21)
>
> > How should we skip the second argument (meaning use the current app locale).
> > The docs page says to leave it "undefined".
>
> Depends on what you mean by "app": If you mean the locale of the JavaScript
> app, it would have to know that by its BCP 47 language tag and pass it in.
> If you mean the containing app (Thunderbird), pass in undefined, and make
> sure that the default locale for the ECMAScript Internationalization API is
> determined by the locale of the containing app (as it is in Firefox).
>
> > > Also, please check what the file systems you work with do for
> > > case-insensitive comparison before relying on localeCompare or
> > > localeToUpperCase. I'm not sure whether file systems track locales and, for
> > > example, treat i and İ as equivalent, and i and I as different, in Turkish.
> > Why? The function should be filesystem independent and observe the spec (ICU
> > or something). What would be the point of it depending on the filesystem?
>
> I had the impression that you want to achieve behavior that's compatible
> with that of the file system. If that's not the case, then please ignore my
> comment. But then the entire discussion of case sensitive vs. case
> insensitive seems irrelevant - a reasonable locale sensitive sort order will
> always sort strings next to each other if they only differ in case, and for
> the user interface that's all that matters.
We want locale sensitive sort order that ignores case (if that is appropriate for the locale).
And we are trying to determine whether the reporter's locale is somehow "unreasonable" or whether .localeCompare actually works correctly. It now looks like we may not have the correct locale support compiled in TB yet for .localeCompare to work according to http://mxr.mozilla.org/comm-central/source/mozilla/js/src/jit-test/tests/basic/testLocaleCompare.js.
Does bug 853301 contain the changes that we need to apply to TB to use the new API? Is Firefox already using the new API?
Assignee | ||
Comment 24•11 years ago
|
||
OK, I'll consolidate the sorting into a function so we can switch it all later when we find out how we can make use of the new .localeCompare features.
Attachment #8392391 -
Attachment is obsolete: true
Attachment #8398137 -
Flags: review?(neil)
Attachment #8398137 -
Flags: review?(mkmelin+mozilla)
Flags: needinfo?(neil)
Comment 25•11 years ago
|
||
Comment on attachment 8398137 [details] [diff] [review]
patch v2
> let sortKey = a._folder.compareSortKeys(b._folder);
> if (sortKey)
> return sortKey;
>- return a.text.localeCompare(b.text);
>+ return localeCompare(a.text, b.text);
...
> return a.compareSortKeys(b) ||
>- a.prettyName.localeCompare(b.prettyName);
>+ this.localeCompare(a.prettyName, b.prettyName);
compareSortKeys already compares both the special folder type and the name (case-insensitively, to boot). So we shouldn't be attempting a secondary sort...
> recentFolders.sort(function sort_folders_by_name(a, b) {
>- return a.label.localeCompare(b.label);
>+ return this.localeCompare(a.label, b.label);
"this" isn't what you think it is...
Attachment #8398137 -
Flags: review?(neil) → review-
Assignee | ||
Comment 26•11 years ago
|
||
(In reply to neil@parkwaycc.co.uk from comment #25)
> > return a.compareSortKeys(b) ||
> >- a.prettyName.localeCompare(b.prettyName);
> >+ this.localeCompare(a.prettyName, b.prettyName);
> compareSortKeys already compares both the special folder type and the name
> (case-insensitively, to boot). So we shouldn't be attempting a secondary
> sort...
So why is the secondary sort there? Maybe there are account types where comparesortkey is unimplemented? Or should I just remove it?
Comment 27•11 years ago
|
||
I would just remove it.
Assignee | ||
Comment 28•11 years ago
|
||
The 'this' inside of .sort() seems to work for me (it fetches the right function localeCompare) so I left it in.
Attachment #8398137 -
Attachment is obsolete: true
Attachment #8398137 -
Flags: review?(mkmelin+mozilla)
Attachment #8398762 -
Flags: review?(neil)
Attachment #8398762 -
Flags: review?(mkmelin+mozilla)
Comment 29•11 years ago
|
||
Comment on attachment 8398762 [details] [diff] [review]
patch v3
Review of attachment 8398762 [details] [diff] [review]:
-----------------------------------------------------------------
::: mailnews/base/util/folderUtils.jsm
@@ +225,5 @@
> + *
> + * @param aString1 first string to compare
> + * @param aString2 second string to compare
> + */
> +function localeCompare(aString1, aString2) {
Could we name it something that doesn't collide with an existing name, like folderCompare?
@@ +228,5 @@
> + */
> +function localeCompare(aString1, aString2) {
> + // Ultimately we want to use something like this:
> + // aString1.localeCompare(aString2, undefined, {usage:"sort", sensitivity: "accent"})
> + // but for that TB needs to switch to the new internationalization API, see bug 981405.
It's unclear to me if we needed to do some kind of switchover. If we need some change, file a bug and reference that.
Comment 30•11 years ago
|
||
Comment on attachment 8398762 [details] [diff] [review]
patch v3
Review of attachment 8398762 [details] [diff] [review]:
-----------------------------------------------------------------
Other than that, r=mkmelin I suppose. Seems to do what it should.
Attachment #8398762 -
Flags: review?(mkmelin+mozilla) → review+
Assignee | ||
Comment 31•11 years ago
|
||
Did you mean this?
Attachment #8398762 -
Attachment is obsolete: true
Attachment #8398762 -
Flags: review?(neil)
Attachment #8402342 -
Flags: review?(neil)
Attachment #8402342 -
Flags: review?(mkmelin+mozilla)
Comment 32•11 years ago
|
||
Comment on attachment 8402342 [details] [diff] [review]
patch v4
Review of attachment 8402342 [details] [diff] [review]:
-----------------------------------------------------------------
Yes, though re bug 992651 I'm still confused about why we'd need a config change, or rather if we do, how come not everyone of us need one?
Attachment #8402342 -
Flags: review?(mkmelin+mozilla) → review+
Assignee | ||
Comment 33•11 years ago
|
||
Actually the patch here works around the problem that we don't know why somebody needs the toLowerCase forced. Maybe it is because .localeCompare doesn't work 100% correctly, because TB does not yet use all the new functionality (the new API). Once that is done, we can do bug 992651 and .localeCompare should do everything needed automatically for us.
Comment 34•11 years ago
|
||
Comment on attachment 8402342 [details] [diff] [review]
patch v4
>- var aLabel = a.prettyName;
>- var bLabel = b.prettyName;
>+ let aLabel = a.prettyName;
>+ let bLabel = b.prettyName;
Bah, I wondered what the noise was.
>+ return a.compareSortKeys(b)
Nit: missing ;
Attachment #8402342 -
Flags: review?(neil) → review+
Assignee | ||
Comment 35•11 years ago
|
||
Thanks.
Attachment #8402342 -
Attachment is obsolete: true
Attachment #8402934 -
Flags: review+
Keywords: checkin-needed
Comment 36•11 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
Target Milestone: --- → Thunderbird 31.0
Assignee | ||
Comment 37•11 years ago
|
||
(In reply to neil@parkwaycc.co.uk from comment #25)
> > recentFolders.sort(function sort_folders_by_name(a, b) {
> >- return a.label.localeCompare(b.label);
> >+ return this.localeCompare(a.label, b.label);
> "this" isn't what you think it is...
Maybe you were right. The function works fine when I tried Recent menu in the message list (context menu -> Move to). But it breaks the filter editor (move/copy to actions)...
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Attachment #8402934 -
Attachment description: patch v4.1 → patch v4.1 [checked in in comment 36]
Assignee | ||
Comment 38•11 years ago
|
||
Attachment #8405582 -
Flags: review?(neil)
Comment 39•11 years ago
|
||
Why not use .bind()?
Assignee | ||
Comment 40•11 years ago
|
||
OK, like this?
Attachment #8405582 -
Attachment is obsolete: true
Attachment #8405582 -
Flags: review?(neil)
Attachment #8405662 -
Flags: review?(neil)
Assignee | ||
Comment 41•11 years ago
|
||
Or if you'd like it fancier :)
Attachment #8405689 -
Flags: review?(neil)
Updated•11 years ago
|
Attachment #8405662 -
Flags: review?(neil) → review+
Assignee | ||
Comment 42•11 years ago
|
||
Neil, can you please r- the other patch and comment why the chosen one is better?
Flags: needinfo?(neil)
Comment 43•11 years ago
|
||
Comment on attachment 8405689 [details] [diff] [review]
patch for wrong 'this' v3
I'm not used to their semantics yet, that's all. (Admittedly I didn't try very hard to find out definitively what they are anyway.)
Attachment #8405689 -
Flags: review?(neil)
Flags: needinfo?(neil)
Comment 44•11 years ago
|
||
Comment on attachment 8405689 [details] [diff] [review]
patch for wrong 'this' v3
Actually they used to do the equivalent of .bind() but that doesn't get optimised by whatever JIT we're using these days. However they've very recently been given special treatment so you should now prefer them to .bind().
Attachment #8405689 -
Flags: review+
Assignee | ||
Comment 45•11 years ago
|
||
Keywords: checkin-needed
Attachment #8405662 -
Attachment is obsolete: true
Comment 46•11 years ago
|
||
Status: REOPENED → RESOLVED
Closed: 11 years ago → 11 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•