Closed Bug 564934 (DownloadsPanel) Opened 14 years ago Closed 11 years ago

Implement new Download Manager UI for browser

Categories

(Firefox :: Downloads Panel, defect)

defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME
Tracking Status
firefox14 --- disabled
firefox15 --- disabled
blocking2.0 --- -

People

(Reporter: sdwilsh, Assigned: Paolo)

References

(Depends on 1 open bug, Blocks 2 open bugs, )

Details

(Keywords: meta, Whiteboard: [=== See the STATUS PAGE before posting - linked in the bug's URL field ===])

Attachments

(10 files, 37 obsolete files)

311.68 KB, image/png
Details
366.65 KB, image/png
Details
411.26 KB, image/png
Details
80.50 KB, image/png
Details
953.70 KB, image/jpeg
Details
59.14 KB, image/png
Details
22.06 KB, image/png
Details
1.32 MB, image/png
Details
291.33 KB, image/png
Details
36.56 KB, image/png
Details
Implement the panel UI instead of the window pop-up we currently have in the browser.  This involves overriding the toolkit nsIDownloadManagerUI component (implemented in nsDownloadManagerUI.js) and having it show a custom UI.  Might want to see how Fennec does this (http://mxr.mozilla.org/mobile-browser/source/components/DownloadManagerUI.js) as Firefox will need to do something similar.
Mehdi is going to be working on other stuff, so if someone else wants to take this, feel free to do so!
Assignee: mmulani → nobody
Status: ASSIGNED → NEW
I attached javascript to the ticket for some canvas animations that seem to match what Limi was talking about for a new UI.  It draws a badge with number of current downloads in the center and the badge itself working as a round progress bar for total % downloaded.  It then pulses twice when all downloads are complete.  View a demo here: http://dl.dropbox.com/u/1357257/canvas_test.html
OK.  I have a working addon that more or less implements the Limi UI.  There's a badge that's a circular progress bar of overall download percentage (all current downloading files.)  There's a number in the center for how many downloads are taking place.  

Hovering the mouse over the badge shows a simple progress bar and ETA for each downloading file.  Clicking on the badge brings up the full downloads window.

When a single download completes, the percentage and number of active downloads updates appropriately.  When the last download stops, the badge blinks twice if it was a successful download.  It just disappears immediately for failure or a pause/cancel by the user.  

If any of the downloads don't inform the browser of the file size before downloading, there's a different animation.  Three triangles spin around the circle, rather than a growing progress bar.  I'm having trouble finding a file server to test this with, though.
Attached image screenshot (obsolete) —
Attachment #457660 - Attachment is obsolete: true
Fixed some layout problems in MS Windows
Attachment #459299 - Attachment is obsolete: true
OK... last update for the night... more layout fixes.
Attachment #459303 - Attachment is obsolete: true
Nobody is planning on working on this Jason, so do you want to try and create the patch and get it landed for Firefox 4?  Awesome work so far!
Attached image What I see. (obsolete) —
(In reply to comment #8)
> Created attachment 459304 [details]
> Addon implementation of download badge UI
> 
> OK... last update for the night... more layout fixes.

All of the navigation bar's buttons are suddenly really tall with this add-on enabled for me in Windows 7 on Firefox 4 nightlies.
I haven't checked to see if it's a conflict with some other extension yet, but I thought I'd report this now before I forget it overnight.
@Shawn, making this into a patch might not be too hard, but there's some bugs I don't know how to fix that are mainly related to what I used as a container for the xul code.

A XUL panel contains a row with the status of each download.  The only way I could get the panel to work was to put all the xul objects inside a button with type "panel."   There's some problems with that.  

First of all, it makes the ugly box you see.  There's no reason for that box... the badge itself could just hang out in the menubar if I could get rid of the button.  It might also fix the ugliness that Wes is seeing, because the button is larger than the canvas inside it.  

Also, the "click to bring up downloads window" code breaks in Firefox 4 (it requires a click for the button or window to get focus, then a second click to bring up the downloads window)... it's probably related to using a button and making it activate on hover, rather than click, and something stealing focus when the panel is showing.  Does anyone here have enough XUL experience to suggest an alternative to a button with type "panel" that triggers a XUL panel?

A second problem:  I'm not sure where to get internationalized strings for download time remaining.  Can anyone point me in the right direction?  I might be able to figure this one out on my own.

I _think_ I can figure out how to make this a patch instead of an addon, but I'll need the help I described above.
Oh, and can anyone point me to a page where I can download something and the server doesn't report to me the file size at download time? (so the browser knows how many bytes of the file it has, but not percentage completed)
I found the international strings.  I would argue that some new ones are needed.  There's no string for  "Click badge for Downloads window" and nothing anywhere near like that string... not even "Downloads window" as a phrase.

It would be nice to have abbreviated strings for hours and minutes in each language.  

The current code would require the strings for "about a minute" or "less than a minute" (though I admit I could change the code.)
(In reply to comment #11)
> @Shawn, making this into a patch might not be too hard, but there's some bugs I
> don't know how to fix that are mainly related to what I used as a container for
> the xul code.
> 
> A XUL panel contains a row with the status of each download.  The only way I
> could get the panel to work was to put all the xul objects inside a button with
> type "panel."   There's some problems with that.
Neil is the one you want to ask xul:panel questions too.
  
(In reply to comment #12)
> Oh, and can anyone point me to a page where I can download something and the
> server doesn't report to me the file size at download time? (so the browser
> knows how many bytes of the file it has, but not percentage completed)
Most linux ISOs seem to do this in my experience.  Bonus is that it is long running.  If you make a patch, I think we have tests that you can copy to get the desired look as well.

(In reply to comment #13)
> I found the international strings.  I would argue that some new ones are
> needed.  There's no string for  "Click badge for Downloads window" and nothing
> anywhere near like that string... not even "Downloads window" as a phrase.
That's fine.  Strings are easy to add.

> It would be nice to have abbreviated strings for hours and minutes in each
> language.
hmm, do they need to be abbreviated?

> The current code would require the strings for "about a minute" or "less than a
> minute" (though I admit I could change the code.)
We already have code that handles that for us.  See http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/DownloadUtils.jsm
> > It would be nice to have abbreviated strings for hours and minutes in each
> > language.
> hmm, do they need to be abbreviated?

Abbreviations aren't strictly necessary, but making the panel smaller than the full downloads window seems logical to me, and the only ways I can think to do that are shorter ETA strings and abbreviating the download filename with an ellipsis (I haven't coded the ellipsis, but I was planning to.)  Would you rather a bigger panel, but full filename and no abbreviations in the ETA strings?  Also... on your comment later about already having code for "time remaining" strings... same arguments... I can reuse that code or create something new with more compact ETA strings.

> Most linux ISOs seem to do this in my experience. 

Thanks for the tip.

> Neil is the one you want to ask xul:panel questions to

How do I contact Neil, or is he Cc'ed on this bug?
(In reply to comment #15)
> Abbreviations aren't strictly necessary, but making the panel smaller than the
> full downloads window seems logical to me, and the only ways I can think to do
> that are shorter ETA strings and abbreviating the download filename with an
> ellipsis (I haven't coded the ellipsis, but I was planning to.)  Would you
> rather a bigger panel, but full filename and no abbreviations in the ETA
> strings?  Also... on your comment later about already having code for "time
> remaining" strings... same arguments... I can reuse that code or create
> something new with more compact ETA strings.
I would suspect that we wouldn't want to abbreviate things, but we should get input from UX.

> How do I contact Neil, or is he Cc'ed on this bug?
I cc'd him to the bug.
One other thought.  Instead of ellipsis, we could let a long filename wrap to a second line
No longer displaying badge inside a button... this should fix the Windows 7/Ffx-4 visual glitches, fixes the problems with displaying panel on hover, and fixes problems clicking on the badge to get the downloads window in Ffx-4.

This version creates shorter ETA strings than the Firefox downloads window, but does so using il8n strings already contained in Firefox.

Other misc. formatting cleanup.

The string "Click badge to see Download Window" is still hard-coded.

At this point, it should be code-complete to be converted from an addon to a patch
Attachment #459304 - Attachment is obsolete: true
Attachment #459477 - Attachment is obsolete: true
My mistake... problem with having to double-click on the badge in ffx4 persists.  Not sure why.
Neil, can you offer suggestions?  

In firefox 4, after show panel is run, the parent element doesn't receive the next mouse click.  the user has to click the parent element twice for it to receive the click.  This doesn't happen in firefox 3.6.  Is there some javascript I can run after the show panel to fix this.  using focus() on the parent element doesn't help.  Nor does creating a mouse-click event via createEvent and dispatchEvent.
If you provide the code you are using (in plain text), and describe what you are doing, I can provide more help.

Are you trying to have something happen when an anchor button is pressed while the popup is open? The image seems to imply this. There is a way to do this, but the UI would made a lot more sense if it was just a button or link that was labeled 'Open Downloads' rather than giving instructions on some other thing to do. (which are unclear since most people don't know what a badge is in this context).
Yes, I was trying to let them click on the badge when the panel is open.  I understand your point about "open badge" being less intuitive (wording could easily be changed if that's your concern,) but I also thought that there's no reason for them to move the mouse to the bottom of a list of downloads... they can click where their mouse is already hovering.  If we do things the way you suggest, there's no new il8n strings necessary, but the code about keeping the panel open gets more complex (right now there's only a panel when the user hovers over the badge.)  It has to stay open when the mouse is over the panel.  Any suggestions on how to write that part?  It must be somewhere in Firefox, already.
Why not just do both?  Change the message to "click here for Downloads Window" at the bottom of the panel, and also allow the user to click on the progress graph itself.  Is there any reason to _not_ allow the user to click on the graph to bring up the downloads window?
I had been developing on Firefox 3.6.  Playing with Firefox-4, I see your point.  I'm recoding to follow the lead of the web page identity and bookmarks panels.  I'm trying to copy their CSS, and it will be a click to bring up/hide the details of the individual downloads, rather than hovering to see it.  So I've also changed the last line in the panel to be the internationalized "click here to see downloads window" that is already in firefox.

I'm working now to re-implement as a patch.  We'll see how it goes.  I added preferences and font for the colors used in the progress bar and the number of downloads.  I really do believe that some people would want a compact popup panel, so I added a preference for this too... It makes a shortened ETA string (still internationalized) and sets width for the columns explicitly.  It adds very little to the size of the code base.
Attached patch Patch v1 (obsolete) — Splinter Review
Includes some CSS and minor visual improvements, fully internationalized, adds a visual warning to the user when a download fails.  Who should this be submitted to for review?
Attachment #459683 - Attachment is obsolete: true
Attached patch patch v2 (obsolete) — Splinter Review
Some syntax errors fixed and better use of objects over individual variables
Attachment #460179 - Attachment is obsolete: true
Attachment #460183 - Flags: review?(gavin.sharp)
I'm not sure I'll be able to get to this review request in the near future. Can you find someone else more familiar with the download manager UI code to do a first-pass review?
Attachment #460183 - Flags: review?(gavin.sharp) → review?(sdwilsh)
OK.  Changed reviewer
(In reply to comment #28)
> I'm not sure I'll be able to get to this review request in the near future. Can
> you find someone else more familiar with the download manager UI code to do a
> first-pass review?
That would likely be me, but my review queue is already large and it'd be at least two weeks before I could get to it.  Maybe Mardak?

Jason, you should also posts screenshots of various states and have limi give UI review on them.
Assignee: nobody → jes_jm
Status: NEW → ASSIGNED
In at least the extension form of the button, right-clicking on the download button brings up the downloads window. I'd argue that it should bring up the nav bar's context menu, like every other button in the nav bar (except for the Feedback button...).
Attached image For UI review by Limi (obsolete) —
Attachment #459296 - Attachment is obsolete: true
Attachment #460305 - Flags: ui-review?(limi)
Attachment #460183 - Flags: review?(sdwilsh)
Attached patch Patch v3 (obsolete) — Splinter Review
Fix for middle/right click issues reported by Wes
Attachment #460183 - Attachment is obsolete: true
Attachment #460309 - Flags: review?(edilee)
Attachment #460309 - Flags: review?(edilee)
One thing this patch is missing is tests.  The current download manager has a number of tests that you'll likely want to duplicate for this UI:
http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/tests/chrome/
Attached patch Patch v4 (obsolete) — Splinter Review
Attachment #460309 - Attachment is obsolete: true
Attachment #460319 - Flags: review?(edilee)
Sorry Shawn. I don't have the time to write all the tests you want.  Someone else will have to take over this bug if these are necessary for inclusion in Firefox 4.
How does this code relate to the existing download manager window? Did you take a look at how downloads.js (for the existing download manager window) works?

In particular, there was a comment in the patch re: unknown/undefined file sizes when updating the title/summary. The current window handles it this way:

http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/content/downloads.js#425

Is there a spec somewhere of how things should behave? For example, there was a bit about showing the infinity symbol:

>+        else if (activeDownloads>99) // too long to display, and unlikely to occur
>+            activeDownloads="\u221E";

General style comments that would make it easier to read in the context of other mozilla code:
- spaces around binary operators like =, +, ==, !=, ..
- spaces after commas
- {} instead of new Object()
- let instead of var
- setTimeout with function callbacks instead of javascript strings

I see that you're scoping things like DownloadBadge.canvas.{element,context,width,etc.}. It might make the code easier to follow if those were explicitly declared with canvas: { element: ... }.

Also, there's some prefs defined. Are those to simplify development or they're really for end users to tweak vs having the styles be platform specific?
> How does this code relate to the existing download manager window? Did you take
> a look at how downloads.js (for the existing download manager window) works?

I started with the animations and added the data gathering via public API's from the downloadmanager as public API's are what I use when I'm writing an add-on for firefox. No, I'm afraid I didn't look at downloads.js. 

> In particular, there was a comment in the patch re: unknown/undefined file
> sizes when updating the title/summary.

Ah, I can do that in the next patch version.

> Is there a spec somewhere of how things should behave? For example, there was a
> bit about showing the infinity symbol:

I don't know.  I'm open to ideas of alternatives to the infinity symbol.   To increase the number of digits that could be displayed, you'd have to increase size of the canvas, which might then overflow the toolbar and force other elements to get their height stretched by XUL drawing routines (Wes already complained of this in an early version).  Or I suppose you could have the badge not be circular but oval... wider than tall... but I think that's an ugly looking solution.  How often will users have 99 downloads that are active?  Any alternatives you all can think of?

> General style comments

Points taken, I'm a hobby coder.  Sorry for the lack of knowledge, but what's the difference between let and var?  The only thing I've noticed so far is that if I use let inside an if/then statement, the variable fails one level up (which is a pain IMO).

> Also, there's some prefs defined. Are those to simplify development or they're
> really for end users to tweak vs having the styles be platform specific?

My thoughts were that they were for end users to tweak.  I haven't written any firefox skins, but I assumed that preferences for the colors used, perhaps the font as well... might be useful to people who like skinning the browser (or at least they could access them by hand.)  And the "compactView" setting makes the panel much smaller.  As the colors and fonts are used in drawing routines  for a canvas, css can't alter them... so to make them accessible by the user, I thought that preferences were the only method available.

I had one other thought about animation inconsistencies that I've re-coded for the next patch version, if no one objects.  Having the red warning pulse animation for a download failure at any time, but the green pulse for a successful download only when all downloads have finished seemed inconsistent.  So I thought it would be better for a pulsing animation to happen whenever a file completes... success or failure.  Opinions?
Attachment #460305 - Flags: ui-review?(limi)
Attached image For UI Review by Limi (obsolete) —
Shows code updates (new patch coming) to insert file icon and adjust other data placement
Attachment #460305 - Attachment is obsolete: true
Attachment #460411 - Flags: ui-review?(limi)
Attached image For UI Review by Limi
Attachment #460411 - Attachment is obsolete: true
Attachment #460413 - Flags: ui-review?(limi)
Attachment #460411 - Flags: ui-review?(limi)
(In reply to comment #40)
> Created attachment 460413 [details]
> For UI Review by Limi

Hey Jason,

great job on your work so far, really awesome that someone is picking this up. :)

I did a quick scan through of your code yesterday and noticed that if there were more than 99 items, the panel would display the infinity symbol. Definitely a funny behaviour but I had a quick chat with Limi about it and he said that it would make sense to display something like "99+". He also said that it might be reasonable to make the threshold 10-20 items.
Hi Mehdi.  Thanks for the comments.  Unfortunately, 99+ doesn't solve the problem.  99+ (or even 20+) puts us at three characters, which is the space issue I'm trying to avoid.  Other suggestions that might take less horizontal space?
Attached patch Patch v5 (obsolete) — Splinter Review
Implements most requests of edilee@mozilla.com (cleaning up code readability, etc.) Also found a race condition and coded a fix.  Adds file icons to the downloads window.
Attachment #460319 - Attachment is obsolete: true
Attachment #460319 - Flags: review?(edilee)
I'm bowing out of owning the bug.  I don't have the time or the skills to implement Limi's far-reaching spec.  I just had time to work on the visual badge.  Downloads history and replacing the "what should I do?" dialog with a notification bar will have to fall to someone else.
Assignee: jes_jm → nobody
Status: ASSIGNED → NEW
Hello Jason,

thank you very much for having developed this prototype implementation!
I applied the patch on my computer and tried it out, and this was helpful
to get a sense of how things should work.

Then I agree that going from extension-style code to polished code that can
be included in core is a long way, even for good code like yours. There
are a lot of different details to care about, from interoperability to
accessibility to platform integration, just to name a few.

I think I can try and implement the new UI, but I think I'll approach the
problem form another angle and start by reusing existing core code from
"downloads.js" to create the panel. I'm not particularly skilled with
styling and canvas, thus I'll postpone the work on the actual badge and
progress indicator to the final phases.

I'm not sure if we'll be able to get this feature into Firefox 4.0, as only
a few weeks are available to us, but we can give it a try in any case.
This first experiment shows the Download Manager functionality moved to a
panel that can be displayed by clicking on a toolbar button.

The two differences with the Download Manager window are:

 1. There is no "Clear List" button, but every item has a remove icon
     (clicking the X button repeatedly will eventually remove all
     downloads; the same can be achieved using first the "Select All"
     and then the "Remove from List" context menu options).

 2. There is no search box. Searching completed downloads is expected to be
     implemented in the "Download History" window or tab, that can be opened
     using the button with the same name.

In the screenshot I also mocked up a "open" button whose purpose is to make
clear what is the next action expected on a completed download. Also an
"open parent folder" icon should probably be present.

Clicking the "open" button generally shifts the operating system's focus
to another window, and this closes the popup. I think this is OK. I'm not
sure on what should be done with the download item after "open" is clicked,
if we should remove the item, mark it as "used" by reducing its size, or
leave it alone waiting for the user to remove it manually.

When there are no downloads in the panel (the normal "rest" condition), only
the "Downloads History" button is visible, and the panel can be opened anyway.
I tried with a solution in which the panel couldn't be opened at all in that
case, but I found it counter-intuitive as I was unable to get to the downloads
history in the same way after having removed the last download.
This patch can be useful if you want to experiment with the concept
interactively. It is just a copy of the Download Manager code to the
browser content folder, with the minimum number of modifications
required to mock up the expected functionality.

Some notes:
 * When there are many downloads, the panel expands all the way to the
    bottom of the screen, and a scrollbar appears, correctly. However,
    on Windows XP, the panel overlaps with the taskbar and the taskbar
    is on top of it, effectively hiding the "Downloads History" button.
    Ideas on how to fix this?
 * The "Download History" button currently opens the standalone Download
    Manager instead of the downloads history window.
 * Do we want the download panel to be "detachable"? If, by clicking on a
    button or icon in the panel, you can open the standalone Download
    Manager, then you have a way to keep an eye on every single item of
    your current downloads. I'm not sure if we want to continue to support
    this use case.
Blocks: 574688
What milestone is this targeted for? FF 4.0 code freeze is coming up rather fast, and it'd be nice to get this out for testing purposes.
(In reply to comment #48)
> What milestone is this targeted for? FF 4.0 code freeze is coming up rather
> fast, and it'd be nice to get this out for testing purposes.

Since I should be able to work on this full time next week, I expect the new
panel UI to be ready in time for Beta 5, provided that I can get reviews for
code and user interface.

The exact mechanics of the feature depend on whether other changes, like the
download history changes in bug 564900, are also completed at the same time,
but those are not really blockers for moving the DM to a panel.
Assignee: nobody → paolo.02.prg
Status: NEW → ASSIGNED
In the mockups I saw, you could get full download history up in a tab, will this bug cover that also?
(In reply to comment #50)
> In the mockups I saw, you could get full download history up in a tab, will
> this bug cover that also?
No, because the Library isn't moving in time for Firefox 4.0
Attached image Screenshot of all download types (obsolete) —
Time for feedback! :-) This screenshot from an automated test case displays
one download item for every possible download state. The items are styled
after the new Add-ons Manager. The idea is that if the layout is more or
less OK, work for finalizing the visual style can continue in parallel with
the refinement of the exact dynamic behavior of each UI element (like whether
opening the file hides the download or not, or whether there is an "undo
remove from list" context menu item to resurrect the last download).
Attachment #466688 - Flags: feedback?(limi)
>> The items are styled after the new Add-ons Manager

I actually wondered if the style for downloads in the addons manager was final already. Personally, I really feel that those stop/resume/etc icons are WAY to small. I have trouble getting the meaning of the resume icon at my current display resolution (1280x1024) and I am sure noone will get it beyond 1600x1200. Also, remember that people are supposed to click those tiny 8x8 pixel (?) targets.
(In reply to comment #53)
> I actually wondered if the style for downloads in the addons manager was final
> already. Personally, I really feel that those stop/resume/etc icons are WAY to
> small. I have trouble getting the meaning of the resume icon at my current
> display resolution (1280x1024) and I am sure noone will get it beyond
> 1600x1200. Also, remember that people are supposed to click those tiny 8x8
> pixel (?) targets.

Good point, making the click targets larger and adjusting the icons
accordingly can be an improvement over the current Download Manager
"mini buttons".
(In reply to comment #53)
> >> The items are styled after the new Add-ons Manager
> 
> I actually wondered if the style for downloads in the addons manager was final
> already.

No, it's not final - the visual are being worked on now (for everything). We don't yet have any final mockups for the download progress, but I'm told the main difference will just be in the colors used.
At this point the code is more or less in its final form, except for the
second part of "downloads.js", that still requires to be namespaced. A few
important details need to be worked out, however.

The patch is based on the Download Manager files (revision 4a50f3c34d5a),
but since most of the code had to be namespaced, it is probably easier to
apply the patch and look at the resulting files rather than the diff.
Attachment #463704 - Attachment is obsolete: true
Attachment #467089 - Flags: feedback?(edilee)
(In reply to comment #55)
> (In reply to comment #53)
> > >> The items are styled after the new Add-ons Manager
> > 
> > I actually wondered if the style for downloads in the addons manager was final
> > already.
> 
> No, it's not final - the visual are being worked on now (for everything). We
> don't yet have any final mockups for the download progress, but I'm told the
> main difference will just be in the colors used.

We'll work on the visual design soon, but this might bleed into the "polish" phase (ie. after beta5), we should focus on getting the interactions and functionality right.

There's a lot of polish missing on the (notification) panels, and that will improve the looks of this very much.

Here's a screenshot of the visual design of the panel:
http://www.stephenhorlander.com/images/blog-posts/theme-update-2010-04-20/panel-download-win7.png (note that the progress bar might change style-wise, and we aim to have the same styling in the add-ons manager and download manager, whether they technically use the same code or not).
Comment on attachment 466688 [details]
Screenshot of all download types

The close buttons should be removed, and the list of downloads should be cleared on exit.

Looking good apart from that issue, with the understanding that we'll make the panels and content prettier in the polish phase.
Attachment #466688 - Flags: feedback?(limi) → feedback+
Comment on attachment 467089 [details] [diff] [review]
Mostly working (Windows theme only)

I see that you've copied a bunch of files from toolkit's downloads and converted them into a browser.xul overlay. So the toolbar download icon will show the panel with a button showAllDownloads that opens up Tools:Downloads. There'll be quite a bit of duplicate code to drive similar ui.

Are we supposed to have both accessible? It seems kinda odd to have this new panel view that looks and behaves like the old one.

One issue code-structure-wise is that the toolkit implementation is used by other apps like SeaMonkey and Thunderbird, so the toolkit implementation needs to stay stand-alone functional without the new panel.

>+++ b/browser/base/content/browser.xul
>+             defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container,bookmarks-menu-button-container,downloads-button,navigator-throbber,fullscreenflex,window-controls"
There'll need to be some migration code for the new download button to show up for users that have changed from the default set.

>+++ b/browser/components/downloads/DownloadCommon.jsm
What is this common code supposed to be shared with? Right now it'll only be used for the Firefox download panel?

>+const kDownloadsStringBundleUrl =
>+      "chrome://browser/locale/downloads/downloads.properties";
You've copied the file from the toolkit version and removed some strings, so there'll be duplicate entries. Why does it need to be in a separate file vs reusing the existing toolkit ones?

I know that l10n prefers separate string entities for different uses, but I'm not sure if showing yesterday=Yesterday in the download window is different from showing it in a panel.
sdwilsh: Any suggestions for how the code should be structured to drive both the Firefox panel and toolkit download window?

I suppose the panel could land with its own copies of logic and strings, but it would be good to refactor things so that only the ui/view-specific code are "duplicated" and shared as a js module living in toolkit.
(In reply to comment #60)
> sdwilsh: Any suggestions for how the code should be structured to drive both
> the Firefox panel and toolkit download window?
this sounds good to me:
> I suppose the panel could land with its own copies of logic and strings, but it
> would be good to refactor things so that only the ui/view-specific code are
> "duplicated" and shared as a js module living in toolkit.
although I agree with your comments about the strings in comment 59 and we probably shouldn't duplicate them.
(In reply to comment #60)
> sdwilsh: Any suggestions for how the code should be structured to drive both
> the Firefox panel and toolkit download window?

If by "toolkit download window, you mean this:
http://people.mozilla.com/~madhava/blog/2008-05-26/download_manager.png

…then no, we're not supposed to have that one anymore.

If you're talking about the History view (which mmmulani has a patch that adds Downloads to the sidebar for), that's how it's supposed to work.
(In reply to comment #62)
> …then no, we're not supposed to have that one anymore.
Oh, then I suppose Tools -> Downloads will go to that History/Library view when it does land? Right now I believe the patch will trigger Tools -> Downloads when you click show Downloads History at the bottom of the panel.

sdwilsh: Even if we keep the two code paths separate (browser/components/downloads vs toolkit/mozapps/downloads) should prefs be shared? Also would we actively want to not package chrome://mozapps/content/downloads/ ?

Oh and what should the the shortcut for downloads trigger? Activate the panel or History view?
(In reply to comment #62)
> If you're talking about the History view (which mmmulani has a patch that adds
> Downloads to the sidebar for), that's how it's supposed to work.

I thought I remembered seeing a mock-up of download history in a tab, but have been unable to locate it upon a quick check. Personally I don't use sidebars, I find them ugly and cumbersome, will there be a pref to open download history in a tab or will users be forced to use the sidebar?
Thank you for all the feedback! I'm thrilled to see this taking shape!

I'll try to work out the best solutions together with you, from the
perspectives of code management and interaction design separately.
For now I'll leave aside the visual design as I understand that this
will be finalized at a later time.

I'll answer each point as best I can, but firstly I took some time
to gather my ideas about why I was doing things in a certain way,
and share with you my reasoning. In my experience I found out
that it's much easier to talk about features and details when
the motivations for their existence is clear, forming a common
reference. I think this summarizing work is useful for this
reason, whether the features will be deemed relevant or not,
although I hope there is still room for a contribution in the
area of interaction design.

I considered a specific use case, that I believe is common, from
start to finish: downloading and running a setup program. There
are probably other use cases for which the same considerations
may apply.

For this use case, I compared the current workflow with what I think
that a new workflow, based on Limi's design, could look like. This
is scoped to what is feasible in the limited time until Beta 5.
(In reply to comment #64)
> I thought I remembered seeing a mock-up of download history in a tab, but have
> been unable to locate it upon a quick check. Personally I don't use sidebars, I
> find them ugly and cumbersome, will there be a pref to open download history in
> a tab or will users be forced to use the sidebar?

The patch for showing downloads in History is bug 564900 (it's listed as a dependency of this bug).

You should be able to have History in a tab eventually, but for 4.0 it'll probably still be in a window. Post 4.0, we'll invest some time in improving and rethinking history/bookmarks and related UI.
Here is the current workflow, with default preferences:

 1. Click on a download link on a website.
 2. Confirm download.
 3. The download window appears on top.
 4. If the download takes time, return to the browser window and
    continue browsing while the file is being downloaded.
 5. A download completed notification appears briefly. Generally
    it disappears before you can click on the hyperlink.
 6. Find the downloads window in the operating system's taskbar.
 7. ?

This is where I think there is no obvious hint on what to do next.
You can double-click the file name to continue.

 7. Double-click the file name to continue.
 8. Confirm execution, and (not shown) run setup wizard.
 9. Continue browsing, but before that, remove download.

Although it can be argued that there is no point in removing a
download from the list, and I might as well leave it as it is,
I feel much more comfortable if I can hide the "used up"
downloads. This is because, for me, the downloads list view is
a transient view that is primarily used for current tasks.

Not removing the download is like leaving a tab open when I'm
finished with it - in fact, why close the tab at all? ;-)

This is why I regard point 9 as an integral part of this use case.
Here are two proposals for a new workflow:

 1. Click on a download link on a website. (same as before)
 2. Confirm download. (same as before - there is a plan to remove
    this confirmation, but it's outside of the scope of this bug)
 3. Download indicator flashes, and download panel opens. (the panel
    might open only the first time, or this behavior might be
    controlled by a preference)

I can continue browsing just by dismissing the panel.

 4. Download indicator becomes "highlighted". This indicates that
    there are new downloads for which an action can be performed.
    Click the indicator at any time to open the panel. (the panel
    might also open automatically, or an "icon style" notification
    may appear, or this behavior might be controlled by a preference)
 5. Click "Open" to continue. (a dropdown menu is available if you
    want to perform different non-default actions, like in the new
    "notifications" interface).
 6. Confirm execution and run setup wizard. (same as before - the
    confirmation is asked for by the operating system in some cases)

At this point I see two alternatives.

In solution (A), I'm done! The download is truly "notification
style", that is, the notification disappears on exit. In this way,
when I return to the browser after running the setup wizard, the
downloads indicator is not "highlighted" anymore, and I can
continue browsing without worrying about the download.

If something went wrong with the setup there is an "undo" button
(might look differently from the mockup) to display the last
download again. This is analogous to the "undo close tab" use case.

In solution (B), I can reopen the panel and rest assured that
I will find it in the same state as when it closed itself. If I
want, I can remove the download using a natural interaction (the
left mouse button on the X). If I change my mind, I can resurrect
the item with the undo button (I think this operation should be
first-class, like for tabs, without requiring the history
window to be opened).

Another interesting property of the "close" button is that it can
easily be used to hide multiple downloads by repeated clicking.
For the close buttons of tabs, an effort was recently made to
achieve this property. It is already there in this case.

Comments on these ideas are very welcome!
Attachment #467459 - Flags: feedback?(limi)
Attachment #467455 - Attachment description: [Comment 66] Old workflow for downloading and running a setup program → [Comment 67] Old workflow for downloading and running a setup program
Attachment #467459 - Attachment description: [Comment 67] New workflow for downloading and running a setup program → [Comment 68] New workflow for downloading and running a setup program
(In reply to comment #59)
> Comment on attachment 467089 [details] [diff] [review]
> 
> >+++ b/browser/base/content/browser.xul
> >+             defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container,bookmarks-menu-button-container,downloads-button,navigator-throbber,fullscreenflex,window-controls"
> There'll need to be some migration code for the new download button to show up
> for users that have changed from the default set.

Ah, I hoped this was handled by the XUL toolbar. Is there already some
code that does that for other cases?

> >+++ b/browser/components/downloads/DownloadCommon.jsm
> What is this common code supposed to be shared with? Right now it'll only be
> used for the Firefox download panel?

Since it is a JS module, its data (localized strings for now) is shared
between all the browser window instances, while the other objects have
an instance for each window.

As only one panel is visible at any one time, I had a half idea of
having a single populated panel and move it "in block" to another window,
if at all possible, instead of having each window re-query the same
downloads. When doing this, I would move the data access object to the
JS module. But this is only an optimization, and maybe not even feasible,
so I'm not considering it as a priority at this point.

> >+const kDownloadsStringBundleUrl =
> >+      "chrome://browser/locale/downloads/downloads.properties";
> You've copied the file from the toolkit version and removed some strings, so
> there'll be duplicate entries. Why does it need to be in a separate file vs
> reusing the existing toolkit ones?
> 
> I know that l10n prefers separate string entities for different uses, but I'm
> not sure if showing yesterday=Yesterday in the download window is different
> from showing it in a panel.

Localized strings are one of the points that I was unsure about. It's
exactly as you say, some strings have to be different because the interface
is in a different place (for example, I've already reworded a few English
strings for space reasons). But for other strings, like the "open
executable warning", it might make sense to share them.

But in this case, I think it would not be so difficult to move the entire
interactive confirmation function to a shared place in Toolkit, like
DownloadUtils.jsm. Shawn, what do you think?
(In reply to comment #61)
> (In reply to comment #60)
> > sdwilsh: Any suggestions for how the code should be structured to drive both
> > the Firefox panel and toolkit download window?
> this sounds good to me:

I'm not sure about what you're suggesting exactly, but what I'm trying to do
now is to create separate "blocks" (the singleton objects you can already see)
for various parts of the code, like data access, to make it easier to move
them around.

What I'm trying to achieve is to make it easy (and fast) for this bug to
land independently from Toolkit, and then when the panel is polished and
the interactions are finalized, it should be very easy to replace most of
Toolkit's code with the new one. At that point we could also decide which
blocks to migrate, that is if we want to keep the old interactions for
Toolkit or if we want the DM to simply become a window that hosts the
new panel UI overlay, moved to Toolkit in its entirety.
(In reply to comment #63)
> Oh and what should the the shortcut for downloads trigger? Activate the panel
> or History view?

I'm not sure about this one. I'd say the panel ("manage" current downloads),
with maybe a separate command in the History menu?

I think this was the last unanswered point from the above comments, I've
finished spamming for now ;-) Let me know if you have any other concern!
This patch appears to work correctly (Windows theme only), and most of the
code should be in its final form, except for the global functions in the
second part of "downloads.js". The finished portions are ready for review;
the idea is that after review those parts won't change very much and the
subsequent enhancements can be in turn reviewed using interdiff.

Still missing from this version:
 * Always opening the panel instead of the Download Manager
 * Correct behavior of the Downloads History button
 * Migration code for having the download icon or badge visible by default
 * Share the "open download" function, or at least its strings, with Toolkit
 * Copy the Windows theme to the other theme folders
Attachment #467089 - Attachment is obsolete: true
Attachment #467894 - Flags: review?(edilee)
Attachment #467089 - Flags: feedback?(edilee)
Depends on: 591289
Edward, I have another patch that implements the correct behavior for
displaying the Downloads panel and history, as well as fixing a few other
issues. This means basically a feature-complete version. Do you prefer
to receive it as a patch on top of the existing one, or as a full patch
including the previous one?
This blocks the status bar replacement in bug 574688, so is also blocking+.
blocking2.0: --- → beta6+
(In reply to comment #74)
> This blocks the status bar replacement in bug 574688, so is also blocking+.

Talked this through with Dietrich and Limi - we do not believe that this is necessary for the status bar work.
blocking2.0: beta6+ → -
It may not block due to status bar work, but shouldn't it block a beta for feature freeze in its own right? The current download manager feels old and out of place in Firefox 4 and lots of people would really like to see this get in.
I would love to have it, don't get me wrong, but no, we can't hold the release on it. We are too late in the cycle to contain the risk. But I would love to have it.
No longer blocks: 574688
Whether we'll be able to get the new Download Manager in Firefox 4 actually
comes down to how much review effort is required to finalize it. Shawn kindly
offered to do a first-pass review that may help us in understanding it.

The good news is that this version of the patch is feature-complete, only
the following trivial "maintenance" tasks are still open:
 * Move global functions in "downloads.js" to a dedicated namespace.
 * Ensure the toolbar icon is visible when upgrading from an old profile.
 * Share the "open download" function, or at least its strings, with Toolkit.
 * Copy the Windows theme to the other theme folders.

In case someone wants to try it live, consider that this patch is based on
changeset 9fd11a17eb1a. Also, the dependencies 564900 and 591289 are
required for enjoying the full experience. :-)
Attachment #467894 - Attachment is obsolete: true
Attachment #470869 - Flags: review?(sdwilsh)
Attachment #467894 - Flags: review?(edilee)
Excellent work, Paolo!

Yes, we'd love to have this, but the definition of a blocker is that we'd hold the release for it — which we won't.

That doesn't mean we shouldn't try to get it landed, however! :)
Whiteboard: [strings]
Comment on attachment 470869 [details] [diff] [review]
Feature-complete version for review (Windows theme only)

So, it seems to me that we are completely breaking the toolkit UI with this patch.  Is that right?  We cannot do that since other applications (Thunderbird, Songbird, others probably) do depend on this UI.

For review comments with expandable file context, please see http://reviews.visophyte.org/r/470869/.

on file: browser/base/content/browser.xul line 1004
>       <toolbarbutton id="downloads-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
>                      oncommand="DownloadsOverlay.showPopup();"
>                      ondrop="DownloadsButtonDNDObserver.onDrop(event)"
>                      ondragover="DownloadsButtonDNDObserver.onDragOver(event)"
>                      ondragenter="DownloadsButtonDNDObserver.onDragOver(event)"
>                      ondragleave="DownloadsButtonDNDObserver.onDragLeave(event)"
>                      label="&downloads.label;" removable="true"
>                      tooltiptext="&downloads.tooltip;"/>

nit: one property per line please.  It's easy to miss some of them because
there are randomly more than one on a line.


on file: browser/components/downloads/DownloadCommon.jsm line 81
>   /**
>    * True as soon as initialization begins.
>    */
>   _initStarted: false,

This is private state, so it shouldn't be on an exported symbol.


on file: browser/components/downloads/DownloadCommon.jsm line 95
>     // convert strings to those in the string bundle
>     let (sb = Services.strings.createBundle(kDownloadsStringBundleUrl)) {
>       for (let [name, value] in Iterator(DownloadCommonStrings)) {
>         if (typeof value == "string") {
>           DownloadCommonStrings[name] = sb.GetStringFromName(value);
>         } else {
>           // Convert "arguments" to a real array before calling into XPCOM
>           DownloadCommonStrings[name] = function() sb.formatStringFromName(
>             value[0], Array.prototype.slice.call(arguments), arguments.length);
>         }
>       }
>     }

We should be doing this lazily, as needed (see how DownloadUtils.jsm does
this).


on file: browser/components/downloads/DownloadManagerUI.js line 59
>     var browser = Services.wm.getMostRecentWindow("navigator:browser");
>     if (browser) {
>       browser.DownloadsOverlay.showPopup();
>     }

feels wrong to not show anything if there are now browser windows open.


on file: browser/components/downloads/tests/browser_basic_functionality.js line 180
>     gDownloadsView.focus();

hmm, why do we need to focus?


on file: browser/themes/winstripe/browser/jar.mn line 51
>         skin/classic/browser/downloads/downloadButtons.png           (downloads/downloadButtons.png)
>         skin/classic/browser/downloads/downloadIcon.png              (downloads/downloadIcon.png)
>         skin/classic/browser/downloads/downloads.css                 (downloads/downloads.css)
>         skin/classic/browser/downloads/pause.png                     (downloads/pause.png)
>         skin/classic/browser/downloads/stop.png                      (downloads/stop.png)

note: we'll need to have something, even if not great, for linux and os x
before this can land.


on file: toolkit/components/downloads/src/Makefile.in line 69
> # TODO: Disable this also when building the "browser" application.
> #EXTRA_COMPONENTS = \
> #  nsDownloadManagerUI.js \
> #  nsDownloadManagerUI.manifest \

needs to be fixed before moving forward.  You might get help from khuey on how
to do this properly.

We also still need to test this UI, which means we'll need to build it
somehow.


on file: browser/locales/en-US/chrome/browser/downloads/downloads.properties line 18
> stateBlockedPolicy=Blocked by your Security Zone Policy

if you change a string, you also need to change it's name, otherwise
localizers will not know it's meaning changed.


on file: browser/locales/en-US/chrome/browser/downloads/downloads.properties line 19
> stateDirty=Blocked: May contain a virus or spyware

needs a localization note


on file: browser/components/downloads/download.xml line 29
> #   Blair McBride <bmcbride@mozilla.com>

er?


on file: browser/components/downloads/downloads.js line 57
> Cu.import("resource://gre/modules/DownloadCommon.jsm");

this file you reference is built in browser/ so toolkit/ cannot depend on it.
Attachment #470869 - Flags: review?(sdwilsh) → review-
(In reply to comment #80)
> So, it seems to me that we are completely breaking the toolkit UI with this
I thought that at first as well, but notice that all the files are being copied then modified. It just shows up strange in the diffs.
(In reply to comment #80)
> on file: browser/components/downloads/DownloadManagerUI.js line 59
> >     var browser = Services.wm.getMostRecentWindow("navigator:browser");
> >     if (browser) {
> >       browser.DownloadsOverlay.showPopup();
> >     }
> 
> feels wrong to not show anything if there are now browser windows open.

That's inherent in the panel design I think... but maybe we can ensure that
a new browser window is opened if the call is the result of an explicit user
request, while for new downloads initiated while there is no browser window
open (rare case I think) I don't think we should open a new window, there
will be a screen-level notification when the download is completed in any
case.

I'm also interested in Limi's opinion on this.

> on file: browser/themes/winstripe/browser/jar.mn line 51
> >         skin/classic/browser/downloads/downloadButtons.png
> note: we'll need to have something, even if not great, for linux and os x
> before this can land.

I think copying the folder as is will suffice for now, it's based on the
new Add-ons Manager design which is not platform-specific, and refining
the visual style is explicitly a non-goal for the next beta. I've not done
the copy yet in case I spot any bugs or any change is needed, but I'll do
the copy before the final version.

> on file: toolkit/components/downloads/src/Makefile.in line 69
> > # TODO: Disable this also when building the "browser" application.
> > #EXTRA_COMPONENTS = \
> > #  nsDownloadManagerUI.js \
> > #  nsDownloadManagerUI.manifest \
> 
> needs to be fixed before moving forward.  You might get help from khuey on how
> to do this properly.

Thanks, I'll ask.

> on file: browser/locales/en-US/chrome/browser/downloads/downloads.properties
> line 19
> > stateDirty=Blocked: May contain a virus or spyware
> 
> needs a localization note

Why?

> on file: browser/components/downloads/download.xml line 29
> > #   Blair McBride <bmcbride@mozilla.com>
> 
> er?

This reflects the fact that I originally included work from the
Add-ons Manager download progress XBL binding. It's heavily modified
however, so I'm not sure if the credit is still required.

I'll work on the other nits immediately.
(In reply to comment #81)
> I thought that at first as well, but notice that all the files are being copied
> then modified. It just shows up strange in the diffs.
Ugh, review board appears to have mislead me :(
(In reply to comment #82)
> That's inherent in the panel design I think... but maybe we can ensure that
> a new browser window is opened if the call is the result of an explicit user
> request, while for new downloads initiated while there is no browser window
> open (rare case I think) I don't think we should open a new window, there
> will be a screen-level notification when the download is completed in any
> case.
Hmm, we should clearly get input from UX on this.

> I think copying the folder as is will suffice for now, it's based on the
> new Add-ons Manager design which is not platform-specific, and refining
> the visual style is explicitly a non-goal for the next beta. I've not done
> the copy yet in case I spot any bugs or any change is needed, but I'll do
> the copy before the final version.
As long as UX is OK with this, and we actually have resources to get the theming right, I'm OK with this.  If either of those conditions is a problem, this should probably slip to Firefox.Next

> Why?
So localizers know what it's for.  Also note how the other states have notes.

> This reflects the fact that I originally included work from the
> Add-ons Manager download progress XBL binding. It's heavily modified
> however, so I'm not sure if the credit is still required.
Probably not worthwhile (but make sure you are on there if you care).
All nits addressed. Here is the current list of open tasks:
 * Understand what to do when user requests to open the download manager
    and there is no browser window open.
 * Move global functions in "downloads.js" to a dedicated namespace.
 * Share the "open download" function, or at least its strings, with Toolkit.
 * Copy the Windows theme to the other theme folders.

I also implemented the migration code for the toolbar button. As there is no
automated test suite for testing profile migration from older versions, I did
the following manual tests:
 - Created four new profiles in Firefox 3.6 (A, B, C and D)
 - Started FF 3.6 with profile B and closed immediatley
 - Started FF 3.6 with profile C, customized the toolbar without adding a
    Downloads button, then closed the browser
 - Started FF 3.6 with profile D, added the Downloads button and closed
 - Started Minefield once per profile, and verified that the Download
    button always appeared and there were no related errors in the Console.
Attachment #470869 - Attachment is obsolete: true
Attachment #471241 - Flags: review?(sdwilsh)
(In reply to comment #84)
> (In reply to comment #82)
> > That's inherent in the panel design I think... but maybe we can ensure that
> > a new browser window is opened if the call is the result of an explicit user
> > request, while for new downloads initiated while there is no browser window
> > open (rare case I think) I don't think we should open a new window, there
> > will be a screen-level notification when the download is completed in any
> > case.
> Hmm, we should clearly get input from UX on this.

Wait, how can you get a download without any windows open? Or is that not what this means? :)

To try to cover some edges cases up front in the name of efficiency:
- If you're clicking a link from an external application, you get a browser window.
- If you shut down the last window on Windows, you are quitting the application. If any downloads are in progress, we warn about quitting.
- If you shut down the last window on the Mac, there's no download progress indicator in any windows. The downloads folder will still bounce when the download is done, and you can always open a window to get to the panel, so this is OK too.

Anything else that we need to handle?


> > I think copying the folder as is will suffice for now, it's based on the
> > new Add-ons Manager design which is not platform-specific, and refining
> > the visual style is explicitly a non-goal for the next beta. I've not done
> > the copy yet in case I spot any bugs or any change is needed, but I'll do
> > the copy before the final version.
> As long as UX is OK with this, and we actually have resources to get the
> theming right, I'm OK with this.  If either of those conditions is a problem,
> this should probably slip to Firefox.Next

We are OK with this. Ideally, they should be the same thing eventually, but for now it seems like this is the easiest way, even if it results in some duplication.
(In reply to comment #86)
> Wait, how can you get a download without any windows open? Or is that not what
> this means? :)
An add-on could very easily do this via APIs.

> To try to cover some edges cases up front in the name of efficiency:
> - If you're clicking a link from an external application, you get a browser
> window.
> - If you shut down the last window on Windows, you are quitting the
> application. If any downloads are in progress, we warn about quitting.
> - If you shut down the last window on the Mac, there's no download progress
> indicator in any windows. The downloads folder will still bounce when the
> download is done, and you can always open a window to get to the panel, so this
> is OK too.
- Library or other non-browser window (even add-on provided) is the only thing open.

That's all I got right now, but my gut says there is more.
(In reply to comment #87)
> (In reply to comment #86)
> > Wait, how can you get a download without any windows open? Or is that not what
> > this means? :)
> An add-on could very easily do this via APIs.

OK. I still think that's sufficiently edge-case-y that we're OK with not showing it, given that all major OSes have bounce/glow indicators on download completion.

> - Library or other non-browser window (even add-on provided) is the only thing
> open.

Right. So don't show any panel, but bounce/glow on the OS level still works?
(In reply to comment #88)
> OK. I still think that's sufficiently edge-case-y that we're OK with not
> showing it, given that all major OSes have bounce/glow indicators on download
> completion.
Er, we don't do that at all on windows (except for the browser window, which would be closed in this situation) AFAIK.
(In reply to comment #89)
> (In reply to comment #88)
> > OK. I still think that's sufficiently edge-case-y that we're OK with not
> > showing it, given that all major OSes have bounce/glow indicators on download
> > completion.
> Er, we don't do that at all on windows (except for the browser window, which
> would be closed in this situation) AFAIK.

I'm confused. How can the app be open on Windows with no windows open? (what an awkward sentence :P )
Why not just open a new about:blank window as a fallback when needed? Probably not ideal, but in such an odd edge case it may be fine, at least for now.
(In reply to comment #90)
> I'm confused. How can the app be open on Windows with no windows open? (what an
> awkward sentence :P )
Having a non-browser window open (like the Library) will keep the application running.  However, we don't, AFAIK, do any download indication on those windows.  We only do that for actual browser windows.

We will still do the toaster pop-up though.
(In reply to comment #92)
> We will still do the toaster pop-up though.

Exactly; see attachment 467455 [details], step 5. Clicking the hyperlink named "All
files have finished downloading" used to open the download manager window (by
the way, I never managed to click on it before the notification went away).

To reproduce the condition we're talking about, you'd have to start a
download, open the Library window, close the last browser window, wait for
the screen-level notification, and click the link. In this case, I don't
know if it makes sense to open a new browser window and show the downloads
panel. We might just ignore the click; you'll see the download in the panel
the next time you open a browser window.
Note that my concern here is that we are no longer following the API contract here which says it *will* show the UI if it isn't already visible.  Just because the browser might be OK with this change, other consumers may not be.
(In reply to comment #92)
> (In reply to comment #90)
> > I'm confused. How can the app be open on Windows with no windows open? (what an
> > awkward sentence :P )
> Having a non-browser window open (like the Library) will keep the application
> running.  However, we don't, AFAIK, do any download indication on those
> windows.  We only do that for actual browser windows.
> 
> We will still do the toaster pop-up though.

Sorry if this is off topic.

Will we get a faster, less cpu intensive "Toaster-Popup"?
(In reply to comment #95)
> Will we get a faster, less cpu intensive "Toaster-Popup"?
File a different bug if you have issues with it please.
Just a question about the appearance of the "downloads" button on the toolbar... Are there any plans about making an indicator of the download progress (like in the "download badge" at the beginning of the discussion)?
(In reply to comment #97)
> Just a question about the appearance of the "downloads" button on the
> toolbar... Are there any plans about making an indicator of the download
> progress (like in the "download badge" at the beginning of the discussion)?

Yes, actually my idea was to do that indicator right after beta 6, since that
is not a new feature but a visual improvement requiring no localization changes.

That said, at this point it doesn't seem the panel UI will be able to be
included in Firefox 4, but will have to wait for the next version, since
currently all the people that could review it are assigned to other tasks.

Shawn has been very kind to help with giving an assessment of how much
review effort was required to finish the task, both for this bug and the
dependencies, but, since it was a side-trip from his assigned duties, the
assessment was conducted in a hurry and probably even resulted in the
current code situation being perceived as worse than it actually is,
which would not have happened in a relaxed environment.

I'm happy to have had the opportunity of finishing the task in time, but
I too prefer to have my code reviewed and evaluated without hurry! Then,
the feature will have plenty of time to be polished and even optimized
for performance before it is released for its first public beta.

Moreover, it is also possible that before Firefox 4.1 someone else will
also work on the broader download experience improvements outlined by
Alexander Limi and we'll be able to release them all at once.
Sorry, but I don't think I can get to this before Friday anymore :(
Comment on attachment 471241 [details] [diff] [review]
Updated feature-complete version (Windows theme only) [NOTE: has hg copies]

(In reply to comment #99)
> Sorry, but I don't think I can get to this before Friday anymore :(

That's fine, I wouldn't have been able to get a final review in time in any
case. Thank you for having looked at this in the first place! Since now
there's a lot of time before this feature is released, I think I'll swap
the order in which I thought to do the job, and work first on features of
Toolkit's download manager that will make a shared implementation possible.

I'm currently thinking about bug 438342 and bug 410538, and will file new
bugs as necessary in the following months.
Attachment #471241 - Flags: review?(sdwilsh)
So this will not be in FX4?
It sounds like the plan is to not aim for FF4, but I would still hold out hope for a later than usual backport from future Trunk to the FF4 branch in time for 4.0. This is very important and everyone wants it. Screw the procedure if need be for this one, I say. If not, I do hope 4.1 isn't a fantasy number this time.
(In reply to comment #102)
> If not, I do hope 4.1 isn't a fantasy number this time.

Exactly, I hope 4.1 won't morph into 4.5 and with one year waiting (3.5, anyone?).
(In reply to comment #103)
> Exactly, I hope 4.1 won't morph into 4.5 and with one year waiting (3.5,
> anyone?).

Please read the bugzilla guidelines before commenting: https://bugzilla.mozilla.org/page.cgi?id=etiquette.html

Interesting for you here would be 1.1 and 2.
I'm confused by a bunch of removed strings in attachment 471241 [details] [diff] [review], at least for one I didn't find a corresponding code change (timeDouble).
(In reply to comment #105)
> I'm confused by a bunch of removed strings in attachment 471241 [details] [diff] [review], at least for
> one I didn't find a corresponding code change (timeDouble).
The patch is misleading how it's displayed in bugzilla and other tools.  Read the raw diff.
There is quite some content removed from downloads/downloads.properties, which is used in http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/DownloadUtils.jsm#76, AFAICT, and not removed by this patch.
The strings being removed are from the browser copy of downloads.properties not toolkit's downloads.properties:

copy from toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
copy to browser/locales/en-US/chrome/browser/downloads/downloads.properties
--- a/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
+++ b/browser/locales/en-US/chrome/browser/downloads/downloads.properties
@@ -1,120 +1,31 @@
-# LOCALIZATION NOTE (seconds, minutes, hours, days): Semi-colon list of plural
Ah, now I get it, thanks.
Attachment #471241 - Attachment description: Updated feature-complete version (Windows theme only) → Updated feature-complete version (Windows theme only) [NOTE: has hg copies]
This isn't intended for 4.0?
It might require a miracle, but I believe it's still possible.
I'll prey for miracle then. :)
This is not happening for Firefox 4.  Sorry folks.
(In reply to comment #113)
> This is not happening for Firefox 4.  Sorry folks.

I didn't follow everything here (sorry if it's a dup :-(), but is implementing the download manger that was in the status bar in the hint of the new download button in the primary UI a "good" solution as this bug won't land in time for Fx4 ?
I believe that we are trying to knock the status bar out, at least hidden by default. (see Bug 574688)
(In reply to comment #115)
> I believe that we are trying to knock the status bar out, at least hidden by
> default. (see Bug 574688)

I know that, but I was refering to download label that *was* in ths status bar that could be shown *now* into the new download button hint (on mouse over) to not break too much this functionality with the removal of the status bar (that I don't discuss here) as this info will stay in the primary UI.

Is that a good plan with the situation of this bug now ?
My apologies for bending etiquette here, but I just have to fight for this bug.

How close are we here to being able to have a fully workable patch, within a reasonable minimum criteria? The feature and string freeze beta keeps getting delayed (i.e. the first "beta" that's really not a high-quality alpha) so there's more time than it might look.

Is it possible to do the apparently standard cheat of committing a strings only patch and then getting the rest in at a later date?

The Addon Manager got its nice fancy new tab, but the Download Manager is still futzing with an old popup window. The Download Manager is the last bastion of the old style of GUI and not getting it updated feels to me like Firefox 4 wouldn't be fully complete.
We've had feature and string freeze yesterday, and it missed feature freeze.
Can we cheat somehow then, please? This one is particularly important, I think. Though, I feel I may be waging a loosing battle here... :/
The application of the definition of "feature" here is debatable. It's a GUI update primarily, not really redoing the entire concept of a download manager.

(sorry for the bugspam)
(In reply to comment #119)
> Can we cheat somehow then, please? This one is particularly important, I think.
> Though, I feel I may be waging a loosing battle here... :/
No.  This is explicitly not blocking 2.0, and it's not making Firefox 4.  That is the final answer.
Depends on: 597067
(In reply to comment #116)
> I know that, but I was refering to the download label that *was* in ths status > bar that could be shown *now* into the new download button hint (on mouse over) > to not break too much this functionality with the removal of the status bar
> (that I don't discuss here) as this info will stay in the primary UI.
> 
> Is that a good plan with the situation of this bug now ?

I've filled bug 597067 for this late solution to not break too much the primary UI.
(In reply to comment #121)
> (In reply to comment #119)
> > Can we cheat somehow then, please? This one is particularly important, I think.
> > Though, I feel I may be waging a loosing battle here... :/
> No.  This is explicitly not blocking 2.0, and it's not making Firefox 4.  That
> is the final answer.

:sigh:  Ruling accepted.

However, *something* is going to have to be done, because as pointed out by others even the old GUI is getting broken by the status bar removal.
Agreed.
Here is an idea: As the original mockup from Stephen (http://www.stephenhorlander.com/images/blog-posts/theme-update-2010-04-20/panel-download-win7.png) has showed, we can use pie chart inside button's icon. This is basicaly only transfer the progress meter to a different place, not a new feature, so it shouldn't be affected by feature-freeze, just like showing link's adress in location bar.
Maybe we should file a bug to investigate an alturnative place to put download notifications?
No longer depends on: 597067
(In reply to comment #125)
> Maybe we should file a bug to investigate an alturnative place to put download
> notifications?

(In reply to comment #126)
> Bug 597145

I've filled a generic bug 597155 for this
No longer blocks: 597155
Depends on: 597155
Having this default in new firefox would be awesome, also because in b7 I don't see any downloads information (need to have downloads windows open)

good work!
well i feel pathetic right now , but i kind of made a quick mockup for other method of implementation 

http://img517.imageshack.us/img517/214/20177387.png
This neither looks good nor is it a useful attempt - the previous mockup makes current download's status accessible within 1 click on the downloads-button.
Your attempt needs 1 click and several mouse-moves through submenus to get to needed information..
True but it takes no new button , but yeah , it should be accessible at the earliest hmm
I'd prefer a little, but informative, button over a complicated submenu-structure.. ;)
:)
If we want this for Firefox 5, we should start moving on it soon.  Paolo, do you have time to work on this soon?
(In reply to comment #134)
> If we want this for Firefox 5, we should start moving on it soon.  Paolo, do
> you have time to work on this soon?

Probably, but it depends on what you mean by "soon" :-)

My understanding was that everybody that could review the patch was assigned
to other tasks related to the Firefox 4 release. If this is still the case,
then it means we can't start to work on this again until Firefox 4 is
released, and that would actually match with my current planning :-)

In any case, this bug is not waiting on myself at present. Anybody should
feel free to do code review on the current patch as soon as they wish!
(In reply to comment #135)
> In any case, this bug is not waiting on myself at present. Anybody should
> feel free to do code review on the current patch as soon as they wish!
Ah, in that case, I think it'd be good for Mardak to do a first pass, and limi needs to provide UI feedback.
If someone can get me a tryserver build, I'd be happy to do a first round of UI feedback!
I can request first-pass code review as soon as Mardak is free, but I guess
the tryserver build would require unbitrotting the patch first, because it's
several months old now, and would also require copying the styles to the
non-Windows themes to allow people to test on any platform.
(In reply to comment #138)
> and would also require copying the styles to the
> non-Windows themes to allow people to test on any platform.

I'm fine with limiting the initial UI review to a single platform (Mac, Linux) if that makes it easier to get this started again.
Any reason why was attachment deleted?
It was the same as the patch with extra buttons.
I created an updated patch that can be used for testing on all platforms. Builds
that include this patch will be available here for some time:

http://ftp.mozilla.org/pub/mozilla.org/firefox/tryserver-builds/paolo%2Emozmail%40amadzone%2Eorg-278e7fd33e27/
Attachment #471241 - Attachment is obsolete: true
(In reply to comment #144)
I can not open about download window with shortcut key at its revision.
Shouldn't it be an ArrowPanel??
1. Ongoing download should be at the top of the list.
2. Drop down menu for "Open" should close on clicking arrow button again.
3. The overall appearance also needs to be improved.
Thanks for the feedback! The appearance is intentionally raw, it will be
refined as a next step whan all the functionality is there, also because
it will be different for different operating systems. It will definitely
be an arrow panel!

For now, we're concentrating on functionality and usability.
(In reply to comment #147)
> 1. Ongoing download should be at the top of the list.

I'm really interested in this piece of feedback. Did you use the new build
while browsing normally, or only for testing? In the former case, did you
find a real usability problem with completed downloads being listed first?

The point is that the item you're most likely to interact with is the download
that just finished. This is why it is at the top of the list, to avoid it being
moved out of sight by ongoing downloads. Probably you want to open the file, or
just know that that particular download has finished and dismiss it by clicking
the X (like for tabs).

There will be a separate indicator to see the overall status of ongoing
downloads, that will be visible even without clicking on the button.
1) Clear Download history option is unavailable
2) For two or above downloads , this scheme would not be feasible enough for the case of netbooks as it takes hell lot of space. Instead a theme with 4~5 downloads visible under 600px would do great
3) This requires us to have another download button (i know its discussed) , i think we should use the same idea of downloading of an addon , and place a download button just prior to the url and its icon (whatever its called) and make it global (not the case for addons) . The advantage is that , the user already knowns that his addons download progress can be seen from that point , and now if we put downloads there too , it would be easily noticed
Is download history being handled in a separate bug or will this bug encompass that?
I know many of you care a great deal about this, but this bug is not the right place to discuss various designs and their pros and cons.  Doing so will make it substantially more difficult to track the work, which will make it take longer (which I don't think any of you want).

Please take the discussion to a newsgroup thread, where it belongs:
https://www.mozilla.org/about/forums/#dev-usability
(In reply to comment #149)
I think it's just an issue of how much you download. If you download a lot, then it's easy to have current download progress lost and ultimately that's what a user wants to look for at a glance.

(In reply to comment #150)
> 2) For two or above downloads , this scheme would not be feasible enough for
> the case of netbooks as it takes hell lot of space. Instead a theme with 4~5
> downloads visible under 600px would do great
I think that in the past, we've had issues with long download lists slowing Firefox right down, so in that regard, we'd want this list cleared at the end of each session anyway, thus negating the argument about netbooks and screensize as the average download per session on average, particularly on a netbook will not be anywhere near 4-5 downloads.

(In reply to comment #152)
I wasn't being rude and ignoring you. I was just giving feedback requested by the dev assigned to the bug. Apologies if it caused any offence.
Comment on attachment 511848 [details] [diff] [review]
Updated feature-complete version [NOTE: has hg copies]

This is a first pass.  As I look at this more and more, I'm likely to see things clearer, so don't be surprised if I catch something in later review iterations that I didn't mention at all before.

>+++ b/browser/base/content/browser.xul
> #ifdef WINCE
>              iconsize="small" defaulticonsize="small"
>-             defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,navigator-throbber,fullscreenflex,window-controls"
>+             defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,downloads-button,navigator-throbber,fullscreenflex,window-controls"
> #else
>              iconsize="large"
>-             defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,fullscreenflex,window-controls"
>+             defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,downloads-button,fullscreenflex,window-controls"
> #endif
Nuke the WINCE stuff.  We won't be supporting it, so it can just disappear.

>+++ b/browser/components/downloads/DownloadCommon.jsm
>+const kDownloadsStringBundleUrl =
>+      "chrome://browser/locale/downloads/downloads.properties";
nit: only indent two spaces here

>+/**
>+ * True as soon as initialization begins.
>+ */
>+gInitStarted = false;
var or let here (please declare it)
However, the method this protects could only ever be entered (and running) at once.  As a result, I'd prefer it if this was called gInitialized.

>+  initialize: function DC_initialize() {
global-nit (new files): brace on newline

>+      function DC_setStringFunction(name, value)
dump this into a variable or pull it out globally.  Right now, it's made into a global anyway.

>+++ b/browser/components/downloads/DownloadManagerUI.js
nit: I'd prefer to have this file split into sections like https://mxr.mozilla.org/mozilla-central/source/toolkit/components/downloads/src/nsDownloadManagerUI.js

>+  show: function DMUI_show(aWindowContext, aID, aReason) {
>+    var browser = Services.wm.getMostRecentWindow("navigator:browser");
>+    if (browser) {
>+      browser.DownloadsOverlay.showPopup();
>+    }
I think we'd also want to bring that browser window forward if it isn't the most forward one.

>--- a/toolkit/mozapps/downloads/content/download.xml
>+++ b/browser/components/downloads/download.xml
I think that doing the hg copy here might not be terribly useful and that it might be better to just do an hg add with the new file.  We've made enough changes here that I think preserving history isn't worthwhile.  (Additionally, it will likely make it easier to review.)

>+          <xul:image class="downloadTypeIcon NOT_BLOCKED"
>+                     validate="always"
>                      xbl:inherits="src=image"/>
>+          <xul:image class="downloadTypeIcon blockedIcon BLOCKED"/>
I think it'd be better to have the CSS match on the state attribute of the download, and then hide/unhide these based on that.

>+        <xul:vbox pack="start"
>+                  flex="1">
>+          <xul:hbox align="center"
>+                    flex="1">
>+            <xul:label xbl:inherits="value=target,tooltiptext=target"
>+                       crop="center"
>+                       flex="1"
>+                       class="downloadTarget"/>
>+            <xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
>+                       class="downloadDateTime FINISHED FAILED CANCELED BLOCKED"/>
Likewise, this seems rather odd.  We should be able to style all of these based on download[state="#"] and be OK.

>--- a/toolkit/mozapps/downloads/content/downloads.js
>+++ b/browser/components/downloads/downloads.js
Same here; not sure the hg copy is worthwhile at this point.

>+  initialize: function DO_initialize() {
>+    if (this._initStarted) {
>+      return;
>+    }
>+    this._initStarted = true;
>+
>+    if (!gDownloadManager) {
>+      gDownloadManager = Cc["@mozilla.org/download-manager;1"]
>+                         .getService(nsIDM);
We can just use defineLazyServiceGetter globally for this

>+      gDownloadsView = document.getElementById("downloadsView");
defineLazyGetter globally here

>+  /**
>+   * Initialize the statement without actually opening the database connection.
>+   */
>+  initialize: function DDA_initialize() {
>+    if (!this._statement) {
>+      this._statement = gDownloadManager.DBConnection.createStatement(
>+        "SELECT id, target, name, source, state, startTime, endTime, " +
>+               "referrer, currBytes, maxBytes, " +
>+               "state IN (?1, ?2, ?3, ?4, ?5) isActive, " +
>+               "state IN (?6, ?7, ?8, ?9) isDone " +
>+        "FROM moz_downloads " +
>+        "ORDER BY isDone DESC, isActive ASC, endTime DESC, startTime DESC");
>+    }
We need to use async statements for this (will have to change our call to close too).  This does mean that a bunch of this stuff is going to have to change, sadly.

>--- a/toolkit/mozapps/downloads/content/downloads.xul
>+++ b/browser/components/downloads/downloadsOverlay.xul
likewise, pretty sure there is no value in using hg copy here

>+++ b/browser/components/downloads/tests/browser_basic_functionality.js
global-nit: tests should use http://www.mozilla.org/MPL/boilerplate-1.1/pd-c

This is a good start.  Will look closer in the next iteration.
Attachment #511848 - Flags: feedback-
(In reply to comment #154)

Thank you Shawn for your review! Probably I can spend some time tomorrow to
create a revised patch. Meanwhile, I have a few questions.

> Nuke the WINCE stuff.  We won't be supporting it, so it can just disappear.

Do you mean that "WINCE" will never be defined in supported configurations,
or just that the Download Manager UI isn't applicable on that platform?
Apart from Browser, will Toolkit support Windows CE? I'm asking since I
don't understand if I should remove everything inside any #ifdef WINCE
in "browser.xul" or just do that near the areas I'm touching, and if I
should do that in a separate patch.

> >+++ b/browser/components/downloads/DownloadCommon.jsm

I'm now thinking of defining a "DownloadCommon.strings" lazy getter instead
of using the "DownloadCommonStrings" exported symbol (that, as such, can't
be made lazily-loaded if I understand correctly). This way I could get rid
of the "initialize" method, at least until it's needed again.

"downloads.js" would do something like this:

XPCOMUtils.defineLazyGetter(this, "gStr", function() DownloadCommon.strings);

Another consideration: there aren't many strings in the bundle, we'll probably
need more than one string at a time, and we're already iterating over every
available string name when we need the first one anyway. Does it make sense
to create a lazy getter for each static string, instead of just storing its
value immediately? Is calling into XPCOM the expensive part? When we need the
first string, the "downloads.properties" file has probably already been fully
read and parsed.

> >--- a/toolkit/mozapps/downloads/content/download.xml
> >+++ b/browser/components/downloads/download.xml
> I think that doing the hg copy here might not be terribly useful and that it
> might be better to just do an hg add with the new file.  We've made enough
> changes here that I think preserving history isn't worthwhile.  (Additionally,
> it will likely make it easier to review.)
> >--- a/toolkit/mozapps/downloads/content/downloads.js
> >+++ b/browser/components/downloads/downloads.js
> Same here; not sure the hg copy is worthwhile at this point.

If it's easier for you to review this file as if it was a new file, I think
I can also go one step forward and move many global functions into objects.
Maybe, if not in the next iteration, soon after that.

> We need to use async statements for this (will have to change our call to
> close too).  This does mean that a bunch of this stuff is going to have to
> change, sadly.

Like in the patch you wrote some time ago for bug 438342?

Since we have some more time now to do things in the right way, and you're
reviewing this as if it's new code, I'm also thinking of moving all data
access to a shared JSM module while I rewrite it, so that once the list
of downloads is in memory, it isn't reloaded when the panel is displayed
in other browser windows. Concurrency issues should then be taken into
account, of course.

Another optimization I was thinking about is to allow at most one instance
of the panel to open at a time, and if the user requests to open a panel in
a browser window and we already loaded the downloads list in another one,
just move (import) the XUL nodes across the chrome documents instead of
rebuilding the list. Actually, although faster, that would be a synchronous
operation, thus it might not be appropriate if the list is very large.
We're mostly getting rid of WINCE code across the platform - see bug 614720.
(In reply to comment #154)
> >+            <xul:label xbl:inherits="value=dateTime,tooltiptext=dateTimeTip"
> >+                       class="downloadDateTime FINISHED FAILED CANCELED BLOCKED"/>
> Likewise, this seems rather odd.  We should be able to style all of these
> based on download[state="#"] and be OK.

I started to follow this route but actually the combinations rapidly
exploded. I basically had to add a rule for every element whose visibility
should be controlled by the download state, and I had to apply a new specific
class to those elements that didn't have one already. See for example
".downloadProgress..." below. I stopped when I realized I would have had
to do the same thing for each item in the context menu defined in
"downloadsOverlay.xul".

Is there any specific problem why the current solution, apart oddness? ;-)
The alternative I tried seems more complex, but maybe there's a simpler
alternative I'm missing...

Example of the new, verbose CSS:

.download-state:not(:-moz-any([state="1"], /* Finished */
                              [state="2"], /* Failed   */
                              [state="3"], /* Canceled */
                              [state="6"], /* Blocked  */
                              [state="8"], /* Blocked  */
                              [state="9"]) /* Blocked  */)
               .downloadDateTime,

.download-state:not(:-moz-any([state="-1"],/* Starting */
                              [state="5"]) /* Starting */)
               .downloadProgressNotStarted,

.download-state:not(:-moz-any([state="2"], /* Failed   */
                              [state="3"]) /* Canceled */)
               .downloadProgressStopped,

.download-state:not(:-moz-any([state="0"], /* Downloading */
                              [state="4"]) /* Paused      */)
               .downloadProgressRunning,

.download-state:not(:-moz-any([state="2"], /* Failed   */
                              [state="3"]) /* Canceled */)
               .downloadProgressStopped
{
  display: none;
}
Meanwhile, here is an intermediate version of the patch without the hg copies
on some of the files, that should be easier to review. I'm going to make
relevant changes to it, probably during the week-end, but if you want you
can now take a look at it without the hg copies getting in the way.

In particular I'd like to separate the various parts and modules in such
a way that they can be easily moved to Toolkit to improve the "classic"
Download Manager, for example using asynchronous statements for the
database queries. If this works out well, we might be able to replace
Toolkit's Download Manager with this improved code, while keeping it in
a detached window for applications that want to use it this way, like it
was done for the Add-ons Manager. This would mean more work now, but
fewer code to maintain later.
Attachment #511848 - Attachment is obsolete: true
Attachment #520065 - Flags: feedback?(sdwilsh)
(In reply to comment #154)
> >+++ b/browser/components/downloads/tests/browser_basic_functionality.js
> global-nit: tests should use http://www.mozilla.org/MPL/boilerplate-1.1/pd-c

nit: in this case, these are tests I copied from existing files, thus
I couldn't just change the license. Maybe you know if all test code whose
copyright is owned by the Mozilla Corporation is being dedicated to the
Public Domain using CC0?
Blocks: 639215
(In reply to comment #155)
> Do you mean that "WINCE" will never be defined in supported configurations,
> or just that the Download Manager UI isn't applicable on that platform?
> Apart from Browser, will Toolkit support Windows CE? I'm asking since I
> don't understand if I should remove everything inside any #ifdef WINCE
> in "browser.xul" or just do that near the areas I'm touching, and if I
> should do that in a separate patch.
I mean just remove it when you are touching it.  I suppose someone will come along and remove it all at some point, but there is no need for us to maintain that code anymore.

> Another consideration: there aren't many strings in the bundle, we'll probably
> need more than one string at a time, and we're already iterating over every
> available string name when we need the first one anyway. Does it make sense
> to create a lazy getter for each static string, instead of just storing its
> value immediately? Is calling into XPCOM the expensive part? When we need the
> first string, the "downloads.properties" file has probably already been fully
> read and parsed.
In this module, we probably don't need to make a lazy getter for each string.  The code you grabbed this from had a bunch more.  I'm fine with either approach in this case.

> If it's easier for you to review this file as if it was a new file, I think
> I can also go one step forward and move many global functions into objects.
> Maybe, if not in the next iteration, soon after that.
Works for me!

> Like in the patch you wrote some time ago for bug 438342?
Correct, although we may need to do some changes to that.

> Since we have some more time now to do things in the right way, and you're
> reviewing this as if it's new code, I'm also thinking of moving all data
> access to a shared JSM module while I rewrite it, so that once the list
> of downloads is in memory, it isn't reloaded when the panel is displayed
> in other browser windows. Concurrency issues should then be taken into
> account, of course.
This is a good idea.

> Another optimization I was thinking about is to allow at most one instance
> of the panel to open at a time, and if the user requests to open a panel in
> a browser window and we already loaded the downloads list in another one,
> just move (import) the XUL nodes across the chrome documents instead of
> rebuilding the list. Actually, although faster, that would be a synchronous
> operation, thus it might not be appropriate if the list is very large.
Not sure if importing the nodes is needed, but the panel would close when you click elsewhere anyway, right?

(In reply to comment #157)
> Is there any specific problem why the current solution, apart oddness? ;-)
I guess I can't wrap my head around it (even if it works).  It's as if we are saying the download is FINISHED, FAILED, CANCELED, and BLOCKED all at the same time.

> Example of the new, verbose CSS:
That doesn't seem too terribly verbose, and isn't hard to follow.

(In reply to comment #159)
> nit: in this case, these are tests I copied from existing files, thus
> I couldn't just change the license. Maybe you know if all test code whose
> copyright is owned by the Mozilla Corporation is being dedicated to the
> Public Domain using CC0?
Yes, anything that is owned by Mozilla is OK to change.
I'll try to get this feedback request done by Monday.  It might happen today even.  Sorry for the delay.
(In reply to comment #154)
> We need to use async statements for this (will have to change our call to close
> too).  This does mean that a bunch of this stuff is going to have to change,
> sadly.

The Download Manager used to build the list of downloads with the synchronous
storage API, but it read the results asynchronously, some rows at a time,
waiting some time between each set of rows. This effectively limited the
rate at which results were processed. The time interval between reads was
smaller for the first few items in the list, so that building the list was
initially faster, and then slowed down.

Using the asynchronous API, instead, we can't control the rate at which
results come in. Do you think we should generate the download list items
as soon as we get the results, or that we should buffer the results so
that we can still throttle at least the creation of the XUL nodes?
(In reply to comment #162)
> Using the asynchronous API, instead, we can't control the rate at which
> results come in.
The rate can still be slowed down by querying for a certain number of items then waiting then continuing with a new query.
(In reply to comment #163)
> The rate can still be slowed down by querying for a certain number of items
> then waiting then continuing with a new query.

Good idea, I can implement it if slowing down the query is actually useful.

With this method, I'm still afraid of getting the same download item twice
if I execute multiple LIMITed queries and a download is removed in the
meantime, even if I sort the results by start time. But, probably, this
is an edge case and I can just refresh the entire list if I'm notified
of such an event while I'm building the list.
(In reply to comment #162)
> The Download Manager used to build the list of downloads with the synchronous
> storage API, but it read the results asynchronously, some rows at a time,
> waiting some time between each set of rows. This effectively limited the
> rate at which results were processed. The time interval between reads was
> smaller for the first few items in the list, so that building the list was
> initially faster, and then slowed down.
It was still reading the results synchronously, just in chunks.

> Using the asynchronous API, instead, we can't control the rate at which
> results come in. Do you think we should generate the download list items
> as soon as we get the results, or that we should buffer the results so
> that we can still throttle at least the creation of the XUL nodes?
We might have to try a few approaches here, actually.  Probably the first option is to dump the results in an array when we get them, and then build the DOM.
This gets looked at Friday by me (either the current patch, or something new).
With all this talk of switching from synchronous reads to asynchronous reads, will this fix bug 610775 and bug 610776?
(In reply to comment #166)
> This gets looked at Friday by me (either the current patch, or something new).

And now for something completely different :-)
Attachment #520065 - Attachment is obsolete: true
Attachment #526282 - Flags: feedback?(sdwilsh)
Attachment #520065 - Flags: feedback?(sdwilsh)
(In reply to comment #167)
> With all this talk of switching from synchronous reads to asynchronous reads,
> will this fix bug 610775 and bug 610776?

No, sorry, download performance is different from user interface performance
and responsiveness, that these changes will improve.
Comment on attachment 526282 [details] [diff] [review]
Work in progress, with separation of model, view, and controller [NOTE: has hg copies]

>+++ b/browser/components/downloads/Makefile.in
> ifdef ENABLE_TESTS
>-DIRS += test
>+DIRS += tests
> endif
You actually want to call the directory test and not tests.  I know we are inconsistent in the tree, but "test" is the right one.

>+++ b/browser/components/downloads/downloads.js
>+/**
>+ * Handles the Download Manager user interface and data access.
>+ *
>+ * This module includes the following classes and global objects:
This whole big comment is awesome.  My only comment on it so far is that "class" isn't really what you want.  You say they are global objects, and that's what they really are; just objects.  I wouldn't call them anything, and just say "DownloadsOverlay\n".

>+ * class DownloadsOverlay
>+ *       Handles the panel interface defined in "downloadsOverlay.xul".
I think this is better called DownloadsUI or DownloadsPanel.  Thoughts?

>+  /**
>+   * Updates the time that gets shown for completed download items.
>+   */
>+  updateTime: function DVI_updateTime()
So, this is basically the same as downloads.js for the toolkit UI.  Can you move this to DownloadUtils.jsm (in a patch that would be applied before this one to minimize patch sizes)?

>+++ b/toolkit/components/downloads/src/Makefile.in
> ifndef MOZ_SUITE
> # XXX - Until Suite builds off XULRunner we can't guarantee our implementation
> # of nsIDownloadManagerUI overrides toolkit's.
>+# This is also disabled when building the "browser" application since it also
>+# has its own implementation of nsIDownloadManagerUI.
>+ifneq (browser,$(MOZ_BUILD_APP))
> EXTRA_COMPONENTS = \
>   nsDownloadManagerUI.js \
>   nsDownloadManagerUI.manifest \
>   $(NULL)
> endif
>+endif
This really sucks and means that we run no tests on the toolkit UI, yeah?  We need to figure out how to resolve this in a better way...

This is probably going to take me the better part of a day to review when it's all ready.
Attachment #526282 - Flags: feedback?(sdwilsh) → feedback+
May I ask you to put your button _before_ bookmarks-menu-button-container for now? Since that crazy bookmarks button magically moves to the toolbar, it's easier for the user to notice the movement if it's the last button on the right.
This is planned to change, but since I have no schedule I think for now it's better to avoid problems.

Also, you don't need that utils.js file imported in all browser-chrome tests, just rename it to head.js and it will automagically imported in each test.

And the change in nsBrowserGlue seems bogus, you should not hijack another migration step, just add a new one, otherwise I feel like that will cause you some headaches in future.

I just took a quick look at the patch for personal interest, I'm not a downloads peer, but if you want more eyes on this feel free to f? me.
(In reply to comment #170)
> >+ * class DownloadsOverlay
> >+ *       Handles the panel interface defined in "downloadsOverlay.xul".
> I think this is better called DownloadsUI or DownloadsPanel.  Thoughts?

It's just my habit to call the object that contains the "entry point"
functions (called by code outside the overlay) with the same name of
the JavaScript file, but DownloadsPanel is fine for me since that part
of the code is focused on opening and closing the panel itself.

> >+  /**
> >+   * Updates the time that gets shown for completed download items.
> >+   */
> >+  updateTime: function DVI_updateTime()
> So, this is basically the same as downloads.js for the toolkit UI.  Can you
> move this to DownloadUtils.jsm (in a patch that would be applied before this
> one to minimize patch sizes)?

Now that you say it, it fits there perfectly :-)

> >+++ b/toolkit/components/downloads/src/Makefile.in
> > ifndef MOZ_SUITE
> > # XXX - Until Suite builds off XULRunner we can't guarantee our implementation
> > # of nsIDownloadManagerUI overrides toolkit's.
> >+# This is also disabled when building the "browser" application since it also
> >+# has its own implementation of nsIDownloadManagerUI.
> >+ifneq (browser,$(MOZ_BUILD_APP))
> > EXTRA_COMPONENTS = \
> >   nsDownloadManagerUI.js \
> >   nsDownloadManagerUI.manifest \
> >   $(NULL)
> > endif
> >+endif
> This really sucks and means that we run no tests on the toolkit UI, yeah?  We
> need to figure out how to resolve this in a better way...

Ah, I didn't realize that this killed test coverage for the "classic" UI
on mozilla-central automated builds... but now that I think about it, if
mozilla-central automation only builds Firefox and the classic UI isn't
included in Firefox anymore, what can we do? Can we run tests without
including the unused "content" files in the final product?

This is something we should think about even if we are brave enough to
replace part of the Toolkit's UI implementation with the new one :-)
I've seen that the Add-ons Manager runs tests on mozilla-central for
a windowed version that isn't actually used in Firefox, right?

By the way, isn't "mozapps/downloads" the right place for the
"nsDownloadManagerUI.js" module, rather than "components/downloads"?

> This is probably going to take me the better part of a day to review when it's
> all ready.

I think so! And I'll need at least one more day of work to make things
shine, meaning that new patches might be ready sometime during next week.
(In reply to comment #171)
> May I ask you to put your button _before_ bookmarks-menu-button-container for
> now? Since that crazy bookmarks button magically moves to the toolbar, it's
> easier for the user to notice the movement if it's the last button on the
> right.

Of course, I can change this for now. In the final version, I'm not sure if
the panel's anchor will end up as toolbar button, rather than a notification
icon like the one that is shown for add-on downloads, to make the experience
consistent. Input from the UX team is welcome here!

> Also, you don't need that utils.js file imported in all browser-chrome tests,
> just rename it to head.js and it will automagically imported in each test.

Excellent :-)

> And the change in nsBrowserGlue seems bogus, you should not hijack another
> migration step, just add a new one, otherwise I feel like that will cause you
> some headaches in future.

Good catch, actually the change made sense in the version from one year ago.
Then I merged my patch on top of the latest trunk, messed up that part, and
then forgot about it :-) Thanks for pointing it out!

> I just took a quick look at the patch for personal interest, I'm not a
> downloads peer, but if you want more eyes on this feel free to f? me.

Thank you very much Marco! You needn't ask a second time :-)

The model - view - controller implementation is inspired by the Places
front-end code, and since I understand you worked in that area, I think
you may have valuable suggestions in this regard.
Attachment #526282 - Flags: feedback?(mak77)
(In reply to comment #173)
> The model - view - controller implementation is inspired by the Places
> front-end code

NOW I'm scared! (just kidding...)
Blocks: PBnGen
(In reply to comment #170)
> This really sucks and means that we run no tests on the toolkit UI, yeah?  We
> need to figure out how to resolve this in a better way...

SeaMonkey's nsIDownloadManagerUI implementation has a pref to switch between the toolkit and suite UI, maybe Firefox wants to do that as well so at least the UI itself can be tested by setting that pref?
(In reply to comment #175)
> SeaMonkey's nsIDownloadManagerUI implementation has a pref to switch between
> the toolkit and suite UI, maybe Firefox wants to do that as well so at least
> the UI itself can be tested by setting that pref?
We still end up not testing the component that we ship in toolkit for displaying the UI.
(In reply to comment #172)
> I've seen that the Add-ons Manager runs tests on mozilla-central for
> a windowed version that isn't actually used in Firefox, right?

Yes, but I don't think that will help you here. The addons manager tests are just copied to a second directory (so they're in tests/browser/ and tests/browser-window/). The only difference is that the tests in /browser-window/ are run in a window, which is already supported by the code shipped in Firefox (it's just not exposed in Firefox's menus).
Attached file feedback, round 1 (obsolete) —
Feel free to skip answering each single line of feedback, since it would take double the size of this txt to do that :)
It's possible I missed some reasoning behind some of the choices, in such a case just ignore me, and I'll check the next version. I moved quickly through the View since it still looks a WIP with lots of TODOs, will check it better at the next iteration.
Is there a build with this patch available?  I'd like to test how the changes to the interface look like in RTL mode.
(In reply to comment #176)
> (In reply to comment #175)
> > SeaMonkey's nsIDownloadManagerUI implementation has a pref to switch between
> > the toolkit and suite UI, maybe Firefox wants to do that as well so at least
> > the UI itself can be tested by setting that pref?
> We still end up not testing the component that we ship in toolkit for
> displaying the UI.

Right, that's why I said "at least the UI".
(In reply to comment #178)
> Feel free to skip answering each single line of feedback, since it would take
> double the size of this txt to do that :)

Thanks - you know I would be tempted :-)

You'll find an answer to many comments in the next patch, except of course
for those that refer to code that has already disappeared (refactoring like
unifying DownloadsData was already underway). I've to say that I find this
feedback very useful, especially the JavaScript tips, even if on code that
will not be present in the next iteration.

There are still a few minor items, mostly related to style, for which I'm
not completely sure how to proceed. It would be better if we can sort out
these points early while I'm still writing the code:

* The main JavaScript file is included from an overlay of the browser window,
  and in the future some objects might even be moved elsewhere, thus I'd like
  to avoid global namespace pollution, leaving only the "Downloads..."
  objects (with only a few necessary exceptions). This is why
  "minItemCountForPopup" is a property, for example, which I actually
  considered calling "kMinItemCountForPopup". It can become a "const",
  but at the cost of being in the global namespace. Personally I'd prefer
  to keep it as a property, and even change other "const" to properties,
  but if there is a different recommendation I'm fine either way.

* While reviewing the initialization and termination, I realized that the
  "initialize" and "terminate" methods are not usually called from the
  outside (only test code does that), but they have a clearly defined
  purpose and interface: "initialize" allows preloading the download list
  in the background without opening the panel, while "terminate" frees
  the associated resources until they're needed again. Regardless of
  the name of the methods, which might be improved, should we mark them
  as "private" on the rationale that they're called only by test code?

* I guess methods and properties that are called or accessed by other
  objects, even in the same file, shouldn't be marked as "private".

* I'm accustomed to use "Iterator()" in for loops because it filters out
  properties added to "Object.prototype", for example by extensions that
  don't behave in the right way. Do we care making at least newly written
  front-end code robust to this eventuality?

On a final note, everything related to user interface styling is not only
not final, but also very different from the wanted appearance. I'd like to
focus on one thing at a time, thus I'll not work on improving CSS files for
some more time. However, I'll remember to take your suggestions into account
for the new style sheets at the right time.

Test code is mostly a copy from Toolkit's (it's not an "hg copy" anymore
because it confused things) and I'm not sure if I should spend as much time
to refactor it as I'm spending on production code.
(In reply to comment #179)
> Is there a build with this patch available?  I'd like to test how the changes
> to the interface look like in RTL mode.

User interface styling is far from final, but if you want to provide early
feedback you're welcome to download this intermediate tryserver build:

http://ftp.mozilla.org/pub/mozilla.org/firefox/tryserver-builds/old/paolo%2Emozmail%40amadzone%2Eorg-ca777069fd10/

Note that this build might contain a few minor bugs (I've seen that the panel
doesn't always open automatically when it should, for example).

Also note that this build will expire and disappear very shortly.
(In reply to comment #183)
> (In reply to comment #179)
> > Is there a build with this patch available?  I'd like to test how the changes
> > to the interface look like in RTL mode.
> 
> User interface styling is far from final, but if you want to provide early
> feedback you're welcome to download this intermediate tryserver build:
> 
> http://ftp.mozilla.org/pub/mozilla.org/firefox/tryserver-builds/old/paolo%2Emozmail%40amadzone%2Eorg-ca777069fd10/
> 
> Note that this build might contain a few minor bugs (I've seen that the panel
> doesn't always open automatically when it should, for example).
> 
> Also note that this build will expire and disappear very shortly.

Paolo, I tried this build in RTL mode, and it was really, really, *really* good!  :-)

I'm honestly surprised, I expected there to be RTL problems somewhere but I couldn't find any.  Keep up the good work!  :-)
Whiteboard: [strings] → [strings][needs accessibility qa]
(In reply to comment #184)
> Paolo, I tried this build in RTL mode, and it was really, really, *really*
> good!  :-)
> 
> I'm honestly surprised, I expected there to be RTL problems somewhere but I
> couldn't find any.  Keep up the good work!  :-)

Merit goes to those who wrote the original Download Manager and former Add-ons
Manager styles, which I mostly just copied. Thanks for the encouragement in
any case, I appreciate it very much!

And this reminds me to test the right-to-left layout with the Force RTL add-on
when the time comes to update the styles to match those now in Firefox 4 :-)
Comment on attachment 526902 [details]
feedback, round 1

I've addressed most of the feedback comments, thank you Marco for your help!

Some minor tweaks are still pending, thus I won't be able to attach an
updated patch before Thursday. Meanwhile, I've distilled those comments
that are not handled in the code yet:

> >+Cu.import("resource://gre/modules/DownloadCommon.jsm");
> 
> DownloadCommon is a browser module, so this should be resource://app/modules/...

Do I have to change something in "Makefile.in" if I make this modification?

> >+  onDrop: function DV_onDrop(aEvent)
> 
> Does this handle the uri-list case correctly?

I've not checked, but I guess not, if the current Download Manager doesn't.
This might be a follow-up if it's deemed useful. And, in any case, I think
the drop action should be handled by the download indicator in the final
version.

> >+    if (multiCommand) {
> >+      multiCommand.after.call(null, context); 
> >+    }
> 
> couldn't .before and .after handle an internal _context? and could not
> doCommand detect if it's inside before and after to figure out if this
> is a multiple command?

Not sure what you're asking...

> Any reason this menupopup is defined inside the panel rather than
> directly in the popupset?

I remember there were interaction problems when having two popups open if one
wasn't a child of the other. I've not re-tested it for almost a year, though.

> This is interesting, does the panel allow resizing? The problem is that
> so far tries to make the panel resizeable failed due to some platform
> resize bug. So I'm mostly asking if resizeability was taken into account
> (it could absolutely be a follow-up, though)

The styles used for the content should work correctly for any panel size,
if a minimum width is enforced.

> This is losing the attention flashing compared to the toolkit
> implementation, I guess this could be wanted for the first
> implementation but some sort of attention is planned for the
> button itself?

Yes, the button will handle attention and the progress indicator.
Attachment #526902 - Attachment is obsolete: true
(In reply to comment #186)
> > >+Cu.import("resource://gre/modules/DownloadCommon.jsm");
> > 
> > DownloadCommon is a browser module, so this should be resource://app/modules/...
> 
> Do I have to change something in "Makefile.in" if I make this modification?

no there is no change required, as far as the Makefile.in is in browser/ this is a app module.

> > >+  onDrop: function DV_onDrop(aEvent)
> > 
> > Does this handle the uri-list case correctly?
> 
> I've not checked, but I guess not, if the current Download Manager doesn't.
> This might be a follow-up if it's deemed useful. And, in any case, I think
> the drop action should be handled by the download indicator in the final
> version.

Sure, if it's unsupported by the current manager, it's a follow-up (maybe also already filed)

> > >+    if (multiCommand) {
> > >+      multiCommand.after.call(null, context); 
> > >+    }
> > 
> > couldn't .before and .after handle an internal _context? and could not
> > doCommand detect if it's inside before and after to figure out if this
> > is a multiple command?
> 
> Not sure what you're asking...

mostly if this really needs .before and .after methods and wrapping variables (see context = {}) and could not be done with a callback, like .multipleCommandHandler(function () {do_stuff_here} );

> > This is interesting, does the panel allow resizing? The problem is that
> > so far tries to make the panel resizeable failed due to some platform
> > resize bug. So I'm mostly asking if resizeability was taken into account
> > (it could absolutely be a follow-up, though)
> 
> The styles used for the content should work correctly for any panel size,
> if a minimum width is enforced.

yes, I'm guessing if it works at all in reality though (see bug 652115)
(In reply to comment #187)
> > > >+    if (multiCommand) {
> > > >+      multiCommand.after.call(null, context); 
> > > >+    }
> > > 
> > > couldn't .before and .after handle an internal _context? and could not
> > > doCommand detect if it's inside before and after to figure out if this
> > > is a multiple command?
> > 
> > Not sure what you're asking...
> 
> mostly if this really needs .before and .after methods and wrapping variables
> (see context = {}) and could not be done with a callback, like
> .multipleCommandHandler(function () {do_stuff_here} );

Yes, we could pass an iterator as an argument to the "multiple" version of
the command, then iterate on the items with "for (let item in aItems)", or
use more advanced array comprehensions. The function will just access
"item" instead of using "this". We still need to know in advance which
commands want to handle multiple items in this way.

> > > This is interesting, does the panel allow resizing? The problem is that
> > > so far tries to make the panel resizeable failed due to some platform
> > > resize bug. So I'm mostly asking if resizeability was taken into account
> > > (it could absolutely be a follow-up, though)
> > 
> > The styles used for the content should work correctly for any panel size,
> > if a minimum width is enforced.
> 
> yes, I'm guessing if it works at all in reality though (see bug 652115)

Right, what I'm saying is that once bug 652115 is fixed there should be no
showstoppers due to the way the styles in the panel are written.
(In reply to comment #188)
> Right, what I'm saying is that once bug 652115 is fixed there should be no
> showstoppers due to the way the styles in the panel are written.

bug 652115 is a showstopper by itself if the first implementation wants to be resizeable, that's why I'm asking. Indeed in such a case that bug should be reprioritized and get someone assigned to it.
Depends on: 653261
Here is an updated patch with all comments addressed. Files located directly
under "browser/components/downloads" are ready for a full coding style review,
though they will still be subject to incremental changes to reflect future
user experience iterations. Files in other folders, including "browser/themes"
and "browser/components/downloads/tests", will probably undergo major changes.

I've used the "feedback" flag since I'm requesting a full review from Shawn
only for a portion of the work-in-progress. Marco, if you want to see if
I've interpreted correctly your previous feedback, you're really welcome!
Attachment #526282 - Attachment is obsolete: true
Attachment #528720 - Flags: feedback?(sdwilsh)
Attachment #528720 - Flags: feedback?(mak77)
I went through the bug history to see if I could find comments that still
apply to the current version. Some might be more relevant, some are just
food for thought or may become follow-ups. This list is not sorted.

* Figure out how automated tests in mozilla-central builds could be executed
  for a Toolkit component that we don't use or include in Firefox.

* The openURL global function in Firefox 4 doesn't open a new tab and
  doesn't give any visual feedback if the target page is not available,
  for example because there is no network connection. This happens when
  the "open download page" link is clicked.

* The logic of _addOrMoveElementToTop and _addOrMoveElementToBottom might
  not be clear enough, this might be addressed by the code review.

* The "open" button should be disabled when the file doesn't exist.

* Manual tests for toolbar migration code are listed in comment 85.

* When there are many downloads, the panel expands all the way to the
  bottom of the screen, and a scrollbar appears, correctly. However,
  on Windows XP, the panel overlaps with the taskbar and the taskbar
  is on top of it, effectively hiding the "Downloads History" button.

* Do we want the download panel to be "detachable"? If, by clicking on a
  button or icon in the panel, you can open the standalone Download
  Manager, then you have a way to keep an eye on every single item of
  your current downloads. I'm not sure if we want to continue to support
  this use case.

* The Downloads view in the Library window does not allow to locate the
  target file, even if the file was downloaded successfully.

* Share the "open download" function, or at least its strings, with Toolkit.

* Behavior when a download starts and no browser window is open (comment 87).

* Behavior when a download finishes and no browser window is open. Steps
  to reproduce are written in comment 93.

* Share the new data access and user interface code with Toolkit.

* Isn't "mozapps/downloads" the right place for the "nsDownloadManagerUI.js"
  module, rather than "components/downloads"?

* Minor coding style questions (comment 182).

* Proceed with updating tests, rename "tests" to "test", migrate more tests.
(In reply to comment #191)
> * Do we want the download panel to be "detachable"? If, by clicking on a
>   button or icon in the panel, you can open the standalone Download
>   Manager, then you have a way to keep an eye on every single item of
>   your current downloads. I'm not sure if we want to continue to support
>   this use case.
I suspect we do not want it to be detachable.

> * The Downloads view in the Library window does not allow to locate the
>   target file, even if the file was downloaded successfully.
We can patch that.  I even think mmmulani did a patch for that, so you might want to poke him (or at least adds it to the API so we can store it as an annotation).

> * Behavior when a download starts and no browser window is open (comment 87).
This only applies on OS X FWIW.

> * Behavior when a download finishes and no browser window is open. Steps
>   to reproduce are written in comment 93.
Same here.

> * Isn't "mozapps/downloads" the right place for the "nsDownloadManagerUI.js"
>   module, rather than "components/downloads"?
Yes it is.  Feel free to move it there (but file a different bug to do so please!).

I will try to look at this tomorrow, but if not Friday for sure!
OK, so this is going to happen Friday and not today.  If you want to me give review on parts of it, I encourage you to split those parts out into a different patch and request review on it.  This makes things easier for bookkeeping, and then I don't need to look at it again (even accidentally) in future iterations of the mega patch, which results in a faster review turn around time for you! :D
(In reply to comment #193)
> OK, so this is going to happen Friday and not today.  If you want to me give
> review on parts of it, I encourage you to split those parts out into a
> different patch and request review on it.  This makes things easier for
> bookkeeping, and then I don't need to look at it again (even accidentally) in
> future iterations of the mega patch, which results in a faster review turn
> around time for you! :D

The point is that even those parts on which I'm requesting a more thorough
review (for example, main XUL files and non-skin CSS) are probably going to
change slightly in the next iteration, to reflect changes in the skin, and
those changes would need to be examined together in any case...

Since, if this feedback round on the JavaScript is OK, I'm going to begin skin
work and request full review on everything in the next iteration, which is
going to happen in days and not months from now, maybe keeping one patch is
actually simpler? You can do a thorough review on the main JavaScript in any
case tomorrow, since next week you'll still remember what you looked at :-)
Comment on attachment 528720 [details] [diff] [review]
Version with "components/downloads" ready for review

Review of attachment 528720 [details] [diff] [review]:

Some comments on tests.

You have not yet renamed utils.js to head.js in tests, and removed the useless import code from them.

::: browser/components/downloads/tests/browser_basic_functionality.js
@@ +1,3 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+

see the comments on the other test, most apply here as well, so I won't repeat them :)

::: browser/components/downloads/tests/browser_delete_key_removes.js
@@ +14,5 @@
+{
+  var dmFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
+  dmFile.append("dm-ui-test.file");
+  dmFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
+  var testPath = Services.io.newFileURI(dmFile).spec;

NetUtil.newURI manages also fileURI transparently iirc.

@@ +67,5 @@
+    var richlistbox = document.getElementById("downloadsView");
+    let stmt = dm.DBConnection
+                 .createStatement("SELECT COUNT(*) FROM moz_downloads");
+    try {
+      stmt.executeStep();

check with ok() this call?

@@ +98,5 @@
+
+  function runTests() {
+    // Now we can run our tests
+    for each (let t in testFuncs)
+      t();

nit: For code sanity, don't use for each on arrays. In this case it doesn't matter since this array is not going into the wild, but better not showing bad habits :) use testFuncs.forEach instead.
Also, maybe you could want to start managing these tests as async, even if they are currently synchronous in future they could change (like deleting an entry could become async) and making them fake async from the beginning would speed up fixing them. So this could rather be a runNextTest.

@@ +104,5 @@
+    dmFile.remove(false);
+    DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted;
+
+    // Unload the panel, discarding the current test data.
+    DownloadsPanel.terminate();

why not setCleanState? I suspect you want to cleanup after the test to avoid next tests to see leftover downloads, ideally you should do that in a function registered through registerCleanupFunction.

@@ +110,5 @@
+  }
+
+  // Hook to know when the test data has been loaded
+  var originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
+  DownloadsPanel.onViewLoadCompleted = function() {

nit: this is one of the reasons in future you could want an addObserver and removeObserver in the view and support for multiple observers.

@@ +112,5 @@
+  // Hook to know when the test data has been loaded
+  var originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
+  DownloadsPanel.onViewLoadCompleted = function() {
+    originalOnViewLoadCompleted.apply(this);
+    waitForFocus(function() setTimeout(runTests, 0));

waitForFocus already setTimeout(0), so this call seems useless.

@@ +117,5 @@
+  };
+
+  // Show the Download Manager UI
+  DownloadsPanel.showPanel();
+  waitForExplicitFinish();

nit: I suggest specifying this as first command in test() so that it's immediately clear the test is async.

::: browser/components/downloads/tests/utils.js
@@ +57,5 @@
+      let ios = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService);
+      return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
+                                            ios.newURI(aObj, null, null);
+    }

NetUtil.newURI does all of this this for you IIRC.

@@ +68,5 @@
+        let rnum = Math.floor(Math.random() * chars.length);
+        randomstring += chars.substring(rnum, rnum+1);
+      }
+      return randomstring;
+    }

A neat trick:
function randomString()
  Math.random().toString(36).replace(/^.*\./, '');

notice random is random, so if you need this to also be unique, add an external counter, increment and append it.

@@ +77,5 @@
+    persist.persistFlags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
+                           nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
+                           nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+    let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                 getService(Ci.nsIProperties);

Services.dirsvc

@@ +110,5 @@
+    "INSERT INTO moz_downloads (name, source, target, startTime, endTime, " +
+      "state, currBytes, maxBytes, preferredAction, autoResume) " +
+    "VALUES (:name, :source, :target, :startTime, :endTime, :state, " +
+      ":currBytes, :maxBytes, :preferredAction, :autoResume)");
+  for each (let dl in DownloadData) {

for code evangelization, don't use for each on arrays, use .forEach

@@ +115,5 @@
+    for (let prop in dl) {
+      stmt.params[prop] = dl[prop];
+    }
+
+    stmt.execute();

just for sanity, .reset() after executing

@@ +117,5 @@
+    }
+
+    stmt.execute();
+  }
+  stmt.finalize();

put into a finally
(In reply to comment #195)
> +    stmt.execute();
> 
> just for sanity, .reset() after executing
execute calls reset (API guarantee), so calling reset is not needed.
(In reply to comment #196)
> execute calls reset (API guarantee), so calling reset is not needed.

my fault, I thought it was only for asyncExecute!
Comment on attachment 528720 [details] [diff] [review]
Version with "components/downloads" ready for review

Review of attachment 528720 [details] [diff] [review]:

Plus all of mak's comments, this looks good.

::: browser/components/downloads/download.xml
@@ +25,5 @@
+#   Ben Goodger <ben@bengoodger.com> (v2.0) 
+#   Blake Ross <blakeross@telocity.com>
+#   Shawn Wilsher <me@shawnwilsher.com> (v3.0)
+#   Edward Lee <edward.lee@engineering.uiuc.edu>
+#   Paolo Amadini <http://www.amadzone.org/>

(v4.0) for you, yeah?

::: browser/components/downloads/downloads.js
@@ +115,5 @@
+  kPanelHidden: 1,
+  /** The panel will be shown as soon as possible. */
+  kPanelShowing: 2,
+  /** The panel is open, though download data might still be loading. */
+  kPanelShown: 3,

if you actually want this to be constants, you should implement them as getters.

@@ +207,5 @@
+  /**
+   * Indicates whether the panel is shown or will be shown.
+   */
+  get isPanelShowing() this._panelState == this.kPanelShowing ||
+                       this._panelState == this.kPanelShown,

Because this spans two lines here, I'd prefer it if you didn't use the magic here and used braces and all the normal JS stuff :)

@@ +339,5 @@
+   * element was already in the list, it is moved to the appropriate position.
+   *
+   * @param aElement
+   *        XUL element associated with the download item.
+   *

global-nit: no newline here

@@ +352,5 @@
+    this.richListBox.insertBefore(aElement, aDataItem.done
+                                            ? this.richListBox.firstChild
+                                            : !aDataItem.inProgress
+                                            ? this.firstElementNotDone
+                                            : this.firstElementInProgress);

This is all very complicated and hard to follow.  I suspect you can improve this by using a temporary variable or two.  You do this in a few places, so this comment applies there as well.

@@ +1702,5 @@
+                   , nsIDM.DOWNLOAD_QUEUED
+                   , nsIDM.DOWNLOAD_DOWNLOADING
+                   , nsIDM.DOWNLOAD_PAUSED
+                   , nsIDM.DOWNLOAD_SCANNING
+                   ].indexOf(this.state) >= 0,

Trailing commas are legal in arrays, and I'd rather see that here.  Also, since this spans multiple lines, use braces and a return statement please.

@@ +1717,5 @@
+  get done() [ nsIDM.DOWNLOAD_FINISHED
+             , nsIDM.DOWNLOAD_BLOCKED_PARENTAL
+             , nsIDM.DOWNLOAD_BLOCKED_POLICY
+             , nsIDM.DOWNLOAD_DIRTY
+             ].indexOf(this.state) >= 0,

same here

@@ +1729,5 @@
+   * Indicates whether the download stopped because of an error, and can be
+   * resumed manually.
+   */
+  get canRetry() this.state == nsIDM.DOWNLOAD_CANCELED ||
+                 this.state == nsIDM.DOWNLOAD_FAILED,

and here (going to stop commenting on this, but it applies everywhere)

::: browser/components/downloads/tests/browser_basic_functionality.js
@@ +13,5 @@
+ */
+function test()
+{
+  var dmFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
+  dmFile.append("dm-ui-test.file");

I can one-up mak's suggestion: FileUtils.getFile("TmpD", ["dm-ui-test.file"]);

::: browser/components/downloads/tests/utils.js
@@ +57,5 @@
+      let ios = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService);
+      return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
+                                            ios.newURI(aObj, null, null);
+    }

As mak suspected, this whole method can be nuked and you can just use NetUtil.newURI everywhere.  NetUtil is already pulled into browser.js too I think, so you don't even have to import it.

::: browser/components/nsBrowserGlue.js
@@ +1039,5 @@
     box.persistence = -1; // Until user closes it
   },
 
   _migrateUI: function BG__migrateUI() {
+    const UI_VERSION = 6;

Amusing that this might coincide with the browser version...
Attachment #528720 - Flags: feedback?(sdwilsh) → feedback+
(In reply to comment #197)
> my fault, I thought it was only for asyncExecute!
Nope, just executeStep needs reset called afterwards.
Marco, Shawn, many thanks for the detailed reviews!

Actually, right now I was rewriting the entire test suite using the
generator-based asynchronous browser-chrome test runner of Toolkit.
Everything is much shorter and neater now. Marco, sorry if it seemed
I forgot to address your comments. In fact, I've already implemented
most of your old and new suggestions during my rewrite!

I'll implement some tips like using NetUtils now, and I'll wrap up the
new patch with the test suite for you to see.
Shawn, Marco, if you want to take a look, in this version the tests in
the "browser/components/downloads/test" folder are reimplemented. Note
that this patch is also regenerated upon a recent trunk revision.

The only thing I'd want to draw your attention to, before you look at the
patch, is that in the generator-iterator world I have to use an iteration
whenever I want some tasks to be delegated to an inner generator. Inner
functions cannot be used directly, by the way this is why you'll never
see "myArray.forEach(...)" but only "for ... in Iterator(myArray)".

Iteration calls for subroutines look like this:

  for (yy in gen_example("Parameter")) yield;

Apart for that, control flow is similar to a normal synchronous piece of
code (including iterations and flow of finally statements), and test
functions can be read and followed more or less in the same way as normal
functions. The "yield" causes the test runner to wait for the next event.

(In reply to comment #198)
> NetUtil is already pulled into browser.js too I think, so you don't even
> have to import it.

Now, I have to import it since I'm using it in the global scope.
Attachment #528720 - Attachment is obsolete: true
Attachment #528720 - Flags: feedback?(mak77)
Paolo, have you kicked off a try-server build with the latest patch? I'd like to run this through some tests to see if everything is still properly exposed to assistive technologies for people with disabilities.
Thanks!
Attached patch Base version (obsolete) — Splinter Review
Finally, this is the first version of the patch where I checked every single
line of code, and is thus ready for final code review. This does not mean that
the feature is complete, but only that subsequent changes can be laid out
incrementally and reviewed separately.

The draft theming is based on the popup notifications of Firefox 4. The
temporary toolbar button is near the notifications anchor by default.

The required changes include adding more automated test cases, designing the
best user interaction, and refining visual styles for all platforms.

Dependent bugs should also be resolved before the whole feature can be
completed. They include replacing the downloads button with an appropriate
download progress and status indicator. This activity is not started yet.
Attachment #529247 - Attachment is obsolete: true
Attachment #529878 - Flags: review?(sdwilsh)
Attachment #529878 - Flags: feedback?(mak77)
(In reply to comment #202)
> Paolo, have you kicked off a try-server build with the latest patch? I'd like
> to run this through some tests to see if everything is still properly exposed
> to assistive technologies for people with disabilities.

Thank you for your help Marco! I've started a tryserver build right now, based
on the latest patch, which includes an updated theme and a slightly different
interaction. Final builds should be available here in a few hours:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-2eaa871313d1
Paolo, thanks for writing the patch! You are awesome!

I've only found 3 issues:

1) I downloaded a file. After it was finished, I opened a new window and clicked on the Downloads toolbar button. It did not display the download, and the following was logged in the Error Console:
Error: DownloadUtils.getRecentDateTime is not a function
Source File: chrome://browser/content/downloads/downloads.js
Line: 869

2) At least on OS X, the dark text is very difficult to read, since its background is transparent on top of the dark panel.
Screenshot immediately upon clicking the Downloads toolbar button:
https://people.mozilla.com/~fyan/screenshots/downloads-ui-before-click.png
Screenshot after I clicked on the download:
https://people.mozilla.com/~fyan/screenshots/downloads-ui-after-click.png

3) I think the Downloads toolbar button would be better placed between the #search-container and #home-button. I don't think we want any more stuff between the back/forward button and the URL bar. Please get ui-review before landing.

Those issues aside, this patch provides a great base. Thanks again! :)
Hm, so far I don't see *anything* on Windows using the NVDA screen reader. When I start a download, I'm thrown back to the page where I started the download from, and in all of the accessibility hierarchy, I don't find anything that looks like the downloads panel. Could this be of the JS error that was mentioned, that it simply doesn't work at all yet in the try build?
(In reply to comment #205)
> 3) I think the Downloads toolbar button would be better placed between the
> #search-container and #home-button. I don't think we want any more stuff
> between the back/forward button and the URL bar.

looks like a bug in the glue code, or you moved the bookmarks button, since this downloads button should be put right before the bookmarks button (whose default is being the last button on the right). Did you try in a clean profile?
I tried your try-server build on win7 on a new profile - and it doesn't work. Downloads window doesn't get opened.
Seems like patch is not working for win-machines.
(In reply to comment #204)
> (In reply to comment #202)
> > Paolo, have you kicked off a try-server build with the latest patch? I'd like
> > to run this through some tests to see if everything is still properly exposed
> > to assistive technologies for people with disabilities.
> 
> Thank you for your help Marco! I've started a tryserver build right now, based
> on the latest patch, which includes an updated theme and a slightly different
> interaction. Final builds should be available here in a few hours:
> 
> http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-2eaa871313d1

Download panel is not working for me :

Error: DownloadsPanel is undefined
Source File: chrome://browser/content/browser.xul
Line: 1
I forget to precise, i'm using linux build
I didn't get any love on the mac build either, on an existing Nightly profile, fwiw.
Unfortunately, I'm traveling the so the soonest I'll be able to look at this is Monday, May 9th.
(In reply to comment #211)
> I didn't get any love on the mac build either, on an existing Nightly profile,
> fwiw.

not working also on windows.
Thanks to everyone that tried out the tryserver builds! Unfortunately, it
looks like those builds don't work at all, while the same base patch
compiled locally on my machine and on Frank's one seems to work (Frank,
see below for the reason you see the JavaScript error).

There is certainly a difference in the build environment or configurations.
Although I can't look into this problem in detail now, I've started a new
tryserver job for the same patch set, this time building both debug and
optimized versions, configured to run automated tests. Let's see - I'll
probably be able to look at the results tomorrow or the day after.

(In reply to comment #205)
> 1) I downloaded a file. After it was finished, I opened a new window and
> clicked on the Downloads toolbar button. It did not display the download, and
> the following was logged in the Error Console:
> Error: DownloadUtils.getRecentDateTime is not a function
> Source File: chrome://browser/content/downloads/downloads.js
> Line: 869

This is probably due to the fact that this patch also requires the ones on
dependent bugs, at a minimum the one on bug 653261. Note that patches on
the other dependent bugs might not apply cleanly on latest trunk, I've
refreshed them in my Mercurial patch queue to make them apply.

> 2) At least on OS X, the dark text is very difficult to read, since its
> background is transparent on top of the dark panel.
> Screenshot immediately upon clicking the Downloads toolbar button:
> https://people.mozilla.com/~fyan/screenshots/downloads-ui-before-click.png
> Screenshot after I clicked on the download:
> https://people.mozilla.com/~fyan/screenshots/downloads-ui-after-click.png

Definitely a theming bug. I'll work around it, but the new Download Manager
will require a serious theming effort (from someone else) for all platforms.
Personally, I think even the current appearance details on Windows are far
from ideal, they're just there to give a rough idea and a starting point.
Note that there won't be a "downloads button" in the final version.

(In reply to comment #207)
> (In reply to comment #205)
> > 3) I think the Downloads toolbar button would be better placed between the
> > #search-container and #home-button. I don't think we want any more stuff
> > between the back/forward button and the URL bar.
> 
> looks like a bug in the glue code, or you moved the bookmarks button, since
> this downloads button should be put right before the bookmarks button (whose
> default is being the last button on the right). Did you try in a clean profile?

I've intentionally moved the temporary downloads button to this weird position
in this iteration, so that the panel can open with the same position and
orientation as the so-called "popup notifications" (the ones displayed for
add-on downloads, for example). Whether downloads will be integrated with
popup notifications or kept separate, is a user experience design decision
that should be evaluated in a greater context. In both cases, the place to
which the Download Manager panel arrow points will have a very different
look and feel from the button you see now.

Note that no serious user interaction design work has started yet. It will
probably start after the initial assessment of code stability. Despite that,
code review, accessibility review, and basic functionality testing on the
current patch are welcome, to establish a baseline we can build upon.
Comment on attachment 529878 [details] [diff] [review]
Base version

Review of attachment 529878 [details] [diff] [review]:

I only glanced at the locales/en-US files, so no review for non-localized UI strings or RTL issues or somesuch. But I got a few nits either way.

::: browser/locales/en-US/chrome/browser/downloads/downloads.dtd
@@ +11,5 @@
+<!ENTITY cmd.cancel.accesskey             "C">
+<!ENTITY cmd.show.label                   "Open Containing Folder">
+<!ENTITY cmd.show.accesskey               "F">
+<!ENTITY cmd.showMac.label                "Show in Finder">
+<!ENTITY cmd.showMac.accesskey            "F">

A localization note would be good here to emphasize that cmd.show and cmd.showMac are never shown in the same build, and thus it's perfectly fine to have the accesskeys of the two to conflict with each other in the source.

::: browser/locales/en-US/chrome/browser/downloads/downloads.properties
@@ +1,2 @@
+# LOCALIZATION NOTE (paused): â is the "em dash" (long dash)
+paused=Paused â  #1

Nit, the double whitespace after the em dash might be confusing.

@@ +20,5 @@
+stateCanceled=Canceled
+# LOCALIZATION NOTE (stateBlocked): 'Parental Controls' should be capitalized
+stateBlockedParentalControls=Blocked by Parental Controls
+# LOCALIZATION NOTE (stateBlockedPolicy): 'Security Zone Policy' should be capitalized 
+stateBlockedPolicy=Blocked by your Security Zone Policy

Are Parental Controls and Security Zone Policy elsewhere in our UI?

Also, I'm not sure if capitalized is right, it should probably be consistently named and spelled with the display of those features on Windows in that localization?

@@ +27,5 @@
+
+# LOCALIZATION NOTE (yesterday): Displayed time for files finished yesterday
+yesterday=Yesterday
+# LOCALIZATION NOTE (monthDate): #1 month name; #2 date number; e.g., January 22
+monthDate=#1 #2

I'm tempted to say that English is the odd case in terms of Month/Day, maybe make en-US be "#2 #1"?
(In reply to comment #216)
> I'm tempted to say that English is the odd case in terms of Month/Day, maybe
> make en-US be "#2 #1"?
en-us should most certainly be "January 22" instead of "22 January".  Other English locales may differ, however.
I believe the suggestion was that make en-us #2 #1 and change the code to be flipped so that the common case for other locales is "#1 #2".
(In reply to comment #218)
> I believe the suggestion was that make en-us #2 #1 and change the code to be
> flipped so that the common case for other locales is "#1 #2".

Yes.
(In reply to comment #219)
> (In reply to comment #218)
> > I believe the suggestion was that make en-us #2 #1 and change the code to be
> > flipped so that the common case for other locales is "#1 #2".
> Yes.
Ah, apologies.  That was unclear to me :)
The problem with the patch that caused the tryserver builds not to work is that "resource://app/modules/DownloadCommon.jsm" doesn't exist, because they are omnijar builds, and bug 620931 isn't fixed. You can use "resource:///modules/DownloadCommon.jsm" to refer to it in the mean time as a workaround.
(In reply to comment #221)
> The problem with the patch that caused the tryserver builds not to work is that
> "resource://app/modules/DownloadCommon.jsm" doesn't exist, because they are
> omnijar builds, and bug 620931 isn't fixed. You can use
> "resource:///modules/DownloadCommon.jsm" to refer to it in the mean time as a
> workaround.

I have copied omni.jar/modules/DownloadCommon.jsm to omni.jar/app/modules/DownloadCommon.jsm and it didn't help.
You'd need to copy it to <appdir>/modules. But someone should just fix the patch and make new builds :)
(In reply to comment #221)
> The problem with the patch that caused the tryserver builds not to work is that
> "resource://app/modules/DownloadCommon.jsm" doesn't exist, because they are
> omnijar builds, and bug 620931 isn't fixed. You can use
> "resource:///modules/DownloadCommon.jsm" to refer to it in the mean time as a
> workaround.

Wow... thanks. I manually checked if all files were present in "omni.jar",
checked the "chrome:" URLs, but didn't think about "resource:" at the moment!
The fact that Cu.import failures didn't show up in the Error Console, or the
test logs, didn't help. Is the latter a known issue?

I started a new tryserver build with those lines changed. For the patch,
I'll batch this change together with localization improvements and review
comments after Monday.
New tryserver builds available here for accessibility tests and early feedback
(though comment 215 is a recommended reading if you're testing user experience):

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-d28ebe022bea

There is another weird difference between my local build and this one, at least
on Windows: in my local version, the downloads panel opens automatically
whenever a new download starts, while in the tryserver build it does not
open, and no errors are reported in the Error Console. Clicking the temporary
download button after the download starts, instead, opens the panel as expected
in both builds.
(In reply to comment #216)
> ::: browser/locales/en-US/chrome/browser/downloads/downloads.properties
> @@ +1,2 @@
> +# LOCALIZATION NOTE (paused): â is the "em dash" (long dash)
> +paused=Paused â  #1
> 
> Nit, the double whitespace after the em dash might be confusing.

With regard to strings like these ones, I don't see why different locales
would want to change the "em dash" to something else, change the spacing,
or change the order of the placeholders. Seems like "zh-CN" and "ja" use
normal spacing. Strangely, "ko" gets rid of the entire " - #1". The latter
seems like a possible localization bug, but maybe I'm missing something?

http://mxr.mozilla.org/l10n-central/source/ko/toolkit/chrome/mozapps/downloads/downloads.properties

Wouldn't it make more sense to handle this formatting in the presentation,
and include only the pure strings (e.g. "Paused") in the localization? This
could also give more flexibility to the presentation, for example we might
want a bold label saying "Canceled" or "Paused", but a plain domain name.

Previously I tried to keep the strings similar to their counterpart in
Toolkit, but at this point everything else is basically brand new, so I
think we are free to change these too.

> +# LOCALIZATION NOTE (yesterday): Displayed time for files finished yesterday
> +yesterday=Yesterday
> +# LOCALIZATION NOTE (monthDate): #1 month name; #2 date number; e.g., January
> 22
> +monthDate=#1 #2
> 
> I'm tempted to say that English is the odd case in terms of Month/Day, maybe
> make en-US be "#2 #1"?

Sorry, these two lines are leftovers from previous incarnations - I've
removed them now. See bug 653261. I assume we don't want to change the
order of the elements in Toolkit as those have been already localized.
In my case, downloading with the try server build the download panel does not show automatically, in fact I know there is a download going on because the Nightly icon in the task bar glows green. The new download panel shows only if I click the temporary download button after the download starts.
I'm on Windows 7.
Gabriela, please read comment 225.
The download panel should have scrollbars when there's too much downloads in the list. With current tryserver build, if there's too much downloads only the 17 first (on a 1920x1200 screen) are reachable.
(In reply to comment #228)
> Gabriela, please read comment 225.
> The download panel should have scrollbars when there's too much downloads in
> the list. With current tryserver build, if there's too much downloads only
> the 17 first (on a 1920x1200 screen) are reachable.

Darren, I didn't mention scrollbars in my comment so I'm afraid I don't understand yours.
(In reply to comment #227)
> In my case, downloading with the try server build the download panel does
> not show automatically, in fact I know there is a download going on because
> the Nightly icon in the task bar glows green. The new download panel shows
> only if I click the temporary download button after the download starts.
> I'm on Windows 7.

Thanks for confirming that this affects Windows 7 also, and not only my machine!

(In reply to comment #228)
> The download panel should have scrollbars when there's too much downloads in
> the list. With current tryserver build, if there's too much downloads only
> the 17 first (on a 1920x1200 screen) are reachable.

Thanks for the feedback: this looks like a regression in panels with
type="arrow". They are not limited by the height of the screen, while
normal panels are (though they overlap with the task bar on Windows).
These issues should be looked into by someone familiar with arrow panels.
> http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-d28ebe022bea

After using this test build, I seem some ploblems at the latest design.

First, I cannot recognize the current status of download if DL icon remoed from toolbar.
Second, Download Manager is not opened from shortcut key.
Third, "Download" pane in Places library does not provide the download status.

Are these points fix in the future?
(In reply to comment #229)
> (In reply to comment #228)
> > Gabriela, please read comment 225.
> > The download panel should have scrollbars when there's too much downloads in
> > the list. With current tryserver build, if there's too much downloads only
> > the 17 first (on a 1920x1200 screen) are reachable.
> 
> Darren, I didn't mention scrollbars in my comment so I'm afraid I don't
> understand yours.
The scrollbar part of my comment was adressed to Paolo.
(In reply to comment #232)
> (In reply to comment #229)
> > (In reply to comment #228)
> > > Gabriela, please read comment 225.
> > > The download panel should have scrollbars when there's too much downloads in
> > > the list. With current tryserver build, if there's too much downloads only
> > > the 17 first (on a 1920x1200 screen) are reachable.
> > 
> > Darren, I didn't mention scrollbars in my comment so I'm afraid I don't
> > understand yours.
> The scrollbar part of my comment was adressed to Paolo.

How could I know that part was addressed to Paolo when it starts addressed to me??? I'm sorry but you should have addressed that part to Paolo then!
(In reply to comment #233)
> How could I know that part was addressed to Paolo when it starts addressed
> to me??? I'm sorry but you should have addressed that part to Paolo then!
Because it was nothing related to what you said ?
(In reply to comment #234)
> (In reply to comment #233)
> > How could I know that part was addressed to Paolo when it starts addressed
> > to me??? I'm sorry but you should have addressed that part to Paolo then!
> Because it was nothing related to what you said ?

aaaand that's just about enough "using an active bugzilla bug to discuss conversational structure"

Let's keep it on topic, folks.
I tested the try build with screen readers and have the following observations:

1. The list and context menu still work as in the old download manager UI. Great!
2. Problem: When tabbing from the list onwards, I hit the "Open" button twice. Once it's a sub menu button, the second a regular button. The next thing in the tab order is the "Show download history" button. Why these two tabstops on the Open button?
3. Problem: CTRL+J (on Windows) is not yet hooked up to open the new downloads UI. It currently doesn't do anything.
4. Problem: The panel does not announce itself as being the downloads panel any more. The old window had a title screen readers were able to read. How is it conveyed visually that this is the Downloads window? If through some sort of image, we'll have to apply some WAI-ARIA magic to also give the panel a label. It should also get a proper role, since it is currently non-existent in the a1y hierarchy and needs to be a container. This is done by applying the role attribute to the panel itself. The available roles can be found in the wAI-ARIA documentation: http://www.w3.org/TR/wai-aria/roles#role_definitions
For this case, a role of dialog is probably most appropriate, or group, we'd need to test those.
5. Question: It is not clear to me what actually closes the panel besides Esc. I pressed F6, and it also went away. I would expect F6 to move me to the next panel (document) or the address bar, but not to dismiss the panel automatically.
The try build isn't working on Windows XP SP3 for me. Even if I click on the download icon after starting a download it shows nothing.
Attached image what it look like on Linux/Ubuntu (obsolete) —
Posted a screenshot on what it look like on Ubuntu/Linux, it sure need some visual tweaks.
It work ok but should make like this mockup: http://www.stephenhorlander.com/images/blog-posts/theme-update-2010-04-20/panel-download-win7.png the UI isn't good much, hope it'll land on Nightly
(In reply to comment #238)
> it sure need some visual tweaks

(In reply to comment #239)
> the UI isn't good much

Please can people read the comments above *before* posting; namely comment 215 that states:

> Note that no serious user interaction design work has started yet. It will
> probably start after the initial assessment of code stability. 

Paolo has done a great job with the work in this bug so far; people picking holes in the parts that are known incomplete not only adds unnecessary noise, but seems somewhat rude.

Keep up the great work Paolo :-)
Just to reiterate what Ed said, this bug is nowhere near completion. Thus please leave the attempts to polish it until after it has landed on the Nightly channel.
yeah, can we just at last have it landed to the nightly? I can write a CSS style to make it look like on the mockups.
(In reply to comment #242)
> yeah, can we just at last have it landed to the nightly? I can write a CSS
> style to make it look like on the mockups.

It'll land on ready when it's finished. Currently it's still receiving technical feedback (critiquing), then will be the review(s) and then it will land on the Nightly channel. Please be patient.
(In reply to comment #242)
> yeah, can we just at last have it landed to the nightly? I can write a CSS
> style to make it look like on the mockups.

Go ahead. I've already seen your comments on the Tab+NavBar curves. You claimed that you were "too lazy" to implement your own proposal. Why would it be any different for this bug?

https://bugzilla.mozilla.org/show_bug.cgi?id=570279#c77
Cut the cross chatter, folks.  Before you click submit, think long and hard about your post and if it follows the bugzilla etiquette.  If it doesn't, don't post it, or I will see to it that your account is disabled.  The cross chatter doesn't help move this bug forward; in fact, it only makes development move slower.
https://bugzilla.mozilla.org/page.cgi?id=etiquette.html
(In reply to comment #244)
> (In reply to comment #242)
> > yeah, can we just at last have it landed to the nightly? I can write a CSS
> > style to make it look like on the mockups.
> 
> Go ahead. I've already seen your comments on the Tab+NavBar curves. You
> claimed that you were "too lazy" to implement your own proposal. Why would
> it be any different for this bug?
> 
> https://bugzilla.mozilla.org/show_bug.cgi?id=570279#c77

I've described the way it is possible to do tab curves using pure css, but where we need to create 1 element in the DOM-tree. And I don't know how to create it. Someone said it's possible using DOMi - but I've tried and it didn't work for me.
Besides, I'm not interested in having tab curves, I like the current tabs (they are a bit too square too high and too wide by default, but it gets fixed easily with 5 lines of CSS code).
And I'm really interested in having Doorhanger-like downloads window.
Oh, and I'm not sure they I would be able to make a glassy border for that window myself, as -moz-win-glass is not working (and even if it would - it's not a cross-platform solution) due to existing (or was it resolved WONTFIX) bug created by me.
But I could fix it using SVG filter "Gaussian Blur" but once again - due to an unfixed/ignored bug - SVGs are not working in Firefox if they are inside CSS style. And I only know how to use SVGs using CSS, otherwise I would need to create some patch and Hg is a piece of sh1t for that purpose.
Hadn't worked to me because the German language pack was installed.
Tested it now and it is great! I really like the new Download manager.
Comment on attachment 529878 [details] [diff] [review]
Base version

I'm actually going to let this go through one more feedback cycle from mak before I really dig into this.  He says he should get to this soon :D
Attachment #529878 - Flags: review?(sdwilsh)
Comment on attachment 529878 [details] [diff] [review]
Base version

Review of attachment 529878 [details] [diff] [review]:
-----------------------------------------------------------------

The button positioning needs serious planning.
I see there is discussion on whether it should be a button or an identity notification, but this has to be solved soon (Limi should get an updated trybuild asap).

Btw, this feedback includes everything but css files (styling is still to be defined) and downloads.js.
I plan to do downloads.js tomorrow morning, since it's the largest file and requires more attention.

::: browser/components/downloads/DownloadCommon.jsm
@@ +16,5 @@
> + * The Original Code is Download Manager Code.
> + *
> + * The Initial Developer of the Original Code is
> + * Paolo Amadini <http://www.amadzone.org/>.
> + * Portions created by the Initial Developer are Copyright (C) 2010-2011

just take one, we don't usually specify 2 years. This is usually the year you created the file first.

This seems to apply to all headers you created

@@ +71,5 @@
> +const DownloadCommon = {
> +  /**
> +   * Returns an object whose keys are the string names from the downloads string
> +   * bundle, and whose values are either the translated strings or functions
> +   * that can be used to obtain formatted strings.

nit: s/functions that can be used to obtain/getters for/

@@ +103,5 @@
> +                                   "nsIDownloadManager");
> +
> +XPCOMUtils.defineLazyServiceGetter(DownloadCommon, "ms",
> +                                   "@mozilla.org/mime;1",
> +                                   "nsIMIMEService");

I see that is short, but to me ms sounds not very describing (indeed I was guessing why you had a microsummaries service getter). Why not just "mime"?

::: browser/components/downloads/DownloadManagerUI.js
@@ +70,5 @@
> +
> +  show: function DMUI_show(aWindowContext, aID, aReason)
> +  {
> +    let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
> +    if (browserWin && !browserWin.closed) {

For clarity, annotate bug 528706 in a comment above this.

@@ +79,5 @@
> +
> +  get visible()
> +  {
> +    let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
> +    return browserWin ? browserWin.DownloadsPanel.isPanelShowing : false;

this may have same .closed bug, even if less important since the object should still be there. Btw maybe you could add a simple _getBrowserWindow helper and use it in both places.

::: browser/components/downloads/downloads.css
@@ +1,5 @@
> +/*** Download items ***/
> +
> +richlistitem[type="download"] {
> +  -moz-binding: url('chrome://browser/content/downloads/download.xml#download');
> +  -moz-box-orient: vertical;

out of curiosity, why is it needed to set content to horizontal in the binding and then orient to vertical in the style?

@@ +69,5 @@
> +                                           .downloadShow,
> +
> +.download-state[state="7"]                 .downloadCommandsSeparator
> +
> +{

nit: fwiw, this file, regardless all the indentation tricks, doesn't seem particularly readable to me. But this is a coding style thing I leave to the module owner :)

::: browser/components/downloads/downloadsOverlay.xul
@@ +102,5 @@
> +           align="center"
> +           onpopupshown="document.getElementById('downloadsListBox').focus();"
> +           onpopuphidden="DownloadsPanel.onPopupHidden();">
> +      <menupopup id="downloadsContextMenu"
> +                 class="download-state">

Did you have a chance to check if popups are still conflicting?
If so, you should ensure a bug on that exists and annotate it here with a comment on why this context menu is not defined in the popupset.
Otherwise, if that has been fixed, this should be moved.

@@ +155,5 @@
> +                  accesskey="&selectAllCmd.accesskey;"/>
> +      </menupopup>
> +
> +      <label id="downloadsNoDownloads"
> +             value="&nodownloads.label;"/>

Why is this a <label> rather than a <description>? doesn't seem to be related to any control

::: browser/components/preferences/tests/Makefile.in
@@ +45,5 @@
>  
>  _BROWSER_FILES = \
> +    browser_basic_functionality.js \
> +    browser_delete_key_removes.js \
> +    head.js \

just indent 2 spaces here

PS: Splinter seems to think this is browser/components/preferences/tests/Makefile.in, I was puzzled by that, but I see you hg copied that file, if possibile I'd suggest to rewrite this file since the copy blame is unrelated.

::: browser/components/downloads/test/browser_basic_functionality.js
@@ +1,4 @@
> +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
> +/* vim: set ts=2 et sw=2 tw=80: */
> +/* Any copyright is dedicated to the Public Domain.
> +   http://creativecommons.org/publicdomain/zero/1.0/ */

Sdwilsh: does downloads component style guide require the mode and vim comments? (btw, tab-width seems wrong)

@@ +29,5 @@
> +  ];
> +
> +  for (yy in gen_resetState()) yield;
> +  for (yy in gen_addDownloadRows(DownloadData)) yield;
> +  for (yy in gen_openPanel()) yield;

some comment on each one of these would be welcome, it's a bit cryptic otherwise

@@ +37,5 @@
> +  is(richlistbox.children.length, DownloadData.length,
> +     "There is the correct number of richlistitems");
> +  for (var i = 0; i < richlistbox.children.length; i++) {
> +    var element = richlistbox.children[i];
> +    var dataItem = new DownloadsViewItemController(element).dataItem;

nit: these seem good candidates for "let"

@@ +47,5 @@
> +
> +  // Clean up when the test finishes.
> +  for (yy in gen_resetState()) yield;
> +
> +  gTestTargetFile.remove(false);

you should do this in registerCleanupFunction, remember that browser-chrome tests don't run in separate sandboxes, so you have to ensure any change you make is correctly cleaned up both if the test succeeds and if it fails.

Unless this cleanup code will be specific to only some of the tests you could even move that registerCleanupFunction to head.js (it works, really)

::: browser/components/downloads/test/browser_delete_key_removes.js
@@ +19,5 @@
> +  ];
> +
> +  for (yy in gen_resetState()) yield;
> +  for (yy in gen_addDownloadRows(DownloadData)) yield;
> +  for (yy in gen_openPanel()) yield;

ditto for comments

@@ +34,5 @@
> +           richlistbox.children.length,
> +           "The database and the number of downloads display matches");
> +      },
> +      handleError: function(aError) { Cu.reportError(aError); },
> +      handleCompletion: function(aReason) { testRunner.continueTest(); },

for code style, don't oneline functions please.

@@ +42,5 @@
> +    // Check that the delete key removes each download.
> +    let len = DownloadData.length;
> +    for (let i = 0; i < len; i++) {
> +      // This removes the download synchronously.
> +      EventUtils.synthesizeKey("VK_DELETE", {});

I think it's good practice to focus things before synthesizing keys, the focus could go elsewhere for whatever reason on tinderboxes.

@@ +52,5 @@
> +             len - (i + 1),
> +             "The download was properly removed");
> +        },
> +        handleError: function(aError) { Cu.reportError(aError); },
> +        handleCompletion: function(aReason) { testRunner.continueTest(); },

ditto on oneline functions

@@ +63,5 @@
> +
> +  // Clean up when the test finishes.
> +  for (yy in gen_resetState()) yield;
> +
> +  gTestTargetFile.remove(false);

ditto for cleanup

::: browser/components/downloads/test/head.js
@@ +75,5 @@
> +                  "DELETE FROM moz_downloads");
> +  statement.executeAsync({
> +    handleResult: function(aResultSet) { },
> +    handleError: function(aError) { Cu.reportError(aError); },
> +    handleCompletion: function(aReason) { testRunner.continueTest(); },

ditto for oneline functions

@@ +86,5 @@
> +
> +function gen_addDownloadRows(aDataRows)
> +{
> +  let columnNames = [n for ([n] in Iterator(gDownloadRowTemplate))]
> +                    .join(", ");

do you really need an Iterator here? can't you do Object.keys(gDownloadRowTemplate).join(", "); ?

@@ +88,5 @@
> +{
> +  let columnNames = [n for ([n] in Iterator(gDownloadRowTemplate))]
> +                    .join(", ");
> +  let parameterNames = [":" + n for ([n] in Iterator(gDownloadRowTemplate))]
> +                       .join(", ");

Object.keys(gDownloadRowTemplate).map(function (v) ":" + v).join(", ");

@@ +96,5 @@
> +  try {
> +    // Execute the statement for each of the provided downloads.
> +    for ([, dataRow] in Iterator(aDataRows)) {
> +      // Populate insert parameters from the provided data.
> +      for (let [columnName] in Iterator(gDownloadRowTemplate)) {

just store columnNames as an array and join() it where needed?

@@ +109,5 @@
> +      // Run the statement asynchronously and wait.
> +      statement.executeAsync({
> +        handleResult: function(aResultSet) { },
> +        handleError: function(aError) { Cu.reportError(aError); },
> +        handleCompletion: function(aReason) { testRunner.continueTest(); },

ditto for oneline functions

::: browser/components/nsBrowserGlue.js
@@ +1165,5 @@
> +          currentset.indexOf("downloads-button") == -1) {
> +        // The element is added before the location bar, or as the first button.
> +        if (currentset.indexOf("urlbar-container") != -1) {
> +          currentset = currentset.replace(/(^|,)urlbar-container($|,)/,
> +                                          "$1downloads-button,urlbar-container$2")

clearly this is in couple with my other comments regarding getting early ux feedback on the button position (or existence)

@@ +1168,5 @@
> +          currentset = currentset.replace(/(^|,)urlbar-container($|,)/,
> +                                          "$1downloads-button,urlbar-container$2")
> +        }
> +        else {
> +          currentset = "downloads-button," + currentset;

won't this put the button even before back/forward buttons?
Comment on attachment 529878 [details] [diff] [review]
Base version

Review of attachment 529878 [details] [diff] [review]:
-----------------------------------------------------------------

So, following is a huge list of suggestions, but globally this is much much better than previous version, and pretty much clear.
Amazing work Paolo!
I didn't test the functionality (I'm sure we'll soon get a new trybuild for that), but looking at the code my feedback may only be positive.

::: browser/components/downloads/downloads.js
@@ +115,5 @@
> +  get kPanelHidden() 1,
> +  /** The panel will be shown as soon as possible. */
> +  get kPanelShowing() 2,
> +  /** The panel is open, though download data might still be loading. */
> +  get kPanelShown() 3,

I don't understand this, why having getters for constant values?

I'd rather add a
const STATE = {
  UNINITIALIZED: 0,
  HIDDEN: 1,
  SHOWING: 2,
  SHOWN: 3
}
and then use this._panelState != STATE.HIDDEN and such

@@ +120,5 @@
> +
> +  /**
> +   * Starts loading the download data in the background, without opening the
> +   * panel. You can call the showPanel method instead if you want to load the
> +   * data and open the panel at the same time.

s/in the background/in background/
"Use showPanel() instead to load the data and open the panel at the same time."

nit: per comments readability, double space after periods.

@@ +132,5 @@
> +
> +    window.addEventListener("unload", this.onWindowUnload, false);
> +
> +    DownloadsView.data = new DownloadsData(DownloadsView);
> +    DownloadsView.data.initialize();

is there a case where you have to create a DownloadsData without invoking .initialize()? if not you could just merge initialize in the constructor (luckily this is not cpp+xpcom)

@@ +133,5 @@
> +    window.addEventListener("unload", this.onWindowUnload, false);
> +
> +    DownloadsView.data = new DownloadsData(DownloadsView);
> +    DownloadsView.data.initialize();
> +    DownloadsViewController.initialize();

I think I'd rather provide a initialize() and terminate() in DownloadsView, and inside those init/terminate data and controller.
So the flow here on panel opening is just "we init a view for this panel" and on close "we terminate a view for this panel"

@@ +154,5 @@
> +    this.hidePanel();
> +
> +    DownloadsViewController.terminate();
> +    DownloadsView.data.terminate();
> +    DownloadsView.data = null;

ditto

@@ +167,5 @@
> +   * Approximate minimum number of items to get on initialization before showing
> +   * the panel. This avoids presenting to the user a panel that keeps vertically
> +   * growing for each loaded item.
> +   */
> +  get kMinItemCountForPopup() 20,

why a getter?

@@ +183,5 @@
> +    }
> +
> +    this.initialize();
> +    this._panelState = this.kPanelShowing;
> +    this.onViewItemCountChange();

comment on what this call is for (since the method says it has to be called when the list count changes)

@@ +194,5 @@
> +  hidePanel: function DO_hidePanel()
> +  {
> +    if (this._panelState == this.kPanelUninitialized) {
> +      return;
> +    }

return also if it's hidden? or better you could if (!isPanelShowing)

@@ +200,5 @@
> +    this.panel.hidePopup();
> +
> +    // Ensure that we allow the panel to be reopened, even if the popup was
> +    // already hidden and the onPopupHidden event was not invoked.
> +    this._panelState = this.kPanelHidden;

is not this already done by onPopupHidden?

@@ +209,5 @@
> +   */
> +  get isPanelShowing() {
> +    return this._panelState == this.kPanelShowing ||
> +           this._panelState == this.kPanelShown;
> +  },

I'd suggest to use the short form (no braces and no return) but I think Sdwilsh would be unhappy about that :p

@@ +257,5 @@
> +
> +  /**
> +   * Shows or focuses the user interface dedicated to downloads history.
> +   */
> +  showHistory: function DO_showHistory()

I'd rename this to showDownloadsHistory

@@ +274,5 @@
> +  /**
> +   * Internal method that actually opens the Download Manager panel interface
> +   * when enough data is ready to be displayed.
> +   */
> +  _openPopupIfReady: function DO_openPopupIfReady()

Read is a bit generic, I'd rename to openPopupIfDataReady

@@ +280,5 @@
> +    // We don't want to open the popup if we already displayed it, or if we are
> +    // still loading and there are not enough elements yet.
> +    if (this._panelState != this.kPanelShowing ||
> +        (DownloadsView.itemCount < this.kMinItemCountForPopup &&
> +         !DownloadsView.loadCompleted)) {

this should be more readable:

let isDataReady = DownloadsView.itemCount >= this.kMinItemCountForPopup ||
                  DownloadsView.loadCompleted;
if (this._panelState != this.kPanelShowing || !isDataReady)

@@ +292,5 @@
> +                                                      .ROLLUP_CONSUME);
> +
> +    // If the downloads button has been removed from the toolbar, anchor the
> +    // panel to the toolbar itself. The popup will open near the place where
> +    // the downloads button is present by default.

this comment could need update when there is a decision on button position

@@ +300,5 @@
> +  }
> +};
> +
> +XPCOMUtils.defineLazyGetter(DownloadsPanel, "panel", function()
> +                            document.getElementById("downloadsPanel"));

nit: move function () on the same line as getElementById if it doesn't go over 80 chars

@@ +308,5 @@
> +
> +/**
> + * Builds and updates the downloads list widget, responding to changes in the
> + * download state and real-time data. In addition, handles part of the user
> + * interaction events raised by the downloads list widget.

nit: "real-time data" is a bit generic.

@@ +331,5 @@
> +
> +  /**
> +   * First element in the download list widget whose state is in progress, or
> +   * null if no such element exists. If it exists, this element can be the same
> +   * as firstElementNotDone, or it can be one of the elements following it.

just "Can be the same as firstElementNotDone, or one of the next siblings."

@@ +337,5 @@
> +  firstElementInProgress: null,
> +
> +  /**
> +   * Places the XUL element associated with a download item in the correct
> +   * position in the downloads list widget, first in its category. If the

can probably be explained better, especially the ", first in its category"

@@ +346,5 @@
> +   *
> +   * @param aDataItem
> +   *        DownloadsDataItem that is being added or moved.
> +   */
> +  _addOrMoveElementToTop: function DV_addOrMoveElementToTop(aElement, aDataItem)

the method name is lying, this does not always puts to top (of the list) rather it top of the category. What about _insertAsFirstCategorizedElement or something like that?

@@ +350,5 @@
> +  _addOrMoveElementToTop: function DV_addOrMoveElementToTop(aElement, aDataItem)
> +  {
> +    // Items that are done are inserted before all other items.
> +    if (aDataItem.done) {
> +      this.richListBox.insertBefore(aElement, this.richListBox.firstChild);

should you unset this.firstElementInProgress and this.firstElementNotDone if they are same as aElement?

@@ +357,5 @@
> +
> +    // Items not in progress are inserted before items that are in progress.
> +    if (!aDataItem.inProgress) {
> +      this.richListBox.insertBefore(aElement, this.firstElementNotDone);
> +      this.firstElementNotDone = aElement;

should you unset this.firstElementInProgress if it's aElement?

@@ +383,5 @@
> +   * @param aDataItem
> +   *        DownloadsDataItem that is being added or moved.
> +   */
> +  _addOrMoveElementToBottom: function DV_addOrMoveElementToBottom(aElement,
> +                                                                  aDataItem)

same comments as above

@@ +430,5 @@
> +    // otherwise it means that no such element exists anymore.
> +    if (aElement != this.firstElementNotDone ||
> +        aElement != this.firstElementInProgress) {
> +      return;
> +    }

shouldn't this be an AND? if aElement is going away you should ensure it's not used in both.

@@ +453,5 @@
> +    }
> +    if (aElement == this.firstElementInProgress) {
> +      this.firstElementInProgress = nextDataItem.inProgress ? nextElement
> +                                                            : null;
> +    }

Unless DownloadsViewItemController() is much expensive I think inverting the ifs could be more readable:

if (aElement == this.firstElementNotDone) {
  if (!nextElement) {
    this.firstElementNotDone = null;
  }
  else {
    let nextDataItem = new DownloadsViewItemController(nextElement).dataItem;
    this.firstElementNotDone = !nextDataItem.done ? nextElement : null;
  }
}

if (aElement == this.firstElementInProgress) {
  ...
}

@@ +461,5 @@
> +   * Called when the number of download items in the list changes.
> +   */
> +  _itemCountChanged: function DV_itemCountChanged()
> +  {
> +    // Note that the "itemCount" property may not be available now.

clarify comment please (Add when and why, "now" is not enough)

@@ +462,5 @@
> +   */
> +  _itemCountChanged: function DV_itemCountChanged()
> +  {
> +    // Note that the "itemCount" property may not be available now.
> +    let newItemCount = this.richListBox.childNodes.length;

this.richListBox.childElementCount ?

@@ +486,5 @@
> +  {
> +    let previousSelectedIndex = this.richListBox.selectedIndex;
> +    this._beforeRemoveElement(aElement);
> +    this._addOrMoveElementToTop(aElement, aDataItem);
> +    this.richListBox.selectedIndex = previousSelectedIndex;

What if I selected this specific element, should not the selection follow it?

@@ +532,5 @@
> +  },
> +
> +  /**
> +   * Called when an event occurred for which the downloads database is not
> +   * available anymore and existing data should be discarded.

ehr, rephrase, something like:
"Called when the downloads database becomes unavailable.  Existing data should be discarded."
Bonus points if you also explain situations when it happens.

@@ +550,5 @@
> +   * @param aNewest
> +   *        When true, indicates that this item is the most recent and should be
> +   *        added in the topmost position of its category. This happens when a
> +   *        new download is started. When false, indicates that the item is the
> +   *        least recent with regard to the items that have been already added.

"least recent" or just "not the most recent"?

@@ +551,5 @@
> +   *        When true, indicates that this item is the most recent and should be
> +   *        added in the topmost position of its category. This happens when a
> +   *        new download is started. When false, indicates that the item is the
> +   *        least recent with regard to the items that have been already added.
> +   *        This generally happens during the initial data load, when we want

What is "this", that is set to true?

@@ +565,5 @@
> +      this._addOrMoveElementToTop(element, aDataItem);
> +    } else {
> +      this._addOrMoveElementToBottom(element, aDataItem);
> +    }
> +    this._itemCountChanged();

I'm under the impression that when you add an item selection changes, I suppose it should stay on the same item it was before

@@ +625,5 @@
> +      return;
> +    }
> +
> +    // Find the richlistitem for the download and execute the command.
> +    for (; target.nodeName != "richlistitem"; target = target.parentNode);

better avoiding empty-body for loops, they are confusing and error-prone. use a while instead:
while (target.nodeName != "richlistitem") {
  target = target.parentNode;
}

@@ +635,5 @@
> +    // Double clicks on buttons should not invoke the default action.
> +    if (aEvent.originalTarget.hasAttribute("command") ||
> +        aEvent.originalTarget.hasAttribute("oncommand")) {
> +      return;
> +    }

aEvent.preventDefault() ? or you're just trying to skip next code?

@@ +673,5 @@
> +
> +    var dt = aEvent.dataTransfer;
> +    dt.mozSetDataAt("application/x-moz-file", f, 0);
> +    dt.effectAllowed = "copyMove";
> +    dt.addElement(element);

you could want to stopPropagation since you handled the drag

@@ +683,5 @@
> +    if (types.contains("text/uri-list") ||
> +        types.contains("text/x-moz-url") ||
> +        types.contains("text/plain")) {
> +      aEvent.preventDefault();
> +    }

I think you may use
if (Services.droppedLinkHandler.canDropLink(aEvent, true)) {
  aEvent.preventDefault();
}

@@ +685,5 @@
> +        types.contains("text/plain")) {
> +      aEvent.preventDefault();
> +    }
> +    aEvent.stopPropagation();
> +  },

do you allow both copy and move everywhere? (you're not handling dropEffect in any special way so I suppose yes)

@@ +695,5 @@
> +    var name;
> +    if (!url) {
> +      url = dt.getData("text/x-moz-url") || dt.getData("text/plain");
> +      [url, name] = url.split("\n");
> +    }

you may use
var name = {};
var url = Services.droppedLinkHandler.dropLink(aEvent, name);
name = name.value;

@@ +699,5 @@
> +    }
> +    if (url) {
> +      saveURL(url, name ? name : url, null, true, true);
> +    }
> +  }

you're not checking which operation the user required (dropEffect == "copy" or "move"), but looks like you do the same for both.
you may also call aEvent.preventDefault to indicate you handled the drop.

@@ +710,5 @@
> +//// DownloadsViewItem
> +
> +/**
> + * Builds and updates a single item in the downloads list widget, responding to
> + * changes in the download state and real-time data.

define real-time data better.

@@ +724,5 @@
> +  this._element = aElement;
> +  this.dataItem = aDataItem;
> +
> +  this.previousDone = this.dataItem.done;
> +  this.previousInProgress = this.dataItem.inProgress;

previous sounds strange, maybe wasDone, wasInProgress?

@@ +725,5 @@
> +  this.dataItem = aDataItem;
> +
> +  this.previousDone = this.dataItem.done;
> +  this.previousInProgress = this.dataItem.inProgress;
> +  this.lastSeconds = Infinity;

I don't have any idea what lastSeconds represents, better name?

@@ +737,5 @@
> +    "state": this.dataItem.state,
> +    "progress": this.dataItem.inProgress ? this.dataItem.percentComplete : 100,
> +    "target": this.dataItem.target,
> +    "image": this.image
> +  };

const

@@ +777,5 @@
> +      try {
> +        // Refresh the icon, so that executable icons are shown. Tacking on
> +        // contentType bypasses cache.
> +        this.image += "&contentType=" + DownloadCommon.ms.getTypeFromFile(
> +                                                       this.dataItem.localFile);

rephrase comment and fix indentation a bit:
// Refresh the icon to ensure executable icons are shown.
// Add contentType to bypass the cache (is there a bug about this to annotate here?).
let mimeType = DownloadCommon.mime.getTypeFromFile(this.dataItem.localFile);
this.image += "&contentType=" + mimeType;

@@ +789,5 @@
> +    if (this.previousInProgress && !this.dataItem.inProgress) {
> +      this.endTime = Date.now();
> +    }
> +
> +    // Move the download to the appropriate place in the list if state changed.

"...to the appropriate list position if..."

@@ +851,5 @@
> +      let transfer = DownloadUtils.getTransferTotal(this.dataItem.currBytes,
> +                                                    this.dataItem.maxBytes);
> +      status = this._replaceInsert(DownloadCommon.strings.paused, 1, transfer);
> +    } else if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) {
> +      let newLast;

better var name

@@ +871,5 @@
> +          case nsIDM.DOWNLOAD_FAILED:           return s.stateFailed;
> +          case nsIDM.DOWNLOAD_CANCELED:         return s.stateCanceled;
> +          case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: return s.stateBlockedParentalControls;
> +          case nsIDM.DOWNLOAD_BLOCKED_POLICY:   return s.stateBlockedPolicy;
> +          case nsIDM.DOWNLOAD_DIRTY:            return s.stateDirty;

I'm not sure I like this indentation, but I leave this to the module owner

@@ +882,5 @@
> +            let [size, unit] = DownloadUtils.convertByteUnits(fileSize);
> +            let sizeText = this._replaceInsert(s.doneSize, 1, size);
> +            return this._replaceInsert(sizeText, 2, unit);
> +        }
> +      }.apply(this);

just add another underscore helper and pass it this.dataItem, putting all of this here inflates the code without big value.

@@ +904,5 @@
> +   * Updates the time that gets shown for completed download items.
> +   */
> +  _updateTime: function DVI_updateTime()
> +  {
> +    // Don't bother updating for things that aren't finished.

"things"?

@@ +909,5 @@
> +    if (this.dataItem.inProgress) {
> +      return;
> +    }
> +
> +    let end = new Date(parseInt(this.dataItem.endTime));

why do you need to parseInt this here, shouldn't rather that be done on setting the property?

@@ +981,5 @@
> +      return false;
> +    }
> +    // Secondly, determine if focus is on a control in the downloads list.
> +    let e = document.commandDispatcher.focusedElement;
> +    for (; e && e != DownloadsView.richListBox; e = e.parentNode);

please avoid empty-body for loops, use a while instead.

@@ +1057,5 @@
> +  {
> +    // Update all the commands that are specific for the selected item.
> +    for ([cmd] in Iterator(DownloadsViewItemController.prototype.commands)) {
> +      goUpdateCommand(cmd);
> +    }

why not just for (cmd in DownloadsViewItemController.prototype.commands) ?

@@ +1088,5 @@
> +  //////////////////////////////////////////////////////////////////////////////
> +  //// Constants
> +
> +  get kPrefBdmAlertOnExeOpen() "browser.download.manager.alertOnEXEOpen",
> +  get kPrefBdmScanWhenDone() "browser.download.manager.scanWhenDone",

why getters?

@@ +1132,5 @@
> +  doCommand: function DVIC_doCommand(aCommand)
> +  {
> +    // Invoke the command, if enabled, using this object for "this".
> +    if (this.isCommandEnabled(aCommand)) {
> +      this.commands[aCommand].apply(this);

I think you could actually use .bind(this) when defining the functions and avoid these apply.

Same for a bunch of apply() I see below

@@ +1313,5 @@
> +          case nsIDM.DOWNLOAD_SCANNING:         return "downloadsCmd_show";
> +          case nsIDM.DOWNLOAD_DIRTY:            return "downloadsCmd_openReferrer";
> +          case nsIDM.DOWNLOAD_BLOCKED_POLICY:   return "downloadsCmd_openReferrer";
> +        }
> +      }.apply(this);

as well as here you could just add a _helper

@@ +1321,5 @@
> +  },
> +
> +  commandsMultiple: {
> +    downloadsCmd_copyLocation: function
> +                               DVIC_CM_downloadsCmd_copyLocation(aControllers)

if it's too long just newline after ":" like
label:
function xyz()

@@ +1460,5 @@
> +  },
> +
> +  /**
> +   * Returns the data item associated with the provided Download Manager object
> +   * or download data row, following a real-time notification or initial load.

can probably be rephrased, it caused me an headache :)

@@ +1478,5 @@
> +   *
> +   * @return New or existing data item, or null if the item was deleted from the
> +   *         list of available downloads.
> +   */
> +  _getOrAddDataItem: function DD_getOrAddDataItem(aSource)

I'd just rename it to fetchDataItem, where it fetches it doesn't matter.

@@ +1601,5 @@
> +
> +    dataItem.state = aDownload.state;
> +    dataItem.referrer = aDownload.referrer && aDownload.referrer.spec;
> +    dataItem.resumable = aDownload.resumable;
> +    dataItem.startTime = Math.round(aDownload.startTime / 1000);

I think you may want to parseInt here, any reason to keep a double?

@@ +1632,5 @@
> +
> +  onStateChange: function(aWebProgress, aRequest, aState, aStatus,
> +                          aDownload) { },
> +
> +  onSecurityChange: function(aWebProgress, aRequest, aState, aDownload) { }

use empty args here in unused methods: "function () {},"

@@ +1677,5 @@
> +    this.target = aDownload.displayName;
> +    this.uri = aDownload.source.spec;
> +    this.referrer = aDownload.referrer && aDownload.referrer.spec;
> +    this.state = aDownload.state;
> +    this.startTime = Math.round(aDownload.startTime / 1000);

parseInt here?

@@ +1708,5 @@
> +    this.uri = aStorageRow.getResultByName("source");
> +    this.referrer = aStorageRow.getResultByName("referrer");
> +    this.state = aStorageRow.getResultByName("state");
> +    this.startTime = Math.round(aStorageRow.getResultByName("startTime") / 1000);
> +    this.endTime = Math.round(aStorageRow.getResultByName("endTime") / 1000);

parseInt here?

@@ +1713,5 @@
> +    this.currBytes = aStorageRow.getResultByName("currBytes");
> +    this.maxBytes = aStorageRow.getResultByName("maxBytes");
> +
> +    // Compute the other properties without accessing the download object.
> +    this.resumable = true;

is this always true?

@@ +1737,5 @@
> +      nsIDM.DOWNLOAD_QUEUED,
> +      nsIDM.DOWNLOAD_DOWNLOADING,
> +      nsIDM.DOWNLOAD_PAUSED,
> +      nsIDM.DOWNLOAD_SCANNING,
> +    ].indexOf(this.state) >= 0;

nit: != -1 would be more correct

@@ +1742,5 @@
> +  },
> +
> +  /**
> +   * Indicates that a download that is proceeding normally is still in its
> +   * initial state, and the actual download of data bytes hasn't started yet.

rephrase

@@ +1748,5 @@
> +  get starting()
> +  {
> +    return this.state == nsIDM.DOWNLOAD_NOTSTARTED ||
> +           this.state == nsIDM.DOWNLOAD_QUEUED;
> +  },

I'd drop braces and return (if sdwilsh allows)

@@ +1766,5 @@
> +      nsIDM.DOWNLOAD_FINISHED,
> +      nsIDM.DOWNLOAD_BLOCKED_PARENTAL,
> +      nsIDM.DOWNLOAD_BLOCKED_POLICY,
> +      nsIDM.DOWNLOAD_DIRTY,
> +    ].indexOf(this.state) >= 0;

!= -1

@@ +1782,5 @@
> +  get canRetry()
> +  {
> +    return this.state == nsIDM.DOWNLOAD_CANCELED ||
> +           this.state == nsIDM.DOWNLOAD_FAILED;
> +  },

I'd drop braces and return (if sdwilsh allows)

@@ +1801,5 @@
> +    // We should be using real URLs all the time, but until bug 239948 is fully
> +    // fixed, this will do...
> +    if (this.file.substring(0, "file://".length) == "file://") {
> +      // If this is a URL, get the file from that.
> +      // XXX It's possible that using a null charset here is bad.

ni-nit:I like these old comments from old code, "//XXX it's possible today it will rain" :)

::: browser/components/downloads/downloadsOverlay.xul
@@ +100,5 @@
> +           type="arrow"
> +           orient="vertical"
> +           align="center"
> +           onpopupshown="document.getElementById('downloadsListBox').focus();"
> +           onpopuphidden="DownloadsPanel.onPopupHidden();">

I suspect in both you could want to check event.target == event.currentTarget (to avoid handling events for nested popups
Attachment #529878 - Flags: feedback?(mak77) → feedback+
Oh I see you used getters to simulate const, personally I don't think it's worth it though, unless you have some clear bad-scenario in mind.
Thanks _very much_ for the detailed review, Marco! I've read it all, now
I've started going through all the open issues in past comments, from the
oldest to the newest in order, to update the patch. Today I didn't get past
comment 216 through! I'll reply to yours and others' comments later.
(In reply to comment #216)
> I only glanced at the locales/en-US files, so no review for non-localized UI
> strings or RTL issues or somesuch. But I got a few nits either way.

Axel, thanks for the suggestions! I've implemented them, including the changes
outlined in comment 226. For me, there's only one open point:

> Are Parental Controls and Security Zone Policy elsewhere in our UI?

No.

> Also, I'm not sure if capitalized is right, it should probably be
> consistently named and spelled with the display of those features on Windows
> in that localization?

I think so, and actually that is already the case for most of the current
translations in the Download Manager:

http://mxr.mozilla.org/l10n-central/search?string=stateBlocked

The question is, do we want new translations of the same strings to be more
consistent with the operating system, or with our previous translations in
Firefox and other Toolkit-based browsers?

Assuming the former, I've provided some links to Windows reference material
in the translation notes. Being consistent with ourselves can however create
less confusion when searching the Internet for existing solutions (this is
relevant only to locales which translated the two strings inconsistently,
in English there is no problem as we already use the correct, official words).
For example:

http://www.google.it/search?q=Security+Zone+Policy

http://kb.mozillazine.org/Unable_to_save_or_download_files#Enable_downloads_blocked_by_Security_Zone_Policy_-_Windows

Here is the latest version of the locale file, if you want to take a look:

# LOCALIZATION NOTE (stateStarting):
# Indicates that the download is starting.
stateStarting=Starting…
# LOCALIZATION NOTE (stateScanning):
# Indicates that an external program is scanning the download for viruses.
stateScanning=Scanning for viruses…
# LOCALIZATION NOTE (stateFailed):
# Indicates that the download failed because of an error.
stateFailed=Failed
# LOCALIZATION NOTE (statePaused):
# Indicates that the download was paused by the user.
statePaused=Paused
# LOCALIZATION NOTE (stateCanceled):
# Indicates that the download was canceled by the user.
stateCanceled=Canceled
# LOCALIZATION NOTE (stateBlockedParentalControls):
# Indicates that the download was blocked by the Parental Controls feature of
# Windows. "Parental Controls" should be consistently named and capitalized with
# the display of this feature in Windows. The following article can provide a
# reference for the translation of "Parental Controls" in various languages:
# http://windows.microsoft.com/en-US/windows-vista/Set-up-Parental-Controls
stateBlockedParentalControls=Blocked by Parental Controls
# LOCALIZATION NOTE (stateBlockedPolicy):
# Indicates that the download was blocked on Windows because of the "Launching
# applications and unsafe files" setting of the "security zone" associated with
# the target site. "Security zone" should be consistently named and capitalized
# with the display of this feature in Windows. The following article can provide
# a reference for the translation of "security zone" in various languages:
# http://support.microsoft.com/kb/174360
stateBlockedPolicy=Blocked by your security zone policy
# LOCALIZATION NOTE (stateDirty):
# Indicates that the download was blocked after scanning.
stateDirty=Blocked: May contain a virus or spyware

# LOCALIZATION NOTE (doneSize):
# #1 size number; #2 size unit.
doneSize=#1 #2
doneSizeUnknown=Unknown size

fileExecutableSecurityWarning="%S" is an executable file. Executable files may contain viruses or other malicious code that could harm your computer. Use caution when opening this file. Are you sure you want to launch "%S"?
fileExecutableSecurityWarningTitle=Open Executable File?
fileExecutableSecurityWarningDontAsk=Don't ask me this again
I found out that the reason why the downloads panel didn't open automatically
and the keyboard shortcut didn't work in the tryserver build is that the XPCOM
component controlling this behavior wasn't included in the installers. This is
because new XPCOM components should be explicitly added to the file named
"package-manifest.in". The next patch revision will include the fix, and I
expect the panel to work correctly in the next tryserver build.

I wonder if package manifests, or portions of them, could be generated
automatically from makefiles. Meanwhile, I've updated the documentation here:

https://developer.mozilla.org/en/Adding_XPCOM_components_to_Mozilla_build_system
oops, this is totally my fault, I had in my todo list a check for package-manifest in this patch but I forgot to do it :(
(In reply to comment #231)
> "Download" pane in Places library does not provide the download status.

I don't know if we want the list of historical downloads to provide more
information and actions than now, for example seeing whether a past download
completed, and if yes allowing the user to open the target file or folder.

If so, either the patch on bug 564900 should be updated, or another patch on
top of that one should be developed.
For old files I think we should create sth like Chrome, simply a new tab when you click e.g.  "Show downloaded files" in new download manager.
I remember it was proposed somewhere like in bug #582594 or in meta bug #584942
(In reply to comment #236)
> 2. Problem: When tabbing from the list onwards, I hit the "Open" button
> twice. Once it's a sub menu button, the second a regular button. The next
> thing in the tab order is the "Show download history" button. Why these two
> tabstops on the Open button?

I verified that this is the same behavior as the menu-button in the popup
notifications (for example, the one that is opened when you click an add-on
download link in any website). Pressing ALT+Down (on Windows) opened the
drop-down menu only when focus was on the part of the button with the down
arrow, not on the main button. Maybe this is the expected behavior of XUL
menu-buttons? If not, I think a different bug should be filed.

> 4. Problem: The panel does not announce itself as being the downloads panel
> any more. The old window had a title screen readers were able to read. How
> is it conveyed visually that this is the Downloads window? If through some
> sort of image, we'll have to apply some WAI-ARIA magic to also give the
> panel a label.

I'd like to be initiated to this kind of magic :-) Which is the method
you have in mind for implementing this panel labeling? Which is the method
that is currently used for labeling the "popup notifications" panel, if any?

> It should also get a proper role, since it is currently
> non-existent in the a1y hierarchy and needs to be a container. This is done
> by applying the role attribute to the panel itself. The available roles can
> be found in the wAI-ARIA documentation:
> http://www.w3.org/TR/wai-aria/roles#role_definitions
> For this case, a role of dialog is probably most appropriate, or group, we'd
> need to test those.

Which tools can I use to do a basic verification that the panel is included
in the accessibility hierarchy, if I assign a role attribute to it?

> 5. Question: It is not clear to me what actually closes the panel besides
> Esc. I pressed F6, and it also went away. I would expect F6 to move me to
> the next panel (document) or the address bar, but not to dismiss the panel
> automatically.

For me, on Windows, pressing F6 doesn't dismiss the panel. This, however, is
confusing, as pressing F6 again never returns the keyboard focus to the panel.
The more serious problem is that, at this point, even pressing CTRL+J doesn't
return focus to the panel: it's open but inaccessible. This is the same
behavior as the popup notifications, but I think it's a bug in both cases.

I think both panels should be dismissed as soon as they lose keyboard focus.
In fact, I managed to have two panels open, the identity panel and an add-on
installation request, overlapping each other. This is not the best experience
visually. I don't know what could be the best behavior as far as screen
readers are concerned, however.
(In reply to comment #249)
> Review of attachment 529878 [details] [diff] [review] [review]:

Thanks for the review! It's funny to see how many comments at this point are
about things I was in doubt to do in one way or the other, and eventually I
did in "the other way" :-) I think I'll count them for my own curiosity ;-)

> ::: browser/components/downloads/DownloadCommon.jsm
> @@ +16,5 @@
> > + * The Original Code is Download Manager Code.
> > + *
> > + * The Initial Developer of the Original Code is
> > + * Paolo Amadini <http://www.amadzone.org/>.
> > + * Portions created by the Initial Developer are Copyright (C) 2010-2011
> 
> just take one, we don't usually specify 2 years. This is usually the year
> you created the file first.

(1) I wonder why I even bothered to do an MXR search to see if there were
files with two recent years specified, and since they existed, I assumed two
years were required when the work before check-in spanned multiple years.
I knew that this modification would stand out in the interdiff though, so
someone would have told me if things were different :-)

> > +const DownloadCommon = {
> > +  /**
> > +   * Returns an object whose keys are the string names from the downloads string
> > +   * bundle, and whose values are either the translated strings or functions
> > +   * that can be used to obtain formatted strings.
> 
> nit: s/functions that can be used to obtain/getters for/

nit on nit: They're not getters, technically. I've rephrased and shortened
as "functions returning formatted strings".

> > +XPCOMUtils.defineLazyServiceGetter(DownloadCommon, "ms",
> > +                                   "@mozilla.org/mime;1",
> > +                                   "nsIMIMEService");
> 
> I see that is short, but to me ms sounds not very describing (indeed I was
> guessing why you had a microsummaries service getter). Why not just "mime"?

(2) Sticking to the convention of "lowercase initials of the words in the
interface name" didn't convince me either, but I wanted a second opinion :-)

> > +  get visible()
> > +  {
> > +    let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
> > +    return browserWin ? browserWin.DownloadsPanel.isPanelShowing : false;
> 
> this may have same .closed bug, even if less important since the object
> should still be there. Btw maybe you could add a simple _getBrowserWindow
> helper and use it in both places.

(3) Yeah, that was my reasoning. I opted for shorter code without the helper,
but since you recommend it too, I've now written the helper and referred to
the bug number in its comment.

> ::: browser/components/downloads/downloads.css
> @@ +1,5 @@
> > +/*** Download items ***/
> > +
> > +richlistitem[type="download"] {
> > +  -moz-binding: url('chrome://browser/content/downloads/download.xml#download');
> > +  -moz-box-orient: vertical;
> 
> out of curiosity, why is it needed to set content to horizontal in the
> binding and then orient to vertical in the style?

(4) I noticed this too, but didn't take the time to investigate if I could
remove it, as I've not started styling yet. Thanks for pointing it out
however, as I forgot to add this item to my local checklist and I could
have forgotten to verify it later.

> @@ +69,5 @@
> > +                                           .downloadShow,
> > +
> > +.download-state[state="7"]                 .downloadCommandsSeparator
> > +
> > +{
> 
> nit: fwiw, this file, regardless all the indentation tricks, doesn't seem
> particularly readable to me. But this is a coding style thing I leave to the
> module owner :)

(5) For some background regarding the choice of this CSS styling method,
see comment 157 and comment 160. If you have an idea to make the file
more readable using the same CSS styling method, it's welcome :-)

> ::: browser/components/preferences/tests/Makefile.in
> @@ +45,5 @@
> >  
> >  _BROWSER_FILES = \
> > +    browser_basic_functionality.js \
> > +    browser_delete_key_removes.js \
> > +    head.js \
> 
> just indent 2 spaces here
> 
> PS: Splinter seems to think this is
> browser/components/preferences/tests/Makefile.in, I was puzzled by that, but
> I see you hg copied that file, if possibile I'd suggest to rewrite this file
> since the copy blame is unrelated.

(6) You're not the first one, unfortunately, that gets confused by the fact
than review tools have problems with hg copies. Since writing these makefiles
from scratch is trivial, I'll just follow your suggestion.

> > +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
> > +/* vim: set ts=2 et sw=2 tw=80: */
> 
> Sdwilsh: does downloads component style guide require the mode and vim
> comments? (btw, tab-width seems wrong)

(7) I had the same doubt about tab-width and ts, the first time I saw these
lines in the style guide. Both are correct, we've already worked this out:
see bug 561472 comment 5. We also concluded that "Mode: C++" is valid for
the lack of a better, widely available Emacs mode.

> @@ +29,5 @@
> > +  for (yy in gen_resetState()) yield;
> > +  for (yy in gen_addDownloadRows(DownloadData)) yield;
> > +  for (yy in gen_openPanel()) yield;
> 
> some comment on each one of these would be welcome, it's a bit cryptic
> otherwise

(8) Ok, I also thought about adding comments but was afraid of over-commenting.

> @@ +37,5 @@
> > +  is(richlistbox.children.length, DownloadData.length,
> > +     "There is the correct number of richlistitems");
> > +  for (var i = 0; i < richlistbox.children.length; i++) {
> > +    var element = richlistbox.children[i];
> > +    var dataItem = new DownloadsViewItemController(element).dataItem;
> 
> nit: these seem good candidates for "let"

Yeah, I globally replaced "var" with "let" now.

> @@ +47,5 @@
> > +  // Clean up when the test finishes.
> > +  for (yy in gen_resetState()) yield;
> > +
> > +  gTestTargetFile.remove(false);
> 
> you should do this in registerCleanupFunction, remember that browser-chrome
> tests don't run in separate sandboxes, so you have to ensure any change you
> make is correctly cleaned up both if the test succeeds and if it fails.

Unfortunately, test infrastructure doesn't allow cleanup functions to be
asynchronous (regardless of the fact that we use generators or not):

http://mxr.mozilla.org/comm-central/source/mozilla/testing/mochitest/browser-test.js#169

My current thinking is that, for the first version, we should really cater
for the case where tests succeed, or fail without an exception or timing out.
The right, complete solution is to update the test infrastructure so that it
is possible to detect timeout, call the throw() function on the generator,
and allow the generator's stack to unwind so that all "finally" blocks are
called (with a second "unwind timeout", of course). I could outline the
required changes in a separate bug, but I don't think the implementation
should be done now or block the new Download Manager.

> Unless this cleanup code will be specific to only some of the tests you
> could even move that registerCleanupFunction to head.js (it works, really)

(9) We can group both initialization and cleanup code in a function in head.js.
I'll do that for sure if I have to add more tests with the same pattern.

> Object.keys(gDownloadRowTemplate).join(", "); ?
> Object.keys(gDownloadRowTemplate).map(function (v) ":" + v).join(", ");

Great suggestions, thanks!

> @@ +96,5 @@
> > +  try {
> > +    // Execute the statement for each of the provided downloads.
> > +    for ([, dataRow] in Iterator(aDataRows)) {
> > +      // Populate insert parameters from the provided data.
> > +      for (let [columnName] in Iterator(gDownloadRowTemplate)) {
> 
> just store columnNames as an array and join() it where needed?

The current way seems more readable to me. Enumerating an array or an object's
keys makes no big difference, and we have the object's keys already.

> @@ +1168,5 @@
> > +          currentset = currentset.replace(/(^|,)urlbar-container($|,)/,
> > +                                          "$1downloads-button,urlbar-container$2")
> > +        }
> > +        else {
> > +          currentset = "downloads-button," + currentset;
> 
> won't this put the button even before back/forward buttons?

(10) Yes. I hope that testers that removed the location bar from the
navigation toolbar won't get too upset by seeing the temporary downloads
button before the back/forward buttons instead of after them ;-)
My apologies, I know this is mentioned somewhere in this huge bug, but why was it decided to put the downloads button smack-bang in the middle of the navigational elements (back, forward _AND_ url bar) rather than either before or (preferably) after?
(In reply to comment #260)
> My apologies, I know this is mentioned somewhere in this huge bug, but why
> was it decided to put the downloads button smack-bang in the middle of the
> navigational elements (back, forward _AND_ url bar) rather than either
> before or (preferably) after?

It's explained in comment 215, basically the downloads button you see now is a
temporary placeholder, and this is not the final position of the panel for sure.
(In reply to comment #250)
> nit: per comments readability, double space after periods.

This requires going through all the comments again and changing the style
globally. I'd rather keep French-style spacing at this point, which I've
used consistently until now, but if both you and Shawn require it, I can
find some time to update the style before the patch lands.

> @@ +132,5 @@
> > +    DownloadsView.data = new DownloadsData(DownloadsView);
> > +    DownloadsView.data.initialize();
> 
> is there a case where you have to create a DownloadsData without invoking
> .initialize()? if not you could just merge initialize in the constructor

Hehe, you fell for it :-) It's correct that I always have to call "initialize"
after construction, but if I called it inside the constructor, it would be too
early, as the assignment to the "data" property would not have been executed.

(11) In theory, as "initialize" starts receiving events, it should only be
called after all the objects are hooked up and ready to handle the events
themselves. I considered renaming the functions to "start" and "stop" to
reflect that, though my doubt is that "stop" might look like an optional
call, while "terminate" looks like a mandatory call. What do you think?

> @@ +133,5 @@
> > +    window.addEventListener("unload", this.onWindowUnload, false);
> > +
> > +    DownloadsView.data = new DownloadsData(DownloadsView);
> > +    DownloadsView.data.initialize();
> > +    DownloadsViewController.initialize();
> 
> I think I'd rather provide a initialize() and terminate() in DownloadsView,
> and inside those init/terminate data and controller.
> So the flow here on panel opening is just "we init a view for this panel"
> and on close "we terminate a view for this panel"

Well, as I understand it, from a pure MVC design point of view, the View
shouldn't reference the Controller or be responsible for its initialization.
It's true that I've implemented View and Controller separation very loosely,
to favor code simplicity where appropriate, but by the same principle we
might as well avoid to write two other methods that would be called once.

> @@ +200,5 @@
> > +    this.panel.hidePopup();
> > +
> > +    // Ensure that we allow the panel to be reopened, even if the popup was
> > +    // already hidden and the onPopupHidden event was not invoked.
> > +    this._panelState = this.kPanelHidden;
> 
> is not this already done by onPopupHidden?

Maybe you've just overlooked the comment here, but if the comment is not
clear then suggestions to improve it are welcome :-)

> > +  get isPanelShowing() {
> > +    return this._panelState == this.kPanelShowing ||
> > +           this._panelState == this.kPanelShown;
> > +  },
> 
> I'd suggest to use the short form (no braces and no return) but I think
> Sdwilsh would be unhappy about that :p

Yeah :-)

> > +XPCOMUtils.defineLazyGetter(DownloadsPanel, "panel", function()
> > +                            document.getElementById("downloadsPanel"));
> 
> nit: move function () on the same line as getElementById if it doesn't go
> over 80 chars

It does...

> > +/**
> > + * Builds and updates the downloads list widget, responding to changes in the
> > + * download state and real-time data. In addition, handles part of the user
> > + * interaction events raised by the downloads list widget.
> 
> nit: "real-time data" is a bit generic.

(12) Intentionally? I generally strive to write comments that can be robust
to future modifications in other areas of the code, while still providing an
overall idea of what they're describing, but without being pleonastic with
code written in their immediate surroundings. Of course this is not easy at
all :-) In this case, the solution I chose was to use "state" as a
definition-by-example of the more general group "real-time data". I
even thought that "real-time data" could look a bit generic, but couldn't
come up with a better term or formulation. If you have an idea, it's welcome!

And if you're smiling about how much thought I put in advance in every
secondary detail, you should know that I am smiling about that too :-) But
I see this frame of thought is quite encouraged here! (which I appreciate)

Given the number of items on which I could and would have asked a second
opinion beforehand, I'm also thinking about how being in the same room,
with over-the-shoulder review, makes things a lot faster with regard to
small things like these ones!

[Now I'm taking a break before working on all the following review items...]
> > is not this already done by onPopupHidden?
> 
> Maybe you've just overlooked the comment here, but if the comment is not
> clear then suggestions to improve it are welcome :-)

Well, the comment may say when that could happen, since looks strange that a popup closes without notifying onpopuphidden.

Regarding "real-time data", I mostly found puzzling to figure out which kind of data, if it was referring to real-time download statistics.

Regarding the comments nit, it's a nit, reviews don't block on those.
(In reply to comment #263)
> > Maybe you've just overlooked the comment here, but if the comment is not
> > clear then suggestions to improve it are welcome :-)
> 
> Well, the comment may say when that could happen, since looks strange that a
> popup closes without notifying onpopuphidden.

Updated, thanks!

> Regarding "real-time data", I mostly found puzzling to figure out which kind
> of data, if it was referring to real-time download statistics.

Not only statistics. I'll have to think if there can be a better term and
update the comment in case I find one.

> Regarding the comments nit, it's a nit, reviews don't block on those.

Yes, I imagine. I'm not trying to be serious in most of my replies to those
nits :-) I hope it's not a problem if I reply in a playful way!

(In reply to comment #250)
> @@ +350,5 @@
> > +  _addOrMoveElementToTop: function DV_addOrMoveElementToTop(aElement, aDataItem)
> > +  {
> > +    // Items that are done are inserted before all other items.
> > +    if (aDataItem.done) {
> > +      this.richListBox.insertBefore(aElement, this.richListBox.firstChild);
> 
> should you unset this.firstElementInProgress and this.firstElementNotDone if
> they are same as aElement?
> 
> > +    if (!aDataItem.inProgress) {
> > +      this.richListBox.insertBefore(aElement, this.firstElementNotDone);
> > +      this.firstElementNotDone = aElement;
> 
> should you unset this.firstElementInProgress if it's aElement?

This is done in _beforeRemoveElement, if I understand your comments correctly.

> @@ +430,5 @@
> > +    // otherwise it means that no such element exists anymore.
> > +    if (aElement != this.firstElementNotDone ||
> > +        aElement != this.firstElementInProgress) {
> > +      return;
> > +    }
> 
> shouldn't this be an AND? if aElement is going away you should ensure it's
> not used in both.

Good catch! I missed this while inverting the condition.

> @@ +453,5 @@
> > +    }
> > +    if (aElement == this.firstElementInProgress) {
> > +      this.firstElementInProgress = nextDataItem.inProgress ? nextElement
> > +                                                            : null;
> > +    }
> 
> Unless DownloadsViewItemController() is much expensive I think inverting the
> ifs could be more readable:

(13) It's a lookup in the dictionary of active downloads. I'm not sure how
much expensive it could become when there are many downloads. Even if I
don't think it's significant, in doubt I preferred to ensure that we don't
do two lookups unnecessarily (originally I wrote the ifs like you suggested).

> @@ +461,5 @@
> > +   * Called when the number of download items in the list changes.
> > +   */
> > +  _itemCountChanged: function DV_itemCountChanged()
> > +  {
> > +    // Note that the "itemCount" property may not be available now.
> 
> clarify comment please (Add when and why, "now" is not enough)

Ah, this time you caught me out! I didn't remember for sure in which cases the
property was not available anymore. But I've now verified that it happens
before the panel is shown for the first time, because XBL bindings haven't
been applied yet.

> @@ +486,5 @@
> > +  {
> > +    let previousSelectedIndex = this.richListBox.selectedIndex;
> > +    this._beforeRemoveElement(aElement);
> > +    this._addOrMoveElementToTop(aElement, aDataItem);
> > +    this.richListBox.selectedIndex = previousSelectedIndex;
> 
> What if I selected this specific element, should not the selection follow it?

(14) Well, maybe it should, if it's the only selected element, but maybe not
if there are multiple elements selected, even if it's the currently focused
element. In general, I think that the mere fact that elements change their
position in the list might be confusing for keyboard navigation. Probably
we should leave the exact selection mechanics for a later phase.

> @@ +550,5 @@
> > +   * @param aNewest
> > +   *        When true, indicates that this item is the most recent and should be
> > +   *        added in the topmost position of its category. This happens when a
> > +   *        new download is started. When false, indicates that the item is the
> > +   *        least recent with regard to the items that have been already added.
> 
> "least recent" or just "not the most recent"?

Least recent. Please don't ask to change aNewest to an enum for clarity :-)

> @@ +551,5 @@
> > +   *        When true, indicates that this item is the most recent and should be
> > +   *        added in the topmost position of its category. This happens when a
> > +   *        new download is started. When false, indicates that the item is the
> > +   *        least recent with regard to the items that have been already added.
> > +   *        This generally happens during the initial data load, when we want
> 
> What is "this", that is set to true?

That is set to false. I've now replaced "this" with "the latter".

> @@ +625,5 @@
> > +      return;
> > +    }
> > +
> > +    // Find the richlistitem for the download and execute the command.
> > +    for (; target.nodeName != "richlistitem"; target = target.parentNode);
> 
> better avoiding empty-body for loops, they are confusing and error-prone.
> use a while instead:
> while (target.nodeName != "richlistitem") {
>   target = target.parentNode;
> }

I prefer this way too. The fact that you suggested using such a loop in
attachment 526902 [details] made me think you preferred one-liners.

> @@ +635,5 @@
> > +    // Double clicks on buttons should not invoke the default action.
> > +    if (aEvent.originalTarget.hasAttribute("command") ||
> > +        aEvent.originalTarget.hasAttribute("oncommand")) {
> > +      return;
> > +    }
> 
> aEvent.preventDefault() ? or you're just trying to skip next code?

Yes, "default action" in the sense of "the default action associated with the
download item". I've clarified the comment, thanks!

Note: I'm skipping review comments on how to improve the drag-and-drop section
for now. There is no way to drop something on the panel after all :-) Drop
handling will move to the download progress indicator. The new functions
accessible from Services.droppedLinkHandler are cool however!

> @@ +725,5 @@
> > +  this.dataItem = aDataItem;
> > +
> > +  this.previousDone = this.dataItem.done;
> > +  this.previousInProgress = this.dataItem.inProgress;
> > +  this.lastSeconds = Infinity;
> 
> I don't have any idea what lastSeconds represents, better name?

My impression is that you have a score to settle with the current Download
Manager... not a single name or code line can escape and find their way in
the new code :-)

"lastSeconds", or "lastSec", is the name of an opaque parameter of the
"getDownloadStatus" function in the "DownloadUtils" module. It's used to
calculate the remaining download time more accurately. The comment says:
"Last time remaining in seconds or Infinity for unknown". Given this, what
do you think a better name could be?

> @@ +737,5 @@
> > +    "state": this.dataItem.state,
> > +    "progress": this.dataItem.inProgress ? this.dataItem.percentComplete : 100,
> > +    "target": this.dataItem.target,
> > +    "image": this.image
> > +  };
> 
> const

Can you explain the rationale of using "const" here? I often use "let" in a
lot of cases where the rest of the function doesn't change the variable's
value. Are "const" assignments re-evaluated when re-entering the same
function? (I couldn't find this documented.) If so, does it still make
sense to use "const"?

> @@ +777,5 @@
> > +      try {
> > +        // Refresh the icon, so that executable icons are shown. Tacking on
> > +        // contentType bypasses cache.
> > +        this.image += "&contentType=" + DownloadCommon.ms.getTypeFromFile(
> > +                                                       this.dataItem.localFile);
> 
> rephrase comment and fix indentation a bit

Another couple of lines that didn't escape :-)

> > +      let newLast;
> 
> better var name

It's the same declared name as the function's output. Suggestions?

> @@ +904,5 @@
> > +   * Updates the time that gets shown for completed download items.
> > +   */
> > +  _updateTime: function DVI_updateTime()
> > +  {
> > +    // Don't bother updating for things that aren't finished.
> 
> "things"?

Another line from the original Download Manager! You're a killer!

> @@ +1057,5 @@
> > +  {
> > +    // Update all the commands that are specific for the selected item.
> > +    for ([cmd] in Iterator(DownloadsViewItemController.prototype.commands)) {
> > +      goUpdateCommand(cmd);
> > +    }
> 
> why not just for (cmd in DownloadsViewItemController.prototype.commands) ?

For the reason outlined in comment 182: excluding enumerable properties
coming from the object's prototype chain.
Regarding selection and D&D, I guess you have a todo, would be fine to expose it somewhere and link it in the url field of this bug (either a feature page on the wiki, or an etherpad).

> "lastSeconds", or "lastSec", is the name of an opaque parameter of the
> "getDownloadStatus" function in the "DownloadUtils" module.

That rounding code is awesome :p
Maybe something like lastKnownSecondsLeft, lastCachedSecondsLeft, lastCachedRemainingTime, lastRemainingSeconds.
Actually my favorite (apart being verbose) is lastEstimatedSecondsLeft

> Can you explain the rationale of using "const" here?

Actually, mostly because it actually is const data, but I don't have that level of knowledge of js internals to have a strong opinion on it, consider it a nit.

> > > +      let newLast;

I see this is in couple with the above one, newEstimatedSecondsLeft?
(In reply to comment #265)
> Regarding selection and D&D, I guess you have a todo, would be fine to
> expose it somewhere and link it in the url field of this bug (either a
> feature page on the wiki, or an etherpad).

Excellent, doing this was already in my todo list ;-) I planned to start
cleaning up and publishing the todo list after code review, maybe I can
anticipate it to sometime near the end of this week.

> Actually my favorite (apart being verbose) is lastEstimatedSecondsLeft

Works for me too! We have the required horizontal space :-)

(In reply to comment #250)
> > +        // Refresh the icon, so that executable icons are shown. Tacking on
> > +        // contentType bypasses cache.
> > +        this.image += "&contentType=" + DownloadCommon.ms.getTypeFromFile(
> > +                                                       this.dataItem.localFile);

Digression on this one: I took some time to understand why we are adding the
contentType, and after reading the documentation and some experimentation, it
turns out that changing any parameter supported by nsIMozIconURI works as a
way of forcing the image to be reloaded (adding other parameters such as
"&the_usual_trick_to_force_reloading_urls=random_number" has no effect).

In the end, this line is enough:

this._element.setAttribute("image", this.image + "&state=normal");

We don't even need to call the MIME service for getting the content type, the
"moz-icon" channel already does that for us.

Documentation in the source code:

http://mxr.mozilla.org/mozilla-central/source/modules/libpr0n/decoders/icon/nsIIconURI.idl#42

http://mxr.mozilla.org/comm-central/source/mozilla/modules/libpr0n/test/unit/test_moz_icon_uri.js#9

History of changes / blame / annotation for that part of the code:

http://hg.mozilla.org/mozilla-central/diff/d4f5ebf5c55f/toolkit/mozapps/downloads/content/downloads.js#l1.135

http://bonsai.mozilla.org/cvsview2.cgi?diff_mode=context&whitespace_mode=show&root=/cvsroot&subdir=mozilla/toolkit/mozapps/downloads/content&command=DIFF&root=/cvsroot&file=downloads.js&rev1=1.20&rev2=1.21

https://bugzilla.mozilla.org/show_bug.cgi?id=236988
(In reply to comment #250)
> > +    let end = new Date(parseInt(this.dataItem.endTime));
> 
> why do you need to parseInt this here, shouldn't rather that be done on
> setting the property?

Correct, no need to parseInt as endTime is always of the number data type,
resulting from Date.now() or Math.round().

> @@ +1132,5 @@
> > +    // Invoke the command, if enabled, using this object for "this".
> > +    if (this.isCommandEnabled(aCommand)) {
> > +      this.commands[aCommand].apply(this);
> 
> I think you could actually use .bind(this) when defining the functions and
> avoid these apply.

Actually, using "apply" is simpler here, because these functions are defined
on the object's prototype, and using "bind" (as I've seen it used elsewhere)
would require enumerating all the commands in the object's constructor, to
use only one of them. And, of course, there is no point in just doing
".bind(this)()" instead of "apply(this)".

> > +  _getOrAddDataItem: function DD_getOrAddDataItem(aSource)
> 
> I'd just rename it to fetchDataItem, where it fetches it doesn't matter.

nit: I prefer getOrAdd since the function may invoke "onDataItemAdded"
(the "add" case) or may not do it (the "get" case).

> > +    dataItem.startTime = Math.round(aDownload.startTime / 1000);
> 
> I think you may want to parseInt here, any reason to keep a double?

The JavaScript documentation says that the result of Math.round is already an
integer. More exactly, it's an instance of the general number data type.

> @@ +1713,5 @@
> > +    // Compute the other properties without accessing the download object.
> > +    this.resumable = true;
> 
> is this always true?

No, you're right: this could actually result in a bug for which a running
download would look resumable if the panel is opened in a different window
from the one where the download started. Unfortunately, there is no way to
know the value of the property without accessing the underlying download
object, but I think that, for running downloads, we can access the object
without performance degradation. I've updated the code.

> @@ +1748,5 @@
> > +  get starting()
> > +  {
> > +    return this.state == nsIDM.DOWNLOAD_NOTSTARTED ||
> > +           this.state == nsIDM.DOWNLOAD_QUEUED;
> > +  },
> 
> I'd drop braces and return (if sdwilsh allows)

Doesn't ;-) By the way, at present here I have one-liners with short "get"
syntax mixed with with two-liners with normal "get" syntax. I'd rather be
consistent (for example, always use normal syntax). What do you think?
(In reply to comment #267)
I'm doing some experiment with bind(), will let you know if I figure out a better way.

> The JavaScript documentation says that the result of Math.round is already an
> integer. More exactly, it's an instance of the general number data type.

ehr, I misread that line as having a division out of the round, sorry.

> Doesn't ;-) By the way, at present here I have one-liners with short "get"
> syntax mixed with with two-liners with normal "get" syntax. I'd rather be
> consistent (for example, always use normal syntax). What do you think?

I can't tell, personally I'd go for the short syntax everytime there is only a short return condition, so it doesn't affect readability, but it's up to the module owner to decide the code style for the module. Both ways being consistent is a win.
Depends on: 492960
(In reply to comment #267)
> Doesn't ;-) By the way, at present here I have one-liners with short "get"
> syntax mixed with with two-liners with normal "get" syntax. I'd rather be
> consistent (for example, always use normal syntax). What do you think?
My rule of thumb is if it spans more than one line, use the long syntax (equivalent to brace all ifs), and if it doesn't, do whichever you want.
Here is the updated patch. Thank you very much for the detailed review, Marco!
I'll let you check if I've interpreted your comments correctly before requesting
code review from Shawn and generating another tryserver build.
Attachment #529878 - Attachment is obsolete: true
Attachment #533137 - Flags: feedback?(mak77)
Comment on attachment 533137 [details] [diff] [review]
Improved version with review comments addressed

Review of attachment 533137 [details] [diff] [review]:
-----------------------------------------------------------------

notice I only looked at the patches diff, it looks fine based on my comments.  Thanks for so much patience on them :)

::: browser/components/downloads/Makefile.in
@@ +1,2 @@
> +# Any copyright is dedicated to the Public Domain.
> +# http://creativecommons.org/publicdomain/zero/1.0/

Ehr, I think you cannot use the pd license in Makefile, that license can only be used in test files.

::: browser/components/downloads/downloads.js
@@ +259,5 @@
> +  },
> +
> +  onPopupShown: function DO_onPopupShown(aEvent)
> +  {
> +    // Ignore events raised by children.

nit: by nested popups.

@@ +269,5 @@
> +  },
> +
> +  onPopupHidden: function DO_onPopupHidden(aEvent)
> +  {
> +    // Ignore events raised by children.

nit: by nested popups.

::: browser/installer/package-manifest.in
@@ +306,5 @@
>  #endif
>  @BINPATH@/components/nsHelperAppDlg.manifest
>  @BINPATH@/components/nsHelperAppDlg.js
> +@BINPATH@/components/DownloadManagerUI.manifest
> +@BINPATH@/components/DownloadManagerUI.js

I think you may have to update removed-files.in. Right now nsDownloadManagerUI.manifest and nsDownloadManagerUI.js are removed for omnijar, I've no idea if there are still non-omnijar consumers around though. If so those files should probably be moved out of the omnijar ifdef in removed-files.in
Attachment #533137 - Flags: feedback?(mak77) → feedback+
Comment on attachment 533137 [details] [diff] [review]
Improved version with review comments addressed

Thanks Marco! I think the patch is ready to be reviewed by Shawn (noting that
the few modifications in comment 271 will be addressed in the next version).
I'll provide an updated patch and try building it on the tryserver after that.

Regarding the licensing policy, I re-read it again and my interpretation is
that makefiles are not Product Code because they're merely part of a system
used to build the product, and no part of those files ends up in the binaries:

http://www.mozilla.org/MPL/license-policy.html

"Product Code means all files any part of which are included in nightly
binaries of the Mozilla family of Internet clients - Firefox, Thunderbird,
SeaMonkey and Camino. Note that this definition excludes the code of tools
used merely to build these products, such as system libraries."

While many parts of the build system are complex and worth of copyright
protection, the particular makefiles in my patch are really trivial, and
there's little creativity in them, because they cannot be written in a
significantly different way. As such, my interpretation is that these
particular makefiles could be covered by the Trivial Support Code Exception:

http://www.mozilla.org/MPL/license-policy-flowchart.png

This should give the option of including those files in the tree and retain
their public domain status. This avoids including a boilerplate text which
would be longer than the file itself.

Note that I've already dedicated those few lines to the public domain in my
patch. This is relevant in case someone thinks they are copyrightable at all,
which I doubt given that there's little or no creativity in them. Adding a
copyright notice now will have no practical effect, except if someone updates
the file in the future, that however, given the nature of the file, I expect
to be limited to mechanical work only.

Also note that I've dedicated to the public domain all the Mozilla test code
I wrote, despite it's not so trivial (in fact, we've already discussed many
little details about test implementation).

I hope I've made my point, but in doubt we can consult the licensing team.
Attachment #533137 - Flags: review?(sdwilsh)
(In reply to comment #272)
> While many parts of the build system are complex and worth of copyright
> protection

I think it's not much about strict copyright protection.  Btw, I mostly commented about that, because this is the first Makefile.in I see with that license, so it's worth figuring out if for future we can reduce the boilerplate in these files. I will ping Gerv and ask :)

> Also note that I've dedicated to the public domain all the Mozilla test code
> I wrote, despite it's not so trivial

Be clear, you don't have to, if you don't want.  We suggest doing it just for a shorter boilerplate (I think MPL2 will also have that benefit).
(In reply to comment #273)
> Be clear, you don't have to, if you don't want.  We suggest doing it just for a
> shorter boilerplate (I think MPL2 will also have that benefit).
Also because it means that anybody can then use that code (so our test files become good documentation).
(In reply to comment #273)
> I think it's not much about strict copyright protection.  Btw, I mostly
> commented about that, because this is the first Makefile.in I see with that
> license, so it's worth figuring out if for future we can reduce the
> boilerplate in these files. I will ping Gerv and ask :)

This also was my personal motivation for writing comment 272 :-) Feel free
to point Gerv to it if he's the person to ask!

> > Also note that I've dedicated to the public domain all the Mozilla test code
> > I wrote, despite it's not so trivial
> 
> Be clear, you don't have to, if you don't want.  We suggest doing it just
> for a shorter boilerplate (I think MPL2 will also have that benefit).

Yes, by reading the policy I also understood it was not required, though
recommended (the flowchart is just a quick summary in this regard).

(In reply to comment #274)
> Also because it means that anybody can then use that code (so our test files
> become good documentation).

This is a good point.
(In reply to comment #258)
> (In reply to comment #236)
> > 2. Problem: When tabbing from the list onwards, I hit the "Open" button
> > twice. Once it's a sub menu button, the second a regular button. The next
> > thing in the tab order is the "Show download history" button. Why these two
> > tabstops on the Open button?
> 
> I verified that this is the same behavior as the menu-button in the popup
> notifications (for example, the one that is opened when you click an add-on
> download link in any website). Pressing ALT+Down (on Windows) opened the
> drop-down menu only when focus was on the part of the button with the down
> arrow, not on the main button. Maybe this is the expected behavior of XUL
> menu-buttons? If not, I think a different bug should be filed.

All right, yes this is also already being discussed in bug 616136 which exhibits a similar issue.

> > 4. Problem: The panel does not announce itself as being the downloads panel
> > any more. The old window had a title screen readers were able to read. How
> > is it conveyed visually that this is the Downloads window? If through some
> > sort of image, we'll have to apply some WAI-ARIA magic to also give the
> > panel a label.
> I'd like to be initiated to this kind of magic :-) Which is the method
> you have in mind for implementing this panel labeling? Which is the method
> that is currently used for labeling the "popup notifications" panel, if any?

The notification popup does not have a label, but it has explanatory text (like "Do you want to save the password..."). The reason I asked how this panel is labelled visually is exactly to determine which method to use for labelling it for screen readers.

The simplest is to put an aria-label attribute pointing to a string that contains a human-readable label, for example the same that was used for the old "Downloads" window.
However, if there is an image labelling this panel, then that should receive alternative text (like a tool-tip text or something), and the attribute aria-labelledby should be used, with its value being the ID of the labelling element (in my example, the image).

> > It should also get a proper role, since it is currently
> > non-existent in the a1y hierarchy and needs to be a container. This is done
> > by applying the role attribute to the panel itself. The available roles can
> > be found in the wAI-ARIA documentation:
> > http://www.w3.org/TR/wai-aria/roles#role_definitions
> > For this case, a role of dialog is probably most appropriate, or group, we'd
> > need to test those.
> Which tools can I use to do a basic verification that the panel is included
> in the accessibility hierarchy, if I assign a role attribute to it?

If you assign the role attribute, you can be sure it is included, because *everything* that has the role attribute set also gets an accessible object created for it.
I am not certain about the current status of DOM Inspector, but it used to also have a working accessibility inspector. Note that this currently only works on Linux and Windows, not on mac, since accessibility isn't turned on for Mac OS X yet.

Regarding the dismissal of the panels, the most important rule is: Be consinstent, not confusing. ;)
This review should happen on Monday.
*NEW PANEL-BASED DOWNLOAD MANAGER TRACKING PAGE*

I've polished and published my local list of open tasks, turning it into a
tracking page that I'll use to make sure that all issues raised on this
specific bug, and its dependencies, are addressed before the work is finished.

Formatting could be improved, but the status information I have is all there:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager



*NEW DOWNLOAD USER EXPERIENCE IMPROVEMENTS SUMMARY PAGE*

I've also reviewed and published a more general page that shows how this
feature fits in the overall download manager user experience improvements.
This is important because all the other features listed in that page are
"next steps", and explicit non-goals of this first part of the overall
improvements. The page is available here:

https://wiki.mozilla.org/User:P.A./Download_user_experience_improvements



*FEEDBACK*

Since there are now many places where possible download manager improvements
are described, and many different pieces of the puzzle are on the table, it's
important that feedback about each piece is provided using the right channels.

Comments directly relevant to the work that is being done in this bug
(downloads panel coding, development, implementation, as well as reviews
from the Accessibility, Development, Localization and User Experience teams)
should be posted here. I'll periodically update the tracking page according
to new comments and solved items.

For more general feedback or suggestions about the design, or about the
other features that are not being developed here, the usability forum is
probably the best place:

http://www.mozilla.org/about/forums/#dev-usability
(In reply to comment #278)
> https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager
That page is simply awesome.  Thanks so much for doing that!
Comment on attachment 533137 [details] [diff] [review]
Improved version with review comments addressed

Review of attachment 533137 [details] [diff] [review]:
-----------------------------------------------------------------

You should have fryn or dao look over your css and xbl changes as they are far better practiced in writing and reviewing that stuff than I am right now.

I didn't look at the tests either, but I trust mak to have caught any issues there at this point (I'm also all reviewed out at this point).

r=sdwilsh with comments addressed (yay!)

::: browser/components/downloads/DownloadCommon.jsm
@@ +85,5 @@
> +      if (stringName in kDownloadsStringsRequiringFormatting) {
> +        strings[stringName] = function() {
> +          // Convert "arguments" to a real array before calling into XPCOM
> +          return sb.formatStringFromName(stringName,
> +                                         Array.prototype.slice.call(arguments),

I'm 95% sure you don't need 'prototype' here.  Additionally, the first argument to slice is required and should be zero (you aren't passing in anything here, which amusingly seems to work but I'd rather not depend on that working).

@@ +99,5 @@
> +};
> +
> +XPCOMUtils.defineLazyServiceGetter(DownloadCommon, "dm",
> +                                   "@mozilla.org/download-manager;1",
> +                                   "nsIDownloadManager");

We should probably just add this to Services.jsm at this point and not include it here.  Everything can then just import that.

::: browser/components/downloads/DownloadManagerUI.js
@@ +91,5 @@
> +  /**
> +   * Returns the most recent browser window that is not closed, or null if no
> +   * such window exists. This helper function will be required at least until
> +   * bug 528706 (nsIWindowMediator::getMostRecentWindow should not return closed
> +   * windows) is fixed.

Can you file a bug about this explicitly, mark it dependent on that bug, and reference the bug number that you file here please?

::: browser/components/downloads/download.xml
@@ +83,5 @@
> +                             tooltiptext="&cmd.pausedisabled.tooltiptext;"
> +                             disabled="true"/>
> +          <xul:toolbarbutton class="downloadButton downloadResume"
> +                             tooltiptext="&cmd.resume.label;"
> +                             oncommand="DownloadsView.onItemCommand(event, 'downloadsCmd_resume');"/>

Why are these xul:toolbarbuttons as opposed to xul:button?  They aren't in a toolbar, so I'm fairly certain they should be xul:buttons instead (especially since you use xul:button further down).

@@ +95,5 @@
> +                             flex="1"
> +                             class="downloadProgressRunning"
> +                             min="0"
> +                             max="100"
> +                             xbl:inherits="mode=progressmode,value=progress"/>

Why did you opt for using three different progressmeters here instead of having one and changing its attributes (via xbl:inherits)?  I'm worried that the current approach makes this binding more expensive.

::: browser/components/downloads/downloads.css
@@ +13,5 @@
> +/*** Visibility of controls inside download items ***/
> +
> +.download-state:-moz-any(     [state="6"], /* Blocked     */
> +                              [state="8"], /* Blocked     */
> +                              [state="9"]) /* Blocked     */

Can you make the Blocked comment a little more detailed?  For example:
[state="8"], /* Bocked (DIRTY) */
This comment applies to the rest of the times you do this in this file.

::: browser/components/downloads/downloads.js
@@ +55,5 @@
> + *
> + * DownloadsView
> + * Builds and updates the downloads list widget, responding to changes in the
> + * download state and real-time data. In addition, handles part of the user
> + * interaction events raised by the downloads list widget.

I know mak commented on this, and this is a super nitty nit, but I'd really prefer to see two spaces after punctuation.  That is the dominant style throughout Mozilla code, as well.  With that being said, I'm not going to ask you to change it all.  That's your call.

@@ +89,5 @@
> +Cu.import("resource://gre/modules/DownloadUtils.jsm");
> +Cu.import("resource:///modules/DownloadCommon.jsm");
> +
> +const nsLocalFile = Components.Constructor("@mozilla.org/file/local;1",
> +                                           "nsILocalFile", "initWithPath");

Make this lazy please (with XPCOMUtils.defineLazyGetter)

@@ +218,5 @@
> +
> +  /**
> +   * Indicates whether the panel is shown or will be shown.
> +   */
> +  get isPanelShowing() {

nit: brace goes on a newline

@@ +388,5 @@
> +   *        XUL element associated with the download item. If the element is
> +   *        already in the list, it is moved to the appropriate position.
> +   *
> +   * @param aDataItem
> +   *        DownloadsDataItem that is being added or moved.

global-nit: no newlines between @param statements

@@ +910,5 @@
> +
> +      // We use the same XUL label to display both the state and the amount
> +      // transferred, separating them with the Unicode character U+2014 'EM
> +      // DASH'. For example, "Paused -  1.1 MB".
> +      status = DownloadCommon.strings.statePaused + " \u2014  " + transfer;

This doesn't feel very l10n friendly (namely rtl languages).

@@ +925,5 @@
> +    } else if (this.dataItem.state == nsIDM.DOWNLOAD_SCANNING) {
> +      status = DownloadCommon.strings.stateScanning;
> +    } else if (!this.dataItem.inProgress) {
> +      let stateLabel = function()
> +      {

nit: for inline functions like this, the brace should go on the same line as function()

@@ +943,5 @@
> +
> +      // We use the same XUL label to display both the state and the host name,
> +      // separating them with the Unicode character U+2014 'EM DASH'. For
> +      // example, "Canceled - 222.net" or "1.1 MB - website2.com".
> +      status = stateLabel + " \u2014 " + displayHost;

same here regarding l10n/rtl friendliness.

@@ +1238,5 @@
> +        try {
> +          dontAsk = !Services.prefs.getBoolPref(this.kPrefBdmAlertOnExeOpen);
> +        } catch (ex) { }
> +
> +#ifdef XP_WIN

If we can avoid prepocessing this file by some checks in JavaScript, I'd be a happier man.

@@ +1406,5 @@
> +  _openExternal: function DVIC_openExternal(aFile)
> +  {
> +    let protocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
> +                      .getService(Ci.nsIExternalProtocolService);
> +    protocolSvc.loadUrl(Services.io.newFileURI(aFile));

I'd prefer to see you use NetUtil.newURI here.

::: toolkit/components/downloads/Makefile.in
@@ +72,5 @@
>  # XXX - Until Suite builds off XULRunner we can't guarantee our implementation
>  # of nsIDownloadManagerUI overrides toolkit's.
> +# This is also disabled when building the "browser" application since it also
> +# has its own implementation of nsIDownloadManagerUI.
> +ifneq (browser,$(MOZ_BUILD_APP))

I think the right way to work around this problem is to just unregister the default component in final-ui-startup in browser land for the contract id.  I'm saying this without doing a whole lot of investigation to make sure that would work though...
Attachment #533137 - Flags: review?(sdwilsh) → review+
(In reply to comment #280)
> r=sdwilsh with comments addressed (yay!)

Yay! :-)

> ::: browser/components/downloads/download.xml
> @@ +83,5 @@
> > +                             tooltiptext="&cmd.pausedisabled.tooltiptext;"
> > +                             disabled="true"/>
> > +          <xul:toolbarbutton class="downloadButton downloadResume"
> > +                             tooltiptext="&cmd.resume.label;"
> > +                             oncommand="DownloadsView.onItemCommand(event, 'downloadsCmd_resume');"/>
> 
> Why are these xul:toolbarbuttons as opposed to xul:button?  They aren't in a
> toolbar, so I'm fairly certain they should be xul:buttons instead
> (especially since you use xul:button further down).

The popup notifications used toolbarbuttons too, because this way you avoid
writing the additional CSS that is required to style the button as images,
I guess. Maybe ask Gavin?

> @@ +95,5 @@
> > +                             flex="1"
> > +                             class="downloadProgressRunning"
> > +                             min="0"
> > +                             max="100"
> > +                             xbl:inherits="mode=progressmode,value=progress"/>
> 
> Why did you opt for using three different progressmeters here instead of
> having one and changing its attributes (via xbl:inherits)?  I'm worried that
> the current approach makes this binding more expensive.

This just allowed to style the progress bars differently, without the
JavaScript needing additional code. Currently they all have the same style,
though, so having a single progress bar and a little bit more JavaScript
code might actually be better.

> ::: browser/components/downloads/downloads.js
> @@ +55,5 @@
> > + *
> > + * DownloadsView
> > + * Builds and updates the downloads list widget, responding to changes in the
> > + * download state and real-time data. In addition, handles part of the user
> > + * interaction events raised by the downloads list widget.
> 
> I know mak commented on this, and this is a super nitty nit, but I'd really
> prefer to see two spaces after punctuation.  That is the dominant style
> throughout Mozilla code, as well.  With that being said, I'm not going to
> ask you to change it all.  That's your call.

Since you both ask, I'll make a note to do that before the final checkin :-)

> @@ +910,5 @@
> > +
> > +      // We use the same XUL label to display both the state and the amount
> > +      // transferred, separating them with the Unicode character U+2014 'EM
> > +      // DASH'. For example, "Paused -  1.1 MB".
> > +      status = DownloadCommon.strings.statePaused + " \u2014  " + transfer;
> 
> This doesn't feel very l10n friendly (namely rtl languages).

This is actually an open item from comment 253. It seems that RTL languages
don't need to change the order of those strings. See for example:

http://mxr.mozilla.org/l10n-central/search?string=paused%3D

Note that for Arabic you might see text like "1#  - " because of the
directionality change in the text, but the string is still " -  #1".

> @@ +1238,5 @@
> > +        try {
> > +          dontAsk = !Services.prefs.getBoolPref(this.kPrefBdmAlertOnExeOpen);
> > +        } catch (ex) { }
> > +
> > +#ifdef XP_WIN
> 
> If we can avoid prepocessing this file by some checks in JavaScript, I'd be
> a happier man.

Nice! I'd also prefer that.

> ::: toolkit/components/downloads/Makefile.in
> @@ +72,5 @@
> >  # XXX - Until Suite builds off XULRunner we can't guarantee our implementation
> >  # of nsIDownloadManagerUI overrides toolkit's.
> > +# This is also disabled when building the "browser" application since it also
> > +# has its own implementation of nsIDownloadManagerUI.
> > +ifneq (browser,$(MOZ_BUILD_APP))
> 
> I think the right way to work around this problem is to just unregister the
> default component in final-ui-startup in browser land for the contract id. 
> I'm saying this without doing a whole lot of investigation to make sure that
> would work though...

Seems strange to me, because we know at build time that we don't need that
component. We shouldn't probably include neither the component nor the old
UI at all.
(In reply to comment #281)
> The popup notifications used toolbarbuttons too, because this way you avoid
> writing the additional CSS that is required to style the button as images,
> I guess. Maybe ask Gavin?
Ah, I didn't think of checking the other things like that.

> This is actually an open item from comment 253. It seems that RTL languages
> don't need to change the order of those strings. See for example:
> 
> http://mxr.mozilla.org/l10n-central/search?string=paused%3D
> 
> Note that for Arabic you might see text like "1#  - " because of the
> directionality change in the text, but the string is still " -  #1".
Can you check with l10n please?  I'm still worried even if no locale currently does it differently.

> Seems strange to me, because we know at build time that we don't need that
> component. We shouldn't probably include neither the component nor the old
> UI at all.
Then we have no way to test it, which isn't acceptable (just because Firefox doesn't use it, it doesn't mean that it becomes unsupported in toolkit).  You can ask Dave Townsend (toolkit module owner) what he thinks is acceptable here.
(In reply to comment #281)
> > ::: browser/components/downloads/download.xml
> > @@ +83,5 @@
> > > +                             tooltiptext="&cmd.pausedisabled.tooltiptext;"
> > > +                             disabled="true"/>
> > > +          <xul:toolbarbutton class="downloadButton downloadResume"
> > > +                             tooltiptext="&cmd.resume.label;"
> > > +                             oncommand="DownloadsView.onItemCommand(event, 'downloadsCmd_resume');"/>
> > 
> > Why are these xul:toolbarbuttons as opposed to xul:button?  They aren't in a
> > toolbar, so I'm fairly certain they should be xul:buttons instead
> > (especially since you use xul:button further down).
> 
> The popup notifications used toolbarbuttons too, because this way you avoid
> writing the additional CSS that is required to style the button as images,
> I guess. Maybe ask Gavin?

Popup notifications use a toolbarbutton for the close button because we're sharing styles with the notification bar messageCloseButton, which is a toolbarbutton. You should probably just use a normal button here.
(In reply to comment #282)
> (In reply to comment #281)
> > This is actually an open item from comment 253. It seems that RTL languages
> > don't need to change the order of those strings. See for example:
> > 
> > http://mxr.mozilla.org/l10n-central/search?string=paused%3D
> > 
> > Note that for Arabic you might see text like "1#  - " because of the
> > directionality change in the text, but the string is still " -  #1".
> Can you check with l10n please?  I'm still worried even if no locale
> currently does it differently.

Sorry for the lag here, I've had my head focused on a few other items.

Yes, please don't assume things to be equal across all languages, even if the ones we have make no other choice. They could be wrong, and we could encounter new languages that need the flexibility.

The localization notes are great stuff, nice job on those.
Blocks: 607186
(In reply to comment #280)
> > +   * Returns the most recent browser window that is not closed
> 
> Can you file a bug about this explicitly, mark it dependent on that bug, and
> reference the bug number that you file here please?

You probably just want to use nsIBrowserGlue::getMostRecentBrowserWindow here instead.
Attached patch Addressed review nits (obsolete) — Splinter Review
Updated version. You might want to take a look to the interdiff to verify the
few changes to the localized strings file, as well as the other minor changes.
See below for more comments.

(In reply to comment #280)
> ::: browser/components/downloads/DownloadManagerUI.js
> @@ +91,5 @@
> > +  /**
> > +   * Returns the most recent browser window that is not closed, or null if no
> > +   * such window exists. This helper function will be required at least until
> > +   * bug 528706 (nsIWindowMediator::getMostRecentWindow should not return closed
> > +   * windows) is fixed.
> 
> Can you file a bug about this explicitly, mark it dependent on that bug, and
> reference the bug number that you file here please?

If I understand correctly, this is required to track that an action should be
taken after both that bug and this one are marked as fixed, right? I ask
because this might not be necessary here, since this function is gone, but
maybe we should do the same for bug 492960, which is now just marked as a
dependency of this bug.

> I'd prefer to see you use NetUtil.newURI here.

About newURI in general, I'm now using the following code in another place:

let fileUrl = NetUtil.newURI(this.file).QueryInterface(Ci.nsIFileURL);

Last time I checked, the QueryInterface call (or an "instanceof" check) was
required in order to access the properties defined on nsIFileURL. If this
is still the case, shouldn't "NetUtil.newURI" do the QueryInterface for us?
Currently it doesn't, even if it would be a very simple change:

http://mxr.mozilla.org/comm-central/source/mozilla/netwerk/base/src/NetUtil.jsm#228

> ::: toolkit/components/downloads/Makefile.in
> @@ +72,5 @@
> >  # XXX - Until Suite builds off XULRunner we can't guarantee our implementation
> >  # of nsIDownloadManagerUI overrides toolkit's.
> > +# This is also disabled when building the "browser" application since it also
> > +# has its own implementation of nsIDownloadManagerUI.
> > +ifneq (browser,$(MOZ_BUILD_APP))
> 
> I think the right way to work around this problem is to just unregister the
> default component in final-ui-startup in browser land for the contract id. 
> I'm saying this without doing a whole lot of investigation to make sure that
> would work though...

As far as I know, that wouldn't work because we are running all the Toolkit
chrome tests with a browser window open. I did my own investigation, and will
post my proposal in a separate comment later :-)
Attachment #533137 - Attachment is obsolete: true
Attachment #536124 - Flags: feedback?(sdwilsh)
(In reply to comment #286)
> If I understand correctly, this is required to track that an action should be
> taken after both that bug and this one are marked as fixed, right? I ask
> because this might not be necessary here, since this function is gone, but
> maybe we should do the same for bug 492960, which is now just marked as a
> dependency of this bug.
If it goes away, we don't need to worry about it, but in general, yes, it's so we can track that.

> Last time I checked, the QueryInterface call (or an "instanceof" check) was
> required in order to access the properties defined on nsIFileURL. If this
> is still the case, shouldn't "NetUtil.newURI" do the QueryInterface for us?
> Currently it doesn't, even if it would be a very simple change:
We should file a bug to automagically do that.

> As far as I know, that wouldn't work because we are running all the Toolkit
> chrome tests with a browser window open. I did my own investigation, and will
> post my proposal in a separate comment later :-)
You can get a component by uid still and not the contract, so the tests could do that.

I'm unlikely to be able to look at this before I go away for a while.
Depends on: 663772
A new tryserver build is now ready, including a prototype of the new download
progress indicator in the main window, which is implemented in bug 663772.
Screenshots of the indicator can be found in attachment 538844 [details]
(<https://bugzilla.mozilla.org/attachment.cgi?id=538844>) as well as
attachment 538846 [details].

Note that the default position of the indicator is now the tab bar, in part
because download items are a logical extension of the set of open, background
tasks represented by tabs, and in part because this way the indicator remains
visible when browsing pages that hide the navigation bar.

This build is still work in progress, and due to some known issues the
following should not be tested:

* Adding more downloads than the screen height allows.
* Removing the indicator from the browser window and restarting
  (the indicator won't be re-initialized at startup).
* Keeping more than one browser window open (because the attention
  indicators are still handled independently in each window).
* Relative orientation of the panel (not always consistent).
* Accessibility to screen readers (will be done after UI review).
* The Library window (will probably change very soon).

Everything else should work, even if the interaction is not necessarily final.
It's recommended to use a new user profile for testing, though migration of
existing profiles is also supported.

The builds can be found here:
http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-fbdce45ee0cc

If you want to test a large download of unknown size, you can use:
http://tinderbox.mozilla.org/showlog.cgi?log=Try/1307958378.1307981287.17961.gz

Other similar links to build logs can be found here:
http://tbpl.mozilla.org/?tree=Try&rev=fbdce45ee0cc

Enjoy!
Hello everyone,

I'm taking on UX side of things for the Download Manager UI from Alex.

Awesome work with the indicator Paolo! I'll get back with some details on some of the open UX issues soon!
I tried the new try-build. The new download panel is awesome! The Download History is a great idea!
I found the following: 
        1)Clicking the indicator once in a maximized window nothing happens but clicking it twice it rezises the window to a half. Double clicking it again returns the window to maximized. Even in safe mode. Shouldn't one or two clicks bring up the new panel?
        2)The new panel can only be accessed via Nightly button>Downloads. Is this the expected behavior?
i tried the try-build as well. it's a great implementation to an a design made by firefox ue team and set in stone in safari 5.1 in osx lion; firefox really should beat them to this; the new download progress control could replace downloads button and replace the icon with multiple state icons to the xul "download progress control" object like [downloading] [error] [clear] or what so ever. did we really need the places window integration? the download progress could be a small docked window floating on xul animated object hover state. great work people :)
(In reply to comment #290)
>         1)Clicking the indicator once in a maximized window nothing happens
> but clicking it twice it rezises the window to a half. Double clicking it
> again returns the window to maximized. Even in safe mode. Shouldn't one or
> two clicks bring up the new panel?

The fact that the indicator doesn't always respond to clicks when the window
is maximized is a bug to be investigated, thanks for reporting!

>         2)The new panel can only be accessed via Nightly button>Downloads.
> Is this the expected behavior?

In addition to clicking the indicator with the mouse, yes, the menu items and
the associated keyboard shortcuts are the only primary interface for opening
the panel.
(In reply to comment #292)
> > 
> The fact that the indicator doesn't always respond to clicks when the window
> is maximized is a bug to be investigated, thanks for reporting!

No problem for reporting, I like to help! The indicator doesn't respond to clicks when the window isn't maximized either.
> 
>  
> In addition to clicking the indicator with the mouse, yes, the menu items and
> the associated keyboard shortcuts are the only primary interface for opening
> the panel.

I wasn't sure whether clicking the indicator should bring up the new panel, now I know it should, Nightly button>Downloads is an alternative way to reach the new panel then.
Depends on: 612516
Blocks: 612516
No longer depends on: 612516
Will it be pushed to UX branch? Or, may be, directly to Central?
I had a wonderful conversation with Sinchan about the design of the new
Downloads panel, and we've concluded that we're going for a much more
lightweight, notification-style approach, with great usability and simplicity.
We've summarized our conclusions here:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager#Designs

While the visual design is still to be defined by the UX team, I've already
prepared a tryserver build that implements part of the new interactions. Feel
free to try it out, while considering that this is still work in progress and
some details are still to be implemented.

Most known issues of the previous build still apply, thus the following
should not be tested:

* Adding more downloads than the screen height allows.
* Removing the indicator from the browser window and restarting
  (the indicator won't be re-initialized at startup).
* Keeping more than one browser window open (because the attention
  indicators are still handled independently in each window).
* Accessibility to screen readers (will be done after UI review).
* Opening files with double-clicks from the Library window.

Note that the icon for "show in folder" (the looking glass) is missing,
and is temporarily replaced by the "resume" icon on a green background.

Also, with some configurations, clicks on the downloads indicator might not
work, and the panel must be opened using the Downloads menu item, or CTRL+J.

The build can be found here:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-f04c7da05a05/
Comment on attachment 460413 [details]
For UI Review by Limi

While the design of the Downloads panel changed a lot during the last year,
looking at this old screenshot, I'd still like to thank Jason for creating
this initial prototype and inspiring me to take it up!
Attachment #460413 - Flags: ui-review?(limi)
Attachment #459315 - Attachment is obsolete: true
Attachment #463698 - Attachment is obsolete: true
Attachment #466688 - Attachment is obsolete: true
Attachment #467459 - Flags: feedback?(limi)
Attachment #530915 - Attachment is obsolete: true
The new build works much better than the earlier one, the items in the panel respond way quicker.
The new build work great! But I think the download icon is too big that when you put on the nav-bar it break the nav-bar, the icon should be smaller. Also the download icon should be put on the Add-on bar, when all download is complete an Arrow panels notification pop out the App button, when you click the more detail link, the Arrow panels notification pop out the download button (if the add-on bar is hidden, it should only show the download button in the bottom-right like status and hover links).

This build is great any way, but sometimes I can't click the download button if it places on the tab-bar. Can you push it to the latest-nightly-ux? I think that this almost ready to ship now!!!!
(In reply to comment #298)
> The new build work great! But I think the download icon is too big that when
> you put on the nav-bar it break the nav-bar, the icon should be smaller.

Thanks for testing! This is in fact an issue I forgot to mention, the visual
design and styling phase will take care of it.

> Also the download icon should be put on the Add-on bar, when all download is
> complete an Arrow panels notification pop out the App button, when you click
> the more detail link, the Arrow panels notification pop out the download
> button (if the add-on bar is hidden, it should only show the download button
> in the bottom-right like status and hover links).

This is interesting, and while I don't think the Add-on Bar is the optimal
candidate for built-in functionality, as the name says, you're welcome to
discuss these ideas and suggest alternative designs in the usability forum:

http://www.mozilla.org/about/forums/#dev-usability
I'd like to clarify the status of this feature, since I see a lot of interest
and there have already been inquiries about whether we are ready for making
the feature available to users. In fact, there is a lot of difference between
a working prototype and something that is ready to ship to a large user base,
and this should be taken into account.

Firstly, the panel is not the only component that must be developed. There is
a list of the various parts and their current status here:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager#Bugs_list_and_patch_queue

All these parts must be completed before the panel can be made available, and
there are also other issues listed in this bug's dependencies.

Moreover, each one of the dependencies must be reviewed by different teams for
user experience, architecture, accessibility, localizability, security, and
visual design. While we're well ahead with some aspects like code review,
other aspects still require the involvement of the relevant teams.

The designs are also not final, which is normal, but in addition we still have
several open questions and tasks, some of which are blocking with regard to
the release, and are unassigned. If you're curious, the updated list is here:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager#Open_tasks_and_questions

With this list and the release schedule in mind, I think it's clear that
we're now past the point where we could make Firefox 7, even with an
organized effort on part of all the teams. Whether the feature will make
Firefox 8 or a later version is still unknown. My current thinking is that,
if we want to make a specific release, then more coordination or higher
prioritization is probably required, from the people with that responsibility.

Development on the panel itself is now waiting upon the dependencies,
especially the Library window patch and some more design. While these are
being worked out, I'm available for helping with integration: I'll generate
new builds as required, answer questions, and keep the above lists updated
based on the comments on the various bugs.

With regard to my plans for the next few weeks, a quick estimate tells me
that, even if a coordinated effort to finish this feature in Firefox 8
starts, I have now enough time to turn my volunteering efforts towards the
Mozilla Archive Format add-on (<http://maf.mozdev.org/>), that I'm currently
maintaining and is in need of some long-awaited cool features :-)
I think the function is ok, you should focus on the UI. The download box should not be styled like a normal Arrow panel, it should be styled like the Add-ons Manager (In-contend UI). The background, texture, gradient, buttons,....

http://people.mozilla.com/~jboriss/bugs/addons_manager_styling/windows_7_background_color_and_graphics.png

http://people.mozilla.com/~jboriss/bugs/addons_manager_styling/foreground_color_and_graphics.png

https://bug623199.bugzilla.mozilla.org/attachment.cgi?id=516086
The progress line, pause and stop buttons should also should be styled, because I hate the native Windows Progress bar.

Like this:
http://img809.imageshack.us/img809/2761/captureny.png
Will it be pushed to UX branch? And if so - when it will be?
Any changes for Fx6 or 7?
Canis the changes in this bug are not yet finished so cannot have been included in already feature-frozen Firefox releases. Minimal changes are made in the Aurora/Beta channels (which is what Fx7 and Fx6 are in respectively) - for more info on the rapid release process, see: http://mozilla.github.com/process-releases/draft/development_overview/

As for this bug, when the patches here are complete/have landed on mozilla-central, the status of the bug will change to fixed - and whatever version of Firefox is currently in development (ie says "currently in NIGHTLY channel" here: https://wiki.mozilla.org/Releases) is the version in which you will see the changes.
Why it will not be landed on nightly-ux?
(In reply to comment #306)
> Why it will not be landed on nightly-ux?

We are heading toward that, but in its current state is not yet ready for general audience. We'll notify when it lands in the branch and we'll really appreciate feedback on it at that time.
Depends on: 672365
No longer depends on: 672365
Comment on attachment 536124 [details] [diff] [review]
Addressed review nits

clearing feedback request to Shawn, this still needs some work to address latest interaction changes.
He is well aware of this bug and welcome to drive-by but I don't think feedback on this patch, that is fixing previous feedback/review nits, would be useful enough to spend his spare time on.
Better to wait a bit for next iteration.
Attachment #536124 - Flags: feedback?(sdwilsh)
We have a brand new build implementing greatly simplified download management!

This version, based on the updated specifications in the feature page, is now
ready for extensive testing with regard to features and interaction.

Things to watch out for:
* Visual design is still missing. Sometimes elements do not stand out clearly
   on the background, and there are ugly placeholders for most icons :-)
* Opening files with double-clicks from the Library window does not work yet.
* Accessibility to screen readers will be implemented soon.

The new build is available here:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-8893e9af1a54

Thanks in advance for your feedback!
And here is the corresponding patch ready for code review. It's a daunting task,
reviewing 160 KB of code, and I'm afraid that interdiff with the previous
version won't be of much help, given the amount of changes!

However, code style and the general structure should be consistent with our
previous reviews. Note that some things will make sense in the light of bug
663772, which is another 50 KB of code that I kept in a separate bug and
I'll upload shortly.
Attachment #536124 - Attachment is obsolete: true
Attachment #550148 - Flags: ui-review?(sbanerjee)
Attachment #550148 - Flags: review?(mak77)
Comment on attachment 550148 [details] [diff] [review]
Interaction nearly final, no visual design

>-             defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabs-closebutton"
>+             defaultset="tabbrowser-tabs,new-tab-button,downloads-button,alltabs-button,tabs-closebutton"

Why is this on the tab bar? The placement between new-tab-button and alltabs-button seems arbitrary and there appears to be no logical correlation with tabs in general.
(In reply to comment #309)
> The new build is available here:
> 
> http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/
> paolo%2Emozmail%40amadzone%2Eorg-8893e9af1a54
> 
> Thanks in advance for your feedback!

I downloaded a tiny file, the button and the panel appeared, I dismissed the panel and the button disappeared. Is this expected?
(In reply to comment #309)
> We have a brand new build implementing greatly simplified download
> management!
> 
> This version, based on the updated specifications in the feature page, is now
> ready for extensive testing with regard to features and interaction.
> 
> Things to watch out for:
> * Visual design is still missing. Sometimes elements do not stand out clearly
>    on the background, and there are ugly placeholders for most icons :-)
> * Opening files with double-clicks from the Library window does not work yet.
> * Accessibility to screen readers will be implemented soon.
> 
> The new build is available here:
> 
> http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/
> paolo%2Emozmail%40amadzone%2Eorg-8893e9af1a54
> 
> Thanks in advance for your feedback!

How about some more noticeable notification that all the downloads are finished?
Blinking icon that smoothly transforms just into highlighted button (like it is now) would be nice/
How about displaying the number of active downloads?
The button's icon itself is confusing, could you use the old (down arrow) icon but just fill it from the bottom up to the top with green (or better OS dependent color) while the progress moves on. How do you like that idea?
Is it possible to add an about:config pref that would change the displayable value (when the download is in process), from showing average estimated remaining time to download_speed/percentage_of_download_progress/MBytes_downloaded/MBytes_left/cycle_all_mentioned?
Do you know that currently the icon (of active download process) is too high so it makes toolbar jump?
Did you hide the "pause download" button on purpose (it is accessible only from context menu)? Why?
Do you plan to use the current ugly icons for? Why not draw the icons in "glyph" style (like the ones used in the main interface)?
Comment on attachment 550148 [details] [diff] [review]
Interaction nearly final, no visual design

Strings and localization notes look nice, fwiw.
I noticed a couple things:
When downloading a file, the indicator said there was 1 min. remaining until there was only 30 sec. left, then it switched to sec. remaining. Is this expected behavior? Also, after the download finished, when I clicked the "show in folder" button, the download was removed from the download panel, and the download panel shifted to the middle of the browser window before disappearing. I'm running Windows 7 x64.
Just as a reminder, this is not intended to work as the old downloads window, this is a notification panel, and you consume the notifications.
You can always get list of the downloads in the Library (still missing some interaction there) that will mostly work as the old downloads window.
Thanks everyone for the great feedback! I'll try to reply as best as I can.
If you wonder whether something is expected in the new design, most of our
current thinking can be found in the feature page, though it's still changing
as we receive more feedback and suggestions:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager#6._User_experience_design

(In reply to comment #311)
> Why is this on the tab bar?

The practical reason is that in a default profile the tab bar is visible even
when you navigate to an application page where the navigation bar is hidden,
like the Add-ons Manager. I'll let the UX team explain the rest of the logic
behind the choice :-)

(In reply to comment #312)
> I downloaded a tiny file, the button and the panel appeared, I dismissed the
> panel and the button disappeared. Is this expected?

Only if the button was removed from the toolbars during customization, in
which case we display it as a temporary anchor. The button also disappears
when the last download notification is removed.

(In reply to comment #313)
> How about some more noticeable notification that all the downloads are
> finished?
> Blinking icon that smoothly transforms just into highlighted button (like it
> is now) would be nice/

We are considering whether doing more visible notifications when downloads
start or all downloads finish. Blinking and smoothly fading to stable is a
good idea I think. It's in the the visual design phase that we'll define the
exact effect we'll use to get attention.

> How about displaying the number of active downloads?

We want to minimize the space required by the indicator, so we want to
display only one number. We displayed the number of downloads in the
original design, but we changed it to a time indication, because you
already know how many downloads you started but you don't know how much
time they'll require to complete, so it's more useful :-)

> The button's icon itself is confusing, could you use the old (down arrow)
> icon but just fill it from the bottom up to the top with green (or better OS
> dependent color) while the progress moves on. How do you like that idea?

This will also be defined later, in the visual design phase.

> Is it possible to add an about:config pref that would change the displayable
> value (when the download is in process), from showing average estimated
> remaining time to
> download_speed/percentage_of_download_progress/MBytes_downloaded/MBytes_left/
> cycle_all_mentioned?

I think we'll keep the base indicator as simple as possible and leave the
more advanced options to add-ons! Installing add-ons will be much quicker
than changing about:config options, and won't even require a restart :-)

> Do you know that currently the icon (of active download process) is too high
> so it makes toolbar jump?

Thanks for the report: which operating system and toolbar exactly?

> Did you hide the "pause download" button on purpose (it is accessible only
> from context menu)? Why?

We think that pausing a download is something rarely needed in practice,
especially with a small number of downloads, which is the case we're
optimizing for. When going offline or entering Private Browsing Mode,
current downloads are paused and resumed automatically if needed.

> Do you plan to use the current ugly icons for? Why not draw the icons in
> "glyph" style (like the ones used in the main interface)?

Of course we're not keeping the ugly icons :-) Even the shapes of the icons
might be different from now, and even different based on the operating
system. We might actually use simple shapes for some or all of them.

(In reply to comment #314)
> Strings and localization notes look nice, fwiw.

Thanks :-)

(In reply to comment #315)
> I noticed a couple things:
> When downloading a file, the indicator said there was 1 min. remaining until
> there was only 30 sec. left, then it switched to sec. remaining. Is this
> expected behavior?

Yes, we want to start the "countdown" in the last thirty seconds. Seeing
the number changing rapidly might hint that the download is about to finish,
but we don't want the countdown to start too early. Maybe we could display
"<1m" instead of "1m" from 60 to 30 seconds left, but I'm not sure it's
worth it or if the meaning is clear. Thoughts?

> Also, after the download finished, when I clicked the
> "show in folder" button, the download was removed from the download panel,

This is by design, though we're probably changing the design and keeping
the notification until it's manually removed or the session finishes.

> and the download panel shifted to the middle of the browser window before
> disappearing. I'm running Windows 7 x64.

This is a bug. I reproduced it today, I guess the panel is tracking an
invisible movement of the anchor, it's time-based so doesn't always happen.
(In reply to comment #317)
> > Do you know that currently the icon (of active download process) is too high
> > so it makes toolbar jump?
> Thanks for the report: which operating system and toolbar exactly?

Win7x64, default theme, the button is placed on the nav-bar. I also use "small icons" (an option in toolbar>customize).
Yup, to expand on Paolo's explanation for why the button is currently on the tab-bar, we chose to try the button out on the tab-bar because it belongs there if we strictly follow the visual hierarchy of the browser - i.e. the downloads button does not have tab-specific relevance, but rather it applies to the browsing session in general. We do understand that we might have to end up placing it on the navigation bar because there aren't such buttons on the tab-bar [except for the 'which tabs are open' button], but we decided to try it out and see how it felt :)
Perhaps it is more convenient to place the download indicator in the address bar?
In this way indicator will not break the visual hierarchy of the browser and will not take place in the tab-bar.
(In reply to Tiger.711 from comment #320)
> Created attachment 553446 [details]
> Download indicator in urlbar
> 
> Perhaps it is more convenient to place the download indicator in the address
> bar?
> In this way indicator will not break the visual hierarchy of the browser and
> will not take place in the tab-bar.

That makes no sense: urlbar shows the information related to the currently active tab.
And downloads may correspond to a closed tab or even to no tab at all.
Plus, why should favicon get hidden in case of an active download?
Url-bar in ux-nightly is attached to back/forward button. This is a continuation of the idea of integration.

If the button is located between the back/forward and the url-bar then icon is in url-bar. Otherwise, the user can place the indicator in any other place. As with the reload/stop/go button.
When the UX Team was presenting the idea of Tabs on Top, they made a great arguments about page controls, tab controls, content controls, etc. to ultimately go along with the stratagem, the Download icon/button belongs either in the Tab Bar or above or the Add-On Bar.
As long as we can move it to any toolbar via customize, there's no point debating. However combining it with the URL bar is unnecessary complication and definitely not a part of this bug.
Comment on attachment 550148 [details] [diff] [review]
Interaction nearly final, no visual design

Review of attachment 550148 [details] [diff] [review]:
-----------------------------------------------------------------

This is a first pass, since I had to read it all to figure out what changed from the last time, I annotated some hints/comments (I know the styling is undone, but I still annotated something, you may have already fixed that). I may have more comments regarding the whole structure, but I have to think about it a bit more, now that I've refreshed my mind.  Globally seems fine though.  In the meanwhile I guess you may already have an updated version with the new design.

Btw, I'm in favor of pushing next iteration to UX branch, I'll do another pass to bug 663772 shortly.

::: browser/base/content/browser.xul
@@ +779,2 @@
>  #else
> +             defaultset="tabbrowser-tabs,new-tab-button,downloads-button,alltabs-button,tabs-closebutton"

So, while the positioning on the tabbar has seen some reasoning, I'm not sure why this is in the middle of buttons that act on tabs, esp. between newtab and alltabs. I think for now it should go to the far end of the bar, after tabs-closebutton, rather than interrupting that group of related elements.

::: browser/components/downloads/content/downloads.js
@@ +47,5 @@
> +
> +/**
> + * Handles the Downloads panel user interface for each browser window.
> + *
> + * This module includes the following constructors and global objects:

nit: "module" may be misinterpreted

@@ +77,5 @@
> +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
> +Cu.import("resource://gre/modules/Services.jsm");
> +Cu.import("resource://gre/modules/NetUtil.jsm");
> +Cu.import("resource://gre/modules/DownloadUtils.jsm");
> +Cu.import("resource:///modules/DownloadsCommon.jsm");

the last 3 may probably be lazyModuleGetters

@@ +94,5 @@
> +
> +  /**
> +   * State of the downloads panel, based on one of the kPanel constants.
> +   */
> +  _panelState: 0,

should be inited to one of the constants rather than a magic number

@@ +103,5 @@
> +  get kPanelHidden() 1,
> +  /** The panel will be shown as soon as possible. */
> +  get kPanelShowing() 2,
> +  /** The panel is open, though download data might still be loading. */
> +  get kPanelShown() 3,

I still suggest a fake enum approach

@@ +122,5 @@
> +    // Ensure that the Download Manager service is running.  This resumes
> +    // active downloads if required, and may start loading data asynchronously.
> +    Services.dm;
> +
> +    // Now that data loading has started if required, initialize our views.

nit: s/has started if required/has eventually started/

@@ +190,5 @@
> +
> +    // Ensure that we allow the panel to be reopened.  Note that, if the popup
> +    // was open, then the onPopupHidden event handler has already updated the
> +    // current state, but if the popup was not open (the kPanelShowing state),
> +    // calling hidePopup does nothing and we must update the state ourselves.

s/, but if the popup was not open (the kPanelShowing state), calling hidePopup does nothing and we must update the state ourselves./, otherwise we must update the state ourselves./

Globally, the new code is really well commented but some comment repeats the same stuff twice, if any comment can be compacted, without hurting its clearness, readability of this long code will improve.

@@ +287,5 @@
> +  },
> +
> +  /**
> +   * Internal method that actually opens the downloads panel when data is ready
> +   * to be displayed.

s/internal method that actually//

@@ +306,5 @@
> +
> +    // If the downloads button has been removed from the toolbar, anchor the
> +    // panel to the toolbar itself.
> +    this.panel.openPopup(document.getElementById("downloads-button") ||
> +                         document.getElementById("nav-bar"),

move this to a local "anchor" var

btw, the button is now on tabbar, not nav-bar, and the panel floating from nowhere may not look that nice... should we maybe temporarily show the button?

@@ +330,5 @@
> +  /**
> +   * Object containing all the available DownloadsViewItem objects, indexed by
> +   * their numeric download identifier.
> +   */
> +  viewItems: {},

may probably be prefixed as internal _

@@ +338,5 @@
> +
> +  /**
> +   * Indicates whether we are still loading downloads data asynchronously.
> +   */
> +  loading: false,

apart if the data loading is aborted, then it indicates unreliable data

@@ +350,5 @@
> +  },
> +
> +  /**
> +   * Called after data loading finished.  This method is not called if data
> +   * loading is aborted before completion, for any reason.

I'm a bit worried by this, maybe would be better to always notify completion with a status argument, otherwise it may be hard to track begin and end of loading operations.
if the query fails or is canceled this.loading keeps being true even if we are not actually loading anything.

@@ +446,5 @@
> +   *        walk up the parent nodes until it finds a DOM node that is.
> +   * @param aCommand
> +   *        The command to be performed.
> +   */
> +  onDownloadCommand: function DV_onItemCommand(aEvent, aCommand)

label doesn't match

@@ +465,5 @@
> +      return;
> +    }
> +
> +    // Only do the action for primary clicks.
> +    if (aEvent.button == 0) {

moving this condition to the early bailout check would be fine

@@ +467,5 @@
> +
> +    // Only do the action for primary clicks.
> +    if (aEvent.button == 0) {
> +      // Open the download if the command is enabled for this item.
> +      goDoCommand("downloadsCmd_open");

the comment does not add anything to the code, imo can be removed

@@ +474,5 @@
> +
> +  onDownloadContextMenu: function DV_onDownloadContextMenu(aEvent)
> +  {
> +    // Ensure that there is an item selected.
> +    if (!this.richListBox.selectedItem) {

you use selectedItem later, may be worth caching it once before the check, like you did in onDownloadDragStart

@@ +502,5 @@
> +
> +    let dataTransfer = aEvent.dataTransfer;
> +    dataTransfer.mozSetDataAt("application/x-moz-file", localFile, 0);
> +    dataTransfer.effectAllowed = "copyMove";
> +    dataTransfer.addElement(element);

is addElement needed? which node are events fired otherwise?

@@ +533,5 @@
> +  this.wasInProgress = this.dataItem.inProgress;
> +  this.lastEstimatedSecondsLeft = Infinity;
> +
> +  // Set the URI that represents the correct icon for the target file.  Note that
> +  // as soon ase bug 239948 comment 12 is handled, the "file" property will be

typo: ase

@@ +636,5 @@
> +
> +    // Dispatch ValueChange for a11y, if the download binding is accessible.
> +    let meter = document.getAnonymousElementByAttribute(this._element,
> +                                                        "anonid",
> +                                                        "progressmeter");

a lazygetter may be useful considering progress may be updated lots of times

@@ +709,5 @@
> +  /**
> +   * Localized string representing the total size of completed downloads, for
> +   * example "1.5 MB" or "Unknown size".
> +   */
> +  get _sizeText()

_filesizeText would be cleared about what it is

@@ +785,5 @@
> +
> +  updateCommands: function DVC_updateCommands()
> +  {
> +    // Update all the commands that are specific for the selected item.
> +    for ([cmd] in Iterator(DownloadsViewItemController.prototype.commands)) {

Object.keys(DownloadsViewItemController.prototype.commands).forEach(goUpdateCommand) ?

@@ +844,5 @@
> +  },
> +
> +  doCommand: function DVIC_doCommand(aCommand)
> +  {
> +    // Invoke the command, if enabled, using this object for "this".

the code is pretty clear by itself, imo

@@ +851,5 @@
> +    }
> +  },
> +
> +  //////////////////////////////////////////////////////////////////////////////
> +  //// Commands

add a small comment regarding the fact "this" in the commands functions is not "commands", as it is it looks a bit confusing, alternatively, you may put commands directly in DownloadsViewItemController, and use an array comprehension to filter out any properties whose name doesn't begin with downloadsCmd_ and get the commands list, may help figuring out what's "this"

::: browser/components/downloads/src/DownloadsCommon.jsm
@@ +70,5 @@
> +const Cr = Components.results;
> +
> +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
> +Cu.import("resource://gre/modules/Services.jsm");
> +Cu.import("resource://gre/modules/NetUtil.jsm");

lazyModuleGetter for NetUtil may be useful

@@ +185,5 @@
> +
> +/**
> + * Returns true if we are executing on Windows Vista or a later version.
> + */
> +XPCOMUtils.defineLazyGetter(DownloadsCommon, "isOnWindowsVista", function () {

why don't you use the same check that is in toolkit, with cheaper preprocessed XP_WIN and just the check to system-info?
Btw, if we retain the separate getter, I'd name it isWinVistaOrHigher to cope with existing isWin7OrHigher

@@ +231,5 @@
> +    // Start receiving real-time events.
> +    aDownloadManagerService.addListener(this);
> +    Services.obs.addObserver(this, "download-manager-remove-download", false);
> +    Services.obs.addObserver(this, "download-manager-database-type-changed",
> +                             false);

these topics are used multiple times, you may want to const them, or expose them through DownloadCommons

@@ +254,5 @@
> +  /**
> +   * Array of view objects that should be notified when the available download
> +   * data changes.
> +   */
> +  views: [],

should this be internal (thus "_" prefixed?) I can't see any access to it from outside, and makes sense

@@ +299,5 @@
> +    // Sort backwards by download identifier, ensuring that the most recent
> +    // downloads are added first regardless of their state.
> +    let loadedItemsArray = [dataItem
> +                            for ([, dataItem] in Iterator(this.dataItems))
> +                            if (dataItem)];

what's the point of the Iterator, if you can use [dataItem for each (dataItem in this.dataItems) if (dataItem)]

@@ +301,5 @@
> +    let loadedItemsArray = [dataItem
> +                            for ([, dataItem] in Iterator(this.dataItems))
> +                            if (dataItem)];
> +    loadedItemsArray.sort(function(a, b) b.downloadId - a.downloadId);
> +    for (let [, dataItem] in Iterator(loadedItemsArray)) {

I understand you like the new constructs with passion, but a simple for loop is cheaper, also than a forEach.

@@ +324,5 @@
> +   */
> +  dataItems: {},
> +
> +  /**
> +   * Saved download state while operating in Private Browsing Mode.

This comment needs some love, I guess it means during PB states are temporarily parked here

@@ +382,5 @@
> +    this.dataItems[downloadId] = dataItem;
> +
> +    // Create the view items before returning.
> +    let addToStartOfList = aSource instanceof Ci.nsIDownload;
> +    for (let [, view] in Iterator(this.views)) {

ditto on Iterator

@@ +397,5 @@
> +  _removeDataItem: function DD_removeDataItem(aDownloadId)
> +  {
> +    if (aDownloadId in this.dataItems) {
> +      let dataItem = this.dataItems[aDownloadId];
> +      for (let [, view] in Iterator(this.views)) {

ditto, I won't repeat below, I'd like to see this go away everywhere there isn't a good reason to prefer an Iterator.
Actually, for the specific scope of notifying views, you may have a oneliner notifyViews("notification", [args]) helper.

@@ +421,5 @@
> +  /**
> +   * Indicates which kind of items from the persistent downloads database have
> +   * been fully loaded in memory and are available to the views.
> +   */
> +  _loadState: 0,

should be inited to kLoadNone, rather than a magic number.
The comment should explain where to look for valid values.

@@ +423,5 @@
> +   * been fully loaded in memory and are available to the views.
> +   */
> +  _loadState: 0,
> +
> +  /** No download have been fully loaded yet. */

typo: has or downloads

@@ +428,5 @@
> +  get kLoadNone() 0,
> +  /** All the active downloads in the database are loaded in memory. */
> +  get kLoadActive() 1,
> +  /** All the downloads in the database are loaded in memory. */
> +  get kLoadAll() 2,

I still strongly suggest the fake enum loadStates: {none: 0, active: 1, all: 2},

@@ +483,5 @@
> +  deleteOldPersistentData: function DD_deleteOldPersistentData()
> +  {
> +    let loadedDownloadIds = [dataItem.downloadId
> +                             for ([, dataItem] in Iterator(this.dataItems))
> +                             if (dataItem)];

for each in

@@ +487,5 @@
> +                             if (dataItem)];
> +    let query = "DELETE FROM moz_downloads";
> +    if (loadedDownloadIds.length > 0) {
> +      query += " WHERE id NOT IN (" + loadedDownloadIds.join(",") + ")";
> +    }

actually, DELETE FROM moz_downloads WHERE id NOT IN () works the same way as without the condition, so you may even avoid the check and the local query var

@@ +534,5 @@
> +  },
> +
> +  handleError: function DD_handleError(aError)
> +  {
> +    Cu.reportError(aError);

aError is a mozIStorageError, not sure how reportError would print it out (I suppose as [Object object] or something similar). Something like this may be better:
Cu.reportError("Async statement execution error (" + aError.result + "): '" + aError.message);

@@ +551,5 @@
> +
> +      // Indicate to the views that the batch loading operation is complete.
> +      for (let [, view] in Iterator(this.views)) {
> +        view.onDataLoadCompleted();
> +      }

may be safer to always notify but pass a completed boolean arg to the view

@@ +558,5 @@
> +
> +  //////////////////////////////////////////////////////////////////////////////
> +  //// nsIObserver
> +
> +  observe: function DOB_observe(aSubject, aTopic, aData)

DOB_ ?

@@ +571,5 @@
> +
> +        // Multiple downloads have been removed.  Iterate over known downloads
> +        // and remove those that don't exist anymore.
> +        for (let [, dataItem] in Iterator(this.dataItems)) {
> +          if (dataItem) {

well, here you may indeed use an array comprehension to keep only not-null

@@ +658,5 @@
> +/**
> + * Represents a single item in the list of downloads.  This object either wraps
> + * an existing nsIDownload from the Download Manager, or provides the same
> + * information read directly from the downloads database, with the possibility
> + * of querying the nsIDownload lazily, for performance reasons.

the last sentence is confusing, can be better explained

@@ +823,5 @@
> +   * Returns the nsILocalFile for the download target.
> +   *
> +   * This will throw an exception if the native path is not valid.  This can
> +   * happen if the same profile is used on different platforms, for example if a
> +   * native Windows path is stored and then the item is accessed on a Mac.

use a @throws annotation

@@ +830,5 @@
> +  {
> +    // The download database may contain targets stored as file URLs or native
> +    // paths.  This can still be true for previously stored items, even if new
> +    // items are stored using their file URL.  See also bug 239948 comment 12.
> +    if (this.file.substring(0, "file://".length) == "file://") {

why not matching with /^file:/.test(this.file) (or file:\/\/ if you want the added safety)?

::: browser/components/downloads/src/DownloadsStartup.js
@@ +58,5 @@
> +
> +XPCOMUtils.defineLazyGetter(this, "DownloadsCommon", function() {
> +  Cu.import("resource:///modules/DownloadsCommon.jsm");
> +  return DownloadsCommon;
> +});

use definaLazyModuleGetter

@@ +97,5 @@
> +  observe: function DS_observe(aSubject, aTopic, aData)
> +  {
> +    switch (aTopic) {
> +      case "app-startup":
> +        for ([, topic] in Iterator(kObservedTopics)) {

is there a specific reason to use an Iterator here? it seems uselessly more expensive than a simple for loop

@@ +129,5 @@
> +              !gSessionStore.canRestoreLastSession) {
> +            this._sessionWasRestored = true;
> +          }
> +          this._ensureDataLoaded();
> +        });

I'd appreciate if you could get feedback from zpao on the sessionstore stuff, there may be some hidden magic to make this simpler

@@ +162,5 @@
> +
> +      case "quit-application":
> +        this._shuttingDown = true;
> +
> +        for ([, topic] in Iterator(kObservedTopics)) {

ditto

@@ +213,5 @@
> +
> +  /**
> +   * Contract ID of the service implementing nsIDownloadManagerUI.
> +   */
> +  get _downloadsUIContractId() "@mozilla.org/download-manager-ui;1",

any reasons why these are not just const at the top?

@@ +234,5 @@
> +   */
> +  _dmInitialized: false,
> +
> +  /**
> +   * True if we are processing the application shutdown event.

well, actually it's whether application is shutting down.

@@ +241,5 @@
> +
> +  /**
> +   * Ensures that persistent download data is reloaded at the appropriate time,
> +   * if the conditions are met.  Depending on the session restore state, either
> +   * active downloads or all downloads from the previous session are loaded.

please explain the 2 cases, rather than forcing the reader to figure out which case does what

@@ +259,5 @@
> +    DownloadsCommon.data.ensurePersistentDataLoaded(!this._sessionWasRestored);
> +  },
> +
> +  /**
> +   * Posts the given function to be executed on the main thread.

to be enqueued is more correct since it's not a DISPATCH_SYNC

@@ +265,5 @@
> +  _executeSoon: function DS_executeSoon(aCallbackFn)
> +  {
> +    let self = this;
> +    let mainThread = Cc["@mozilla.org/thread-manager;1"]
> +                     .getService(Ci.nsIThreadManager)

Services.tm

::: browser/components/downloads/src/DownloadsUI.js
@@ +53,5 @@
> +const Cr = Components.results;
> +
> +Cu.import("resource://gre/modules/Services.jsm");
> +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
> +Cu.import("resource:///modules/DownloadsCommon.jsm");

defineLazyModuleGetter DownloadsCommon.jsm, the other 2 are expected to be globally inited already so doesn't matter for those.

@@ +89,5 @@
> +      aReason = Ci.nsIDownloadManagerUI.REASON_USER_INTERACTED;
> +    }
> +
> +    if (DownloadsCommon.useWindowUI) {
> +      this._toolkitUI.show(aWindowContext, aID, aReason);

overriding aReason before passing it to the toolkit UI doesn't seem useful, since it does the same thing, I'd just check windowUI before so we are sure we passthrough the original value.

@@ +93,5 @@
> +      this._toolkitUI.show(aWindowContext, aID, aReason);
> +      return;
> +    }
> +
> +    // Don't show the panel for downloads after the first one in the session.

Wouldn't this become annoying after I'm used to the new panel?
I guess it's done to educate users to the new panel, but it keeps happening forever at every new session. Imo it should appear for a certain number of sessions (like 5) and then stop nagging the user, btw it's something that may be defined later.

@@ +122,5 @@
> +           Services.obs.removeObserver(observer, topic);
> +           aSubject.DownloadsPanel.showPanel();
> +         }
> +      };
> +      Services.obs.addObserver(observer, topic, false);

you can pass a function here

Services.obs.addObserver(function observeDelayedStartup(aSubject, aTopic, aData) {
  Services.obs.removeObserver(observeDelayedStartup, aTopic);
  aSubject.DownloadsPanel.showPanel();
}, "browser-delayed-startup-finished", false);

@@ +129,5 @@
> +      let windowFirstArg = Cc["@mozilla.org/supports-string;1"]
> +                           .createInstance(Ci.nsISupportsString);
> +      let windowArgs = Cc["@mozilla.org/supports-array;1"]
> +                       .createInstance(Ci.nsISupportsArray);
> +      windowArgs.AppendElement(windowFirstArg);

do you really need all of this, the ww interface seems to support null for arguments, as well as an empty array

::: browser/components/downloads/test/browser/Makefile.in
@@ +13,5 @@
> +
> +_BROWSER_FILES = \
> +  browser_basic_functionality.js \
> +  browser_delete_key_removes.js \
> +  head.js \

nit: move head to the first position, so further tests can just be appended

::: browser/components/downloads/test/browser/head.js
@@ +16,5 @@
> +
> +const nsIDM = Ci.nsIDownloadManager;
> +
> +let gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
> +gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0x1B6); // Octal 666

you can use parseInt("666", 8); that is self documenting, or use FileUtils.PERMS_FILE that may be enough

to ensure correct cleanup you may registerCleanupFunction here to remove this file.

::: browser/components/nsBrowserGlue.js
@@ +1204,5 @@
> +
> +      // Need to migrate only if toolbar is customized and the element is not found.
> +      if (currentset &&
> +          currentset.indexOf("downloads-button") == -1) {
> +        // The element is added before the all tabs button, or as the last button.

I don't understand why it must be before all-tabs

::: browser/locales/en-US/chrome/browser/downloads/downloads.dtd
@@ +21,5 @@
> +<!ENTITY cmd.removeFromList.label         "Remove From List">
> +<!ENTITY cmd.removeFromList.accesskey     "e">
> +
> +<!ENTITY downloadshistory.label           "Show Downloads History">
> +<!ENTITY downloadshistory.accesskey       "S">

Considering consistency with Show All Bookmarks and Show All History, I'm tempted to suggest Show All Downloads

::: browser/themes/winstripe/browser/downloads/downloads.css
@@ +2,5 @@
> +
> +#downloadsListBox {
> +  -moz-appearance: none;
> +  width: 45em;
> +  background: #CCC;

these values seem random.
how did you choose the width? it seems pretty large, why does this define a hardcoded background (and no foreground)?

@@ +7,5 @@
> +}
> +
> +#downloadsHistory {
> +  -moz-appearance: none;
> +  width: 45em;

is this needed, can it rather flex?

@@ +9,5 @@
> +#downloadsHistory {
> +  -moz-appearance: none;
> +  width: 45em;
> +  border-radius: 2px;
> +  border: none;

does it have a border or not?

@@ +11,5 @@
> +  width: 45em;
> +  border-radius: 2px;
> +  border: none;
> +  padding: 0;
> +  margin: 0 6px;

why 6? if the button flex and has no border I don't expect this to make an interesting difference
and if so you may just add the .plain class to the button

@@ +15,5 @@
> +  margin: 0 6px;
> +}
> +
> +#downloadsHistory:hover {
> +  background-color: #DDD;

ditto

@@ +28,5 @@
> +
> +richlistitem[type="download"][selected] {
> +  background: transparent;
> +  color: -moz-dialogtext;
> +  outline: 1px #999 dotted;

doesn't look native

@@ +36,5 @@
> +richlistitem[type="download"][state="1"]:hover {
> +  /* Finished downloads can be clicked once to open the target, if it exists. */
> +  background-color: #DDD;
> +  color: -moz-dialogtext;
> +  cursor: pointer;

the relation of the comment with the underlying rule seems weak

@@ +73,5 @@
> +  border: none;
> +  padding: 4px;
> +  margin: 0;
> +  min-height: 0;
> +  min-width: 0;

you may use the .plain class and just override padding

::: toolkit/components/downloads/nsDownloadManager.cpp
@@ +883,5 @@
>      do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
>  
> +  (void)mObserverService->NotifyObservers(
> +                                static_cast<nsIDownloadManager *>(this),
> +                                "download-manager-initialized",

define a DM_INITIALIZED_TOPIC

@@ +1830,5 @@
>  
> +  // Notify that the database type changed before resuming current downloads
> +  (void)mObserverService->NotifyObservers(
> +                                static_cast<nsIDownloadManager *>(this),
> +                                "download-manager-database-type-changed",

define a DM_DATABASE_CHANGED_TOPIC

::: toolkit/components/downloads/test/browser/browser_nsIDownloadManagerUI.js
@@ +125,5 @@
>        t(win);
>  
> +    Cc["@mozilla.org/preferences-service;1"].
> +    getService(Ci.nsIPrefBranch).
> +    clearUserPref("browser.download.manager.useWindowUI");

inconsistent indentation in the same test, btw you should use registerCleanupFunction in b-c tests

::: toolkit/content/Services.jsm
@@ +65,5 @@
>  let initTable = [
>    ["console", "@mozilla.org/consoleservice;1", "nsIConsoleService"],
>    ["contentPrefs", "@mozilla.org/content-pref/service;1", "nsIContentPrefService"],
>    ["cookies", "@mozilla.org/cookiemanager;1", "nsICookieManager2"],
> +  ["dm", "@mozilla.org/download-manager;1", "nsIDownloadManager"],

considering the other naming in Services I'd probably use Services.downloads

::: toolkit/mozapps/downloads/tests/chrome/test_ui_stays_open_on_alert_clickback.xul
@@ +115,5 @@
>          clearUserPref("browser.download.manager.closeWhenDone");
> +
> +        Cc["@mozilla.org/preferences-service;1"].
> +        getService(Ci.nsIPrefBranch).
> +        clearUserPref("browser.download.manager.useWindowUI");

the indentation differs from the rest, I don't mind which of the tens styles existing you use in tests, but be consistent.
Attachment #550148 - Flags: review?(mak77)
(In reply to Marco Bonardo [:mak] from comment #325)
> This is a first pass, since I had to read it all to figure out what changed
> from the last time

Yeah, I knew the interdiff wasn't helpful given the amount of changes.
I really appreciate your review effort, thank you very much!

> I may have more comments regarding the whole structure, but I have to think
> about it a bit more, now that I've refreshed my mind.

If you have any insight, just tell me, and I'll be able to address it in
the next iteration.

> In the meanwhile I guess you may already have an updated version
> with the new design.

This is what I'm working on first, before addressing code review, yes.

> Btw, I'm in favor of pushing next iteration to UX branch, I'll do another
> pass to bug 663772 shortly.

Some things you noticed in this bug will make sense when you look at the
other. It's a patch on top of this one, that changes a few things.

> So, while the positioning on the tabbar has seen some reasoning, I'm not
> sure why this is in the middle of buttons that act on tabs, esp. between
> newtab and alltabs. I think for now it should go to the far end of the bar,
> after tabs-closebutton, rather than interrupting that group of related
> elements.

Well, this way the alltabs button is more difficult to target when the window
is maximized because it does not touch the border of the screen. I'd like some
feedback from the UX team here.

> @@ +94,5 @@
> > +
> > +  /**
> > +   * State of the downloads panel, based on one of the kPanel constants.
> > +   */
> > +  _panelState: 0,
> 
> should be inited to one of the constants rather than a magic number

But they're not in scope until the object literal is terminated. Besides,
the constants are defined next line, so I thought unnecessary to add a
comment saying that 0 is a specific constant.

> @@ +103,5 @@
> > +  get kPanelHidden() 1,
> > +  /** The panel will be shown as soon as possible. */
> > +  get kPanelShowing() 2,
> > +  /** The panel is open, though download data might still be loading. */
> > +  get kPanelShown() 3,
> 
> I still suggest a fake enum approach

Well, I think I can switch style here, since you're the official reviewer now!
But I have to confess that seeing these few lines switching back and forth
again and again and again between styles looks funny to me :-)

Shawn previously asked to use getters to ensure constantness. What is your
point of view on this? Which of the following styles would you prefer?

_panelStates: { uninitialized: 0, hidden: 1 },

_panelStates: {
  get uninitialized() 0,
  get hidden() 1
},

get _panelStates() { uninitialized: 0, hidden: 1 },

Note, the last one is the least efficient.

> @@ +502,5 @@
> > +
> > +    let dataTransfer = aEvent.dataTransfer;
> > +    dataTransfer.mozSetDataAt("application/x-moz-file", localFile, 0);
> > +    dataTransfer.effectAllowed = "copyMove";
> > +    dataTransfer.addElement(element);
> 
> is addElement needed? which node are events fired otherwise?

Not sure what you're asking, doesn't addElement determine which elements are
displayed while you're dragging?

> > +XPCOMUtils.defineLazyGetter(DownloadsCommon, "isOnWindowsVista", function () {
> 
> why don't you use the same check that is in toolkit, with cheaper
> preprocessed XP_WIN and just the check to system-info?

This is not called so often to justify the additional build step, I think.
Shawn asked to do this in comment 280, so he might have other reasons. By the
way, I guess we should have a global SystemInfo preprocessed JSM if we think
it's important.

> @@ +299,5 @@
> > +    // Sort backwards by download identifier, ensuring that the most recent
> > +    // downloads are added first regardless of their state.
> > +    let loadedItemsArray = [dataItem
> > +                            for ([, dataItem] in Iterator(this.dataItems))
> > +                            if (dataItem)];
> 
> what's the point of the Iterator, if you can use [dataItem for each
> (dataItem in this.dataItems) if (dataItem)]

I did a specific question about the use of Iterator() in comment 182, and
also kept it for some time in the list of open questions on the wiki page,
but I got no response. I'd have written all the code according to the
defined style instead of having to check it all again. So I'll repeat the
question hoping to have a definitive answer now.

* I'm accustomed to use "Iterator()" in for loops because it filters out
  properties added to "Object.prototype", for example by extensions that
  don't behave in the right way. Do we care making at least newly written
  front-end code robust to this eventuality?

> @@ +213,5 @@
> > +
> > +  /**
> > +   * Contract ID of the service implementing nsIDownloadManagerUI.
> > +   */
> > +  get _downloadsUIContractId() "@mozilla.org/download-manager-ui;1",
> 
> any reasons why these are not just const at the top?

Consistency with other code in the "downloads" directory.

> ::: browser/components/downloads/src/DownloadsUI.js
> @@ +53,5 @@
> > +const Cr = Components.results;
> > +
> > +Cu.import("resource://gre/modules/Services.jsm");
> > +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
> > +Cu.import("resource:///modules/DownloadsCommon.jsm");
> 
> defineLazyModuleGetter DownloadsCommon.jsm, the other 2 are expected to be
> globally inited already so doesn't matter for those.

The whole DownloadsUI.js is lazy loaded itself, and we use DownloadsCommon in
any function for sure. Should I use the lazy module getter anyway as a
standardized coding example, even if lazyness isn't needed?

> @@ +122,5 @@
> > +           Services.obs.removeObserver(observer, topic);
> > +           aSubject.DownloadsPanel.showPanel();
> > +         }
> > +      };
> > +      Services.obs.addObserver(observer, topic, false);
> 
> you can pass a function here

Cool!

> @@ +129,5 @@
> > +      let windowFirstArg = Cc["@mozilla.org/supports-string;1"]
> > +                           .createInstance(Ci.nsISupportsString);
> > +      let windowArgs = Cc["@mozilla.org/supports-array;1"]
> > +                       .createInstance(Ci.nsISupportsArray);
> > +      windowArgs.AppendElement(windowFirstArg);
> 
> do you really need all of this, the ww interface seems to support null for
> arguments, as well as an empty array

Yeah, it's required by "browser.js", took some time to figure out what was
the minimum I needed to do. I hoped the comment "we must build an empty
arguments list for the new window" was clear, but I'll expand it.

> ::: browser/components/downloads/test/browser/Makefile.in
> @@ +13,5 @@
> > +
> > +_BROWSER_FILES = \
> > +  browser_basic_functionality.js \
> > +  browser_delete_key_removes.js \
> > +  head.js \
> 
> nit: move head to the first position, so further tests can just be appended

Isn't alphabetical order better when adding new tests, instead of appending
them at the end of the list? Especially as the list grows larger.

> ::: toolkit/components/downloads/nsDownloadManager.cpp
> @@ +883,5 @@
> >      do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
> >  
> > +  (void)mObserverService->NotifyObservers(
> > +                                static_cast<nsIDownloadManager *>(this),
> > +                                "download-manager-initialized",
> 
> define a DM_INITIALIZED_TOPIC

Constants are never used for all other topics in this file so I don't see why
we should introduce this change now. If we really care, we could do this in
a follow-up, and consistently for the whole file.

> ::: toolkit/components/downloads/test/browser/browser_nsIDownloadManagerUI.js
> @@ +125,5 @@
> >        t(win);
> >  
> > +    Cc["@mozilla.org/preferences-service;1"].
> > +    getService(Ci.nsIPrefBranch).
> > +    clearUserPref("browser.download.manager.useWindowUI");
> 
> inconsistent indentation in the same test, btw you should use
> registerCleanupFunction in b-c tests

Ok for the indentation, but I fear that any other change that tries to improve
how this test does things might easily turn into a complete refactoring, like
it happened recently for the downloads history test. This is old code, and
does a lot of things in an outdated way: registerCleanupFunction should be
used for more than the individual clearUserPref. Refactoring is appropriate
in some cases, but now I'd really prefer to keep diffs in old code to a
minimum and focus on current work.
(In reply to Paolo Amadini from comment #326)
> > So, while the positioning on the tabbar has seen some reasoning, I'm not
> > sure why this is in the middle of buttons that act on tabs, esp. between
> > newtab and alltabs. I think for now it should go to the far end of the bar,
> > after tabs-closebutton, rather than interrupting that group of related
> > elements.
> 
> Well, this way the alltabs button is more difficult to target when the window
> is maximized because it does not touch the border of the screen. I'd like
> some
> feedback from the UX team here.

Looks like both approaches have downsides, but all tabs is visually and functionally bound to the tabs on its left, and this is not a tab clearly. Fine if you want to ask ux, I still feel like this positioning will be the hardest thing to figure out here.


> Shawn previously asked to use getters to ensure constantness. What is your
> point of view on this? Which of the following styles would you prefer?
> _panelStates: { uninitialized: 0, hidden: 1 },

Personally I'd just go for this one, that is the less const safe (honestly I don't see how/why anyone may try to change those), btw, if Shawn was fine with the original getters, it's ok to keep them as they are.

> > @@ +502,5 @@
> > > +
> > > +    let dataTransfer = aEvent.dataTransfer;
> > > +    dataTransfer.mozSetDataAt("application/x-moz-file", localFile, 0);
> > > +    dataTransfer.effectAllowed = "copyMove";
> > > +    dataTransfer.addElement(element);
> > 
> > is addElement needed? which node are events fired otherwise?
> 
> Not sure what you're asking, doesn't addElement determine which elements are
> displayed while you're dragging?

https://developer.mozilla.org/En/DragDrop/DataTransfer#addElement.28.29
"Set the drag source. Usually you would not change this, but it will affect which node the drag and dragend events are fired at. The default target is the node that was dragged."

So, I am not sure if there is real need to enforce it here.

> > why don't you use the same check that is in toolkit, with cheaper
> > preprocessed XP_WIN and just the check to system-info?
> 
> This is not called so often to justify the additional build step, I think.
> Shawn asked to do this in comment 280, so he might have other reasons.

Ok, fine then, there are too many comments in this bug.

> * I'm accustomed to use "Iterator()" in for loops because it filters out
>   properties added to "Object.prototype", for example by extensions that
>   don't behave in the right way. Do we care making at least newly written
>   front-end code robust to this eventuality?

If an extension touches these internal properties I'd be more lean to blacklist it. If you iterate an object that you got passed in from the outside then it's probably fine to be pickier, doesn't seem this case though. Interestingly, Object.keys behaves the same as Iterator.

> > defineLazyModuleGetter DownloadsCommon.jsm, the other 2 are expected to be
> > globally inited already so doesn't matter for those.
> 
> The whole DownloadsUI.js is lazy loaded itself, and we use DownloadsCommon in
> any function for sure. Should I use the lazy module getter anyway as a
> standardized coding example, even if lazyness isn't needed?

If the constructor or the first invoked function uses the module there is no need to being lazier, otherwise if "some function" will use it later, it's better being lazier. Doesn't matter for xpcomutils and services, since those are usually already loaded for anyone.

> > @@ +129,5 @@
> > > +      let windowFirstArg = Cc["@mozilla.org/supports-string;1"]
> > > +                           .createInstance(Ci.nsISupportsString);
> > > +      let windowArgs = Cc["@mozilla.org/supports-array;1"]
> > > +                       .createInstance(Ci.nsISupportsArray);
> > > +      windowArgs.AppendElement(windowFirstArg);
> > 
> > do you really need all of this, the ww interface seems to support null for
> > arguments, as well as an empty array
> 
> Yeah, it's required by "browser.js", took some time to figure out what was
> the minimum I needed to do. I hoped the comment "we must build an empty
> arguments list for the new window" was clear, but I'll expand it.

Do you know which part of browser.js? I find amusing it requires an array containing an empty string...

> Isn't alphabetical order better when adding new tests, instead of appending
> them at the end of the list? Especially as the list grows larger.

alphabetical is fine, but head is head :) Btw I don't mind much.

> This is old code, and
> does a lot of things in an outdated way: registerCleanupFunction should be
> used for more than the individual clearUserPref. Refactoring is appropriate
> in some cases, but now I'd really prefer to keep diffs in old code to a
> minimum and focus on current work.

In this case there is no need to refactor anything, correctly cleanup a single piece is better than wrongly cleanup everything, especially in b-c tests where we have far too many oranges. I don't care if registerCleanupFunction should be used for more, let's start using it for that single thing, the diff won't change in size.
(In reply to Paolo Amadini from comment #326)
> > So, while the positioning on the tabbar has seen some reasoning, I'm not
> > sure why this is in the middle of buttons that act on tabs, esp. between
> > newtab and alltabs. I think for now it should go to the far end of the bar,
> > after tabs-closebutton, rather than interrupting that group of related
> > elements.
> 
> Well, this way the alltabs button is more difficult to target when the window
> is maximized because it does not touch the border of the screen. 

I think this is a minor issue, when you have tabs in titlebar, the alltabs button is on the left of the window caption buttons, thus it also doesn't touch the border, and it was considered acceptable.
This version of the patch is the first with includes a draft of the visual
design, different for the three major platforms. Another tryserver build is
following in the next days for preliminary testing.
Can you provide us screenshots, please?
(In reply to Peter Henkel [:Terepin] from comment #330)
> Can you provide us screenshots, please?

Not for all the three platforms, in any case there are too many combinations of
the user interface states to get a sense of how things work from one screenshot.
A tryserver build will be available in the next days, however.

Stephen made some interface mockups some time ago, they're very clear, maybe he
can post the links if they are still relevant to the current version.
(In reply to Paolo Amadini from comment #331)
> Stephen made some interface mockups some time ago, they're very clear, maybe
> he can post the links if they are still relevant to the current version.

Forgot to attach these! Also see: http://people.mozilla.com/~shorlander/download-panel-specs/download-panel-specs.html
Can I share my suggestion about Aero styling?
Could it be pushed to UX, please ?
I just noticed a minor issue: The "Show Downloads History" button needs to be hidden if the user has disabled their downloads history via their privacy preferences. It looks like you need to check the "browser.download.manager.retention" pref.
https://developer.mozilla.org/en/Download_Manager_preferences
Needless to say, this feature will affect compatibility of some add-ons :-)

I'm adding the new "addon-compat" bug keyword that is now used by the Mozilla
Add-ons team to track this type of changes and ensure that they are communicated
to add-on developers.
Keywords: addon-compat
(In reply to Dave Garrett from comment #335)
> I just noticed a minor issue: The "Show Downloads History" button needs to
> be hidden if the user has disabled their downloads history via their privacy
> preferences. It looks like you need to check the
> "browser.download.manager.retention" pref.
> https://developer.mozilla.org/en/Download_Manager_preferences

Actually, this preference controls retention of items in the the panel, and has
no effect on history (and never had in the past, too). History preferences and
private browsing options control the lifetime of items in the Library window.
I have a question which affects some of my future ideas for per-window private browsing support.  Is the new downloads panel tied to the window?  For example if I have two windows open and I initiate a download in Window 1, would it appear in the download pane for window 2?
(In reply to Ehsan Akhgari [:ehsan] from comment #338)
> I have a question which affects some of my future ideas for per-window
> private browsing support.  Is the new downloads panel tied to the window? 

Currently, the same download items appear in all windows. This is a choice, but
also a consequence of the fact that the panel is (almost) just a view of the
list of downloads kept by the Toolkit back-end. In fact, per-window Private
Browsing Mode support would probably need a different back-end implementation.
This version is based on the previous one, and includes several improvements and
fixes that Marco made to the styles, for all the platforms. Because all the
major issues have been addressed, and the patch reflects the initial user
experience design, this iteration is probably ready for landing on the UX
branch, for wider feedback.
Attachment #550148 - Attachment is obsolete: true
Attachment #556580 - Attachment is obsolete: true
Attachment #550148 - Flags: ui-review?(banerjee.sinchan)
(In reply to Paolo Amadini from comment #340)
> this iteration is probably ready for landing on the UX
> branch, for wider feedback.
Good news.
Here is the tryserver build that includes the draft of the visual design:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-b824c49ecf9f

This build implements all the functionality that should be present in the final
version, except for opening files with double-clicks from the Library window.

Though there are several known issues, please report everything that you think
should be improved for reaching a first version of the feature that is ready
for integration on mozilla-central. This includes code, interaction and visual
design. We'll merge all the feedback we receive with the list of known issues,
then we'll prioritize and fix any blocking issue before finalizing the feature.

Accessibility testing is also welcome on this build.
Looks great, but when you maximize the window with tabs on bottom, the dialogue gets shoved over, so the arrow appears to be coming from the panorama button instead of the download button. Perhaps the two should be switched?
(In reply to Chris Barry [Christo27] from comment #343)
> Created attachment 558652 [details]
> Tabs on Bottom Maximized
> 
> Looks great, but when you maximize the window with tabs on bottom, the
> dialogue gets shoved over, so the arrow appears to be coming from the
> panorama button instead of the download button. Perhaps the two should be
> switched?

You mean switch the position of the buttons? That wouldn't help much; you can move buttons pretty much anywhere via the toolbar customization dialog. It'll just need fixing to always point in the correct place regardless of UI configuration.

Anyone know if this a bug in this or is it maybe a bug in the arrow panel widget itself?
Some more issues:
Button corrupted when downloading with "Show downloads window..." preffed OFF - pref is no longer needed
Search icon doesn't convey the idea of "Open containing folder"
No X button to delete an entry from the list
Ctrl+J should also close the popup, there may also be a close button
Button does not appear immediately on startup
No hover indication like other buttons in Tab bar
(In reply to Dave Garrett from comment #344)
> (In reply to Chris Barry [Christo27] from comment #343)
> > Created attachment 558652 [details]
> > Tabs on Bottom Maximized
> > 
> > Looks great, but when you maximize the window with tabs on bottom, the
> > dialogue gets shoved over, so the arrow appears to be coming from the
> > panorama button instead of the download button. Perhaps the two should be
> > switched?
> 
> You mean switch the position of the buttons? That wouldn't help much; you
> can move buttons pretty much anywhere via the toolbar customization dialog.
> It'll just need fixing to always point in the correct place regardless of UI
> configuration.
> 
> Anyone know if this a bug in this or is it maybe a bug in the arrow panel
> widget itself?

This is a issue with the arrow panel widget. The arrow fixed a certain distance from the edge of the panel, so there's horizontal space on either side of the screen that the arrow couldn't point to. I came across this in bug 615476, but I don't think a potential solution was ever discussed.
(In reply to Margaret Leibovic [:margaret] from comment #346)
> (In reply to Dave Garrett from comment #344)
> > (In reply to Chris Barry [Christo27] from comment #343)
> > > Created attachment 558652 [details]
> > > Tabs on Bottom Maximized
> 
> This is a issue with the arrow panel widget. The arrow fixed a certain
> distance from the edge of the panel, so there's horizontal space on either
> side of the screen that the arrow couldn't point to. I came across this in
> bug 615476, but I don't think a potential solution was ever discussed.

Yes, this has been quite an edge case until now, but will become more relevant
as we implement this design for the downloads panel. I agree with bug 615476
comment 17, we might need a new type of asymmetric arrow placed at the corner
of the popup.

Another issue is the behavior of the panel when the anchor moves. This happens
very often in the current design, for example when a download is completed.
Currently, the panel moves following the anchor, though sometimes the movement
of the anchor isn't detected for some reason.

If we place the arrow at a greater distance from the panel's edge by default,
like in bug 615476, we'll have room for moving only the arrow and not the rest
of the panel when the anchor moves, which I think is a far better experience.
(In reply to sdrocking from comment #345)
> Some more issues:
> Button corrupted when downloading with "Show downloads window..." preffed
> OFF - pref is no longer needed
> Search icon doesn't convey the idea of "Open containing folder"
> No X button to delete an entry from the list
> Ctrl+J should also close the popup, there may also be a close button
> Button does not appear immediately on startup
> No hover indication like other buttons in Tab bar

Excellent, this is the kind of feedback we need, concise and thorough :-)

Why do you think that Ctrl+J should also close the popup? The ESC key is used
for that, and having the same key for opening and closing might be confusing.
Despite we do that for the standalone downloads window today, it doesn't mean
it's necessarily the best option for a panel interface.
Depends on: 685357
On Windows 7 (I haven't tested other platforms) the download panel isn't wide enough to show the entire speed of the download. It says "(173 ...", so I don't know if that's in KB/sec, MB/sec, etc.
Since download manger is now embedded to the browser window , on closing the browser window (last) all downloads are closed. So we should have a dialog box saying "You have some downloads pending.  |Close| |Wait for them to finish| " or something like that ...
When all downloads are completed, the green shadow around the glyph is clipped.
New DM looks great, but there are 2 things that need to be improved before rolling it out in my opinion.

First, there is no way to one-click clear all the items from the DM box. 
And there definitely should be one. 
Simple little button like "Clear All" would be fine.

Second, the old pre-download box should be re-designed to match the new DM concept.
For now, it looks somehow clumsy on the new UI.
I mean the "You have chosen to open.." dialog box.

These are relevant to the Win7 version (don't know how it's implemented for other systems).
It feels strange not having a background for the new Download Manger button.
(In reply to bogas04 from comment #350)
> Since download manger is now embedded to the browser window , on closing the
> browser window (last) all downloads are closed. So we should have a dialog
> box saying "You have some downloads pending.  |Close| |Wait for them to
> finish| " or something like that ...

We already show such a message, but only if you have any download in progress
that cannot be paused automatically. This is done to reduce the number of
dialog boxes that get in the way of a smooth user experience.

(In reply to Edward Forreal from comment #352)
> First, there is no way to one-click clear all the items from the DM box. 
> And there definitely should be one. 
> Simple little button like "Clear All" would be fine.

Since completed downloads are automatically cleared when the browsing session
ends, we thought that such an interaction wasn't necessary, since the panel is
meant to be as lightweight as possible, with little need for management of
individual entries.

Personally, I believe that a simpler way to remove items from the panel during
the same session would be useful, though the perceived need for that might
actually depend on browsing habits that are a result of how the current user
interface works.

> Second, the old pre-download box should be re-designed to match the new DM
> concept.
> For now, it looks somehow clumsy on the new UI.
> I mean the "You have chosen to open.." dialog box.

This is definitely something we are looking forward to, though we are not
working on it as part of this bug. We have even more ideas to improve the
experience of downloading files locally, and most of them haven't started yet.
Actually, anyone willing to file new bugs and start hacking a patch is welcome!

https://wiki.mozilla.org/User:P.A./Download_user_experience_improvements
@Paolo Amadini

Thanks for your reply Paolo.

Regarding clearing the list. There are some cases when user would want to clear that list without restarting session.

E.g. too much downloads in list, so they definitely would want to clear the space to continue. Restart is kinda ugly option for this case.
Also there might be some privacy issues, when the user wants to clear the list so their, say, coworkers won't see any inappropriate stuff standing behind their back.

So I, personally, still believe that the little tiny button won't hurt much and even opposite.
(In reply to Paolo Amadini from comment #354)
> We already show such a message, but only if you have any download in progress
> that cannot be paused automatically. This is done to reduce the number of
> dialog boxes that get in the way of a smooth user experience.
Some users in any case necessary to know about the uncompleted download.
For example, many file sharing give out a direct link to file only for a few hours. If the next day user will discover that it has an incomplete file, the user would have to spend a few hours to Resume file, or even download the file again.

> Since completed downloads are automatically cleared when the browsing session
> ends, we thought that such an interaction wasn't necessary, since the panel
> is
> meant to be as lightweight as possible, with little need for management of
> individual entries.
Often, the browser does not close within a few days. In addition, in a single session can be downloaded hundreds of images and one text document.
I would also like to be able to clear the list of hundreds of pictures with one click, then to download a text document and open its folder from the new download manager.
There are also users like me who currently use Download Statusbar's ability to clear everything on completion after an X-second delay.

I'd really like to be able to ditch that extension for something less commercialized, but there's a limit to how many clicks/keypresses I'm willing to add to my muscle memory for the process of downloading a file.

As for resuming, a warning is an essential option for anyone who uses a site that doesn't support resume but doesn't trip off automatic detection. (I've had friends tell me that various file lockers seem to do that to try to further annoy non-paying users)
Depends on: 686065
If button is not on the tab bar by the user , then while a download , the button should persist until it gets over. Its so annoying to keep going to downloads or do ctrl+j to check how much of different downloads are completed. Also the progress meter showing time in tab bar is also useful while an on-going download
Letting it to be as big as screen height is not a good idea I guess..
To my above comment , we can probably show 5~6 recent downloads (must be lower for netbooks) coz the rest of the older downloads can be obviously seen from "Show Download History" button.
when download arrow placed on far right on Mac http://dl.dropbox.com/u/61985/Screen.fx.ux.png
In windows also.
The time remaining (In reply to Theodore from comment #349)
> Created attachment 559032 [details]
> Full download speed is not shown on Windows 7
> 
> On Windows 7 (I haven't tested other platforms) the download panel isn't
> wide enough to show the entire speed of the download. It says "(173 ...", so
> I don't know if that's in KB/sec, MB/sec, etc.

The time remaining can be shown as "2m 47s" instead of "2 minutes 47 seconds" to save some space.
I've seen the new Download Manager UI in the latest UX build, it's awesome!!!
Guys if you do not want to add "Clear All Downloads" button to the new DM and that's written in stone, I have another win-win suggestion.

Just add that option (Clear all DM entries) to the right-click context menu when mouse is hovered over the DM box. It would be fine too.
Some accessibility feedback:
1. The Downloads panel announces itself as "Download", and the type is spoken as "grouping". Yay! That's totally correct!
2. Focus usually returns to where one was before download manager when pressing Escape. That's great, too! However, if nothing was focused when DM was invoked, focus should be set explicitly to the document, so that it doesn't get into a limbo state.
3. The option to open the file in focus is nowhere to be found. I can only reach an "Open containing folder" both when tabbing and in the context menu.
4. Another big plus: We have a full tab circle, focus doesn't jump out of the panel when tabbing, that's awesome!

Keep up the good work!
(In reply to Marco Zehe (:MarcoZ) from comment #366)
> Some accessibility feedback:

Thank you for the feedback!

> 3. The option to open the file in focus is nowhere to be found. I can only
> reach an "Open containing folder" both when tabbing and in the context menu.

We open the file when a completed download item (which is a richlistitem) is
clicked, or the return or enter keys are pressed while the item is focused.
Is there a way to provide to the accessibility system a description of the
default action that is executed when activating a list item, if any?
(In reply to Paolo Amadini from comment #367)

> > 3. The option to open the file in focus is nowhere to be found. I can only
> > reach an "Open containing folder" both when tabbing and in the context menu.
> 
> We open the file when a completed download item (which is a richlistitem) is
> clicked, or the return or enter keys are pressed while the item is focused.
> Is there a way to provide to the accessibility system a description of the
> default action that is executed when activating a list item, if any?

Announcing default action on each traversed list item might be annoying. It sounds like adding an item into context menu is a good option. Enter key discoverability is part of evangelism I think. From accessibility API point of view it's reasonable to expose second action via action interface on list item but not sure if screen readers allows to pick up and announce this information and on the another hand Gecko doesn't have good support of multiple actions still.
The new popup does not convey when the downloaded file has been externally removed. When you click on the list item or on the (confusing) magnifying glass, nothing happens.
I can't to see the speed of download:

http://i.minus.com/ibdBHKWU6dOe3j.png

I hope in final version it can be improved.
Attached image Clear list icon
(In reply to Paolo Amadini from comment #354)
> (In reply to Edward Forreal from comment #352)
> > First, there is no way to one-click clear all the items from the DM box. 
> > And there definitely should be one. 
> > Simple little button like "Clear All" would be fine.
> 
> Since completed downloads are automatically cleared when the browsing session
> ends, we thought that such an interaction wasn't necessary, since the panel
> is
> meant to be as lightweight as possible, with little need for management of
> individual entries.

If the panel is meant to be as lightweight as possible then you can add just a little icon to corner of the panel that will not disturb overall design. When the mouse hovering the icon, label "Show download history" can change value to "Clear the list"
Is it ready enough (or has upcoming changes) for Firefox 9 nightly > aurora merge?
(In reply to bogas04 from comment #372)
> Is it ready enough (or has upcoming changes) for Firefox 9 nightly > aurora merge?

There's a bit of work left and even if it were finished soon it doesn't look like there's enough time for sufficient testing before the next merge. My guess would be to expect this for Firefox 10. (though it would be nice if I were wrong ;)
Attached image menu
I suggest you do menu similar to history menu
Are there plans to create a clear-list button or a menu in the app-button?
(In reply to Tiger.711 from comment #376)
> Are there plans to create a clear-list button or a menu in the app-button?

there will be a context menu option to clear the list.
Excellent! We will be happy! And what else would be tasty in the context menu?
(In reply to Tiger.711 from comment #378)
> And what else would be tasty in the context menu?

Cheeseburger. :D
(In reply to Marco Bonardo [:mak] from comment #377)
> (In reply to Tiger.711 from comment #376)
> > Are there plans to create a clear-list button or a menu in the app-button?
> 
> there will be a context menu option to clear the list.

Wow! That's an awesome news! Thank you very much guys ;]
Comment on attachment 558500 [details] [diff] [review]
First version for user experience feedback

> +#downloadsHistory {
...
> +  cursor: pointer;
> +}
> +
> +#downloadsHistory:hover {
> +  cursor: hand;
> +}

Paolo (or whoever picks up this bug (maybe Felipe)), the `#downloadsHistory:hover` rules should be removed. `hand` is not a valid value for CSS cursor, and `cursor: pointer;` is already sufficient. (This appears in winstripe, pinstripe, and gnomestripe.)
The new download manager in the UX builds rocks, but there is a small annoying issue, if you have too many downloads looks too big and ugly please limit it to show the last 5-10 downloads + the download history link.
Depends on: 697678
Depends on: 697679
Depends on: 697680
Depends on: 697683
Depends on: 697686
Depends on: 697687
Depends on: 697688
Direct2d needs to be disabled on some machines to see the doorhanger.
Depends on: 617128
Paolo, please check the changes in Bug 397424, since may affect your patches.
Keywords: access
(In reply to Marco Bonardo [:mak] from comment #384)
> Paolo, please check the changes in Bug 397424, since may affect your patches.

Thank you, I checked them out, and I see some optimizations related to setting
attributes on the progress bars and dispatching the ValueChange event, that
could definitely also apply to the current patches.

Also, QueryInterface(Ci.nsIDownload) is not necessary after getNext() anymore.

Other changes are related to formatting text using the string bundle, which we
already do. The API hasn't changed. Let me know if there is something I'm missing
here, otherwise I think the optimizations can wait until after the final user
interface is drafted in the UX branch.
(In reply to Paolo Amadini from comment #385)
> Let me know if there is something I'm
> missing
> here, otherwise I think the optimizations can wait until after the final user
> interface is drafted in the UX branch.

I mostly care we don't regress the improvements that may have landed there.
This is the same patch as before, updated because of the recent change of the
structure of the theme folders. This patch can be used as the base for local
patch queues. It also matches the version now on the UX branch, where theme
structure changes have been already merged.
Attachment #558500 - Attachment is obsolete: true
Perhaps due to changes in other parts of the code base, it seems like these patches now cause test failures again:
https://tbpl.mozilla.org/?tree=Try&rev=ca89cb42dc86

Paolo, if you have local versions of the patches that do not exhibit these failures, please upload them. If not, we can investigate them.
(In reply to Frank Yan (:fryn) from comment #388)
> Perhaps due to changes in other parts of the code base, it seems like these
> patches now cause test failures again:

That's probably because the new "test_destinationURI_annotation.xul" needs the
same preference switching as the other tests in "mozapps/downloads/tests/chrome".

Before I can produce a patch I need to build the latest trunk, and this still
takes two hours and a half on my machine (let alone that when I update, almost
every time I have to tweak some build option and start from scratch; today I
had to switch to pymake).

The fact is I'm not sure I can find more time for Mozilla in the next few days.
If you don't need a new build right now, please be patient and I'll probably
be able to do a tryserver build, including all the recent UX changes, around
this Thursday.
Thanks for the reply. I do not mean to rush you.

I added preference switching to test_destinationURI_annotation.xul and pushed the updated patches to the UX branch.

Here are the changesets:
Bug 564934 - https://hg.mozilla.org/projects/ux/rev/251d73160c1c
Bug 663772 - https://hg.mozilla.org/projects/ux/rev/678c2cd357c9
Bug 685357 - https://hg.mozilla.org/projects/ux/rev/748aa4367791
For the raw diffs, click the "raw" links at the top of each page.

Thanks again for the work you've already done, Paolo. :)
Depends on: 708566
A new tryserver build is now available here:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo%2Emozmail%40amadzone%2Eorg-e7e33f221e9c

Compared to the version in the UX branch, we made several improvements to visual
design and interaction. At present, we're looking for more feedback specifically
related to these front-end aspects, while code and accessibility reviews are
postponed to a later phase while we iterate over the main interaction.

Some issues we're already aware of include:
* Files can't be opened from the Library window using double-clicks (bug 675902).
* Some progress text is still cropped and the panel is too high (bug 697687).
* The indicator is placed on the tab bar. For now, it should be moved to the
   navigation bar manually (bug 697680).
* Some about:config preferences might affect whether the notification of a
   new download appears at all (bug 697678).

For details about the current state of the feature, and what we changed exactly,
you can refer to the currently associated bugs: bug 564934, bug 663772,
bug 685357, bug 708566, bug 697686, bug 697688, bug 697679, and bug 697683.
The wiki pages will be updated when we're comfortable with the feature state.

The improvements will also make their way to the UX branch shortly.

Enjoy!
Sorry for bumping but will this make it to Firefox 12?
(In reply to bogas04 from comment #392)
> Sorry for bumping but will this make it to Firefox 12?

Probably not; cut-off date is end of this month. Looks like momentum stopped on this.
Using UX builds , it seems alright to me , few fixes and it can make way for aurora it seems? If anything goes drastically wrong it can be removed just like tab animations went..? Apologies , for anything which makes this invalid comment.
Comment on attachment 574268 [details] [diff] [review]
First version for user experience feedback (updated)

The current plan is to have a first draft of the feature available in Nightly
in less than a month, while still keeping it disabled in Aurora, meaning it
would be possible to use the feature in Firefox 13 if a specific "about:config"
preference is set.

In the meantime, you can find the latest iteration here:

http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/paolo.mozmail%40amadzone.org-37d2f8c15125/

Starting from today, there is also a brand new process in place for requesting
reviews from the User Experience team, that should give us better turnaround
time and faster progress in the next few weeks.
Attachment #574268 - Flags: ui-review?(ux-review)
Comment on attachment 574268 [details] [diff] [review]
First version for user experience feedback (updated)

Overall, this seems solid enough to land preffed off in Nightly.

Here's the items I found while testing:
* focus ring should not be visible unless you start using the keyboard

* location of the button should be on the toolbar, not on the tab strip (known issue, as mentioned in earlier comments)

* "show download history" should not be blue text, but white (OS X)

* there's no download arrow when a download is in-progress, only a progress bar (Stephen's mockup had a small arrow + the progress indicator under it, I believe?)

* blue glow at the end of a download to indicate completion shouldn't fill in outside the arrow itself

* it doesn't clear the download panel contents when quitting and starting again (it should!) — actually, the second time I restarted, it seemed to work, odd. maybe test more with a blank profile?

* "show download history" when there are no entries makes the panel much too wide, it should be the same width as the text itself = a bit of padding, not wider

* The arrow animate-into-toolbar-icon doesn't seem to trigger the first time either, but works fine on subsequent downloads

* There's no background (blue on OS X) hover effect on the magnifying glass that shows the location of the file

ui-r+ as-is for preffed off, the remaining issues can be adressed in follow-up bugs and/or patches.
Attachment #574268 - Flags: ui-review?(ux-review) → ui-review+
Forgot to mention that the review was done using your tryserver build, on OS X.

And again, thanks for your great work on this! It's really, really good now, and almost perfect. :)
Can the try server build's patches land to UX builds now?
In UX builds as of 1-26-11 and looking great. However:

* Sometimes the icon is semi-covered by aero.
* a pref to always show the icon would be welcome (if there is one, sorry)
* A way to move the download window so its still visible and you can also see page content at the same time would be nice

Aside from clipping, I think it is ready for aurora.

windows 7 x64.
I noticed a few interesting animations in the new download manager in Safari 5.1 on OSX. There is for example an animation when a download is launched (the download button goes from the middle of the screen to the navigation bar) and also another one for the arrow panel (I now that was planned for every panels in Firefox, but this one will normally be more used than the others so an animation would be very appealing).
(In reply to Guillaume C. [:GE3K0S] from comment #400)
> There is for example an animation when a download is launched

We have a similar animation in place already

> and also another one for the arrow panel

We are not yet using Mac native panels, though bug 723061 has been filed about that. When we'll support native panels the animations will come for free.

Thanks for you feedback.
(In reply to Notlost from comment #399)
> * Sometimes the icon is semi-covered by aero.

known issue

> * a pref to always show the icon would be welcome (if there is one, sorry)

probably it will always be shown by default

> * A way to move the download window so its still visible and you can also
> see page content at the same time would be nice

I think we have a bug to implement detachable panels, that would make it. Though it's not something I'd put as a requirement, may be an enhancement bug.
thanks.
> > * a pref to always show the icon would be welcome (if there is one, sorry)
> 
> probably it will always be shown by default

And we again will hide it through userchrome.css?

Don't do that! Make a pref.
(In reply to Marco Bonardo [:mak] from comment #402)
> probably it will always be shown by default

As I've said months ago, this is against the principle of putting only the most important items in the primary UI by default. Most users won't need this one most of the time. This is analogous to the current download manager window that only opens when you need it. For the minority use case of browsing through your download history, menus work just fine as an entry point.
The UX team is surely aware of the problems each of the two approaches may have.
And why not give the user the ability to configure? In the settings you already have "show downloads window". Just transform it in "Hide downloads button when there is no downloads"
Is there any plans about a warning dialog when the user quits Firefox and there is still a download in progress (I know there is already such a dialog when you come back to normal mode from private browsing) ? I think it's important since the download progress won't be in a separate windows anymore and the user could clearly close the browser without noticing there is still downloads in progress.
The download manager backend prompts on shutdown if any downlads are not resumable, or if downloads are not going to be resumed next time the browser starts up. I would expect that logic to keep working with this new manager.
Will you explain it each reactionist, who decides that he has lost downloads?

Much better to give people the ability to configure new element, than to listen to endless complaints, like "firefox has become even worse"
I only really trust servers to properly report resumability to the extent that it's useful for crash recovery.

I'd much prefer an "are you sure?" dialog if I try to quit while downloads are in progress. That's how I've got the Download Statusbar extension set up now and, that aside, I'm looking forward to being able to replace that extension with a superior option with a more compact UI, less chance of memory leaks, and no tacky on-upgrade message tabs with donation buttons in them.
Attached patch Last update (obsolete) — Splinter Review
This is the same patch as before, updated to fix the global variable leaks in tests (as detected by bug 720985) and to close the database connection in the
Download Manager back-end properly, since we call asynchronous statements on it.
Attachment #574268 - Attachment is obsolete: true
Depends on: 726444
From a first look at what landed on UX (Bug 726444):
a. The popup filling the entire screen doesn't look good. At times, this causes the connecting arrow of the doorhanger to go missing. The list should be tall enough to show just 4-5 items, the remaining would be accessible by scrolling down.
b. Why are the list items so tall?
(In reply to Siddhartha Dugar (sdrocking) from comment #412)
> From a first look at what landed on UX (Bug 726444):
> a. The popup filling the entire screen doesn't look good. At times, this
> causes the connecting arrow of the doorhanger to go missing. The list should
> be tall enough to show just 4-5 items, the remaining would be accessible by
> scrolling down.
> b. Why are the list items so tall?

I think it is supposed to change , maybe in accordance to these mockups https://wiki.mozilla.org/Arrow_Panel_Redesign
On dark personas the download button becomes white instead of black on the nav-bar even in large icon mode. Is this by design as it did not happen with the previous button. (This may be related to Bug 671553.)
The "Download Complete" notification should now be shown less often.
(In reply to Siddhartha Dugar (sdrocking) from comment #415)
> The "Download Complete" notification should now be shown less often.

Repetition or Duration? Because as to my knowledge, Firefox informs users (via popup) once after their downloads are complete which is a vital component used to notify users about their download status when Firefox is not/in focus unless a new approach is designed. Why don't you submit a patch or give us more details so the interested ones would do the same? 

If you're talking about duration or want to mess around the intervals the popup is shown, then copy paste,enter "about:config" without quotes onto the location bar and paste "download" on to the filter box. You'll see a bunch of integers, strings and Boolean's pertaining download manager.








PS: I'm no developer, Just provide support as a volunteer :)
(In reply to Rakshith from comment #416)
> (In reply to Siddhartha Dugar (sdrocking) from comment #415)
> > The "Download Complete" notification should now be shown less often.
> 
> Repetition or Duration?

I obviously meant repetition. Sorry for not explaining it.

The new arrow turns green when a download finishes. So if Firefox is the active window, the user already knows if it has happened.
(In reply to Siddhartha Dugar (sdrocking) from comment #417)

> The new arrow turns green when a download finishes. So if Firefox is the
> active window, the user already knows if it has happened.

If and only they notice it. A mere static transition-less color change on the top right corner of the screen (worse if screen is larger) IMO is not an efficient method to draw attention to it hence the outdated popup which unsurprisingly seems to do the job given its shabby design/animation. So if "Download Complete" notification is to be shown less as you proposed in this regard, amends need to be made to the indicator or any other form of approach to be visually attractive which could further (based on the popup's productivity) aid eliminating the popup  when obsolete. Of course this is just my opinion unless others agree :)
I don't know if this has already been mentioned, but the "download complete" box (that appears on the bottom right) should go away. It's redundant with the download button.
(In reply to Guillaume C. [:GE3K0S] from comment #419)
> I don't know if this has already been mentioned, but the "download complete"
> box (that appears on the bottom right) should go away. It's redundant with
> the download button.

I agree. It also takes the users attention to the bottom whereas the attention needed is on the top.
(In reply to Greg Karz from comment #420)
> (In reply to Guillaume C. [:GE3K0S] from comment #419)
> > I don't know if this has already been mentioned, but the "download complete"
> > box (that appears on the bottom right) should go away. It's redundant with
> > the download button.
> 
> I agree. It also takes the users attention to the bottom whereas the
> attention needed is on the top.

That is bug 588314
Can somebody send the latest tryserver build for this? The UX build seems to have it disabled...
Sorry, just saw the other bug about this.
Moving cursor on downloads popup window makes texts visible for a finished download, not working for "downloading" files.
http://img804.imageshack.us/img804/307/adszofx.png
http://img607.imageshack.us/img607/333/adsz2aq.png

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20120323 Firefox/14.0a1 ID:20120323040238
(In reply to omeringen from comment #424)
> Moving cursor on downloads popup window makes texts visible for a finished
> download, not working for "downloading" files.
> http://img804.imageshack.us/img804/307/adszofx.png
> http://img607.imageshack.us/img607/333/adsz2aq.png
> 
> Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20120323 Firefox/14.0a1
> ID:20120323040238

I confirm it
Depends on: 746591
Depends on: 746658
Depends on: 746674
Depends on: 746751
Blocks: 746772
No longer blocks: 746772
Depends on: 746772
Depends on: 746775
Depends on: 746779
Depends on: 746780
Depends on: 746783
Depends on: 746787
Depends on: 746853
Is the downloads panel meant to be empty when selecting "Downloads" from the menu in a new session?
(In reply to Daniel Cater from comment #426)
> Is the downloads panel meant to be empty when selecting "Downloads" from the
> menu in a new session?

"Downloads" should just open the library, not have any effect on the button/panel, if it does please file a bug.
(In reply to Marco Bonardo [:mak] from comment #427)
> (In reply to Daniel Cater from comment #426)
> > Is the downloads panel meant to be empty when selecting "Downloads" from the
> > menu in a new session?
> 
> "Downloads" should just open the library, not have any effect on the
> button/panel, if it does please file a bug.

Yes, selecting "Tools -> Downloads" opens up an empty panel in a clean profile. Does it not for you?

To rephrase my question (as the opening of the panel wasn't what I was concerned about): is the downloads panel meant to be empty in a new session (if the previous session had downloads in it)?
(In reply to Daniel Cater from comment #428)
> Yes, selecting "Tools -> Downloads" opens up an empty panel in a clean
> profile. Does it not for you?

yes, bug please.

> To rephrase my question (as the opening of the panel wasn't what I was
> concerned about): is the downloads panel meant to be empty in a new session
> (if the previous session had downloads in it)?

It depends on the status of the downloads, completed downloads are expected to be removed on browser closed, ongoing or paused ones are not.
Hello! I'm collecting all the feedback received so far, and will post a more
detailed feature status update later, including answers to some common questions
I've seen asked throughout the development of the feature.

Meanwhile, with regard to the "Tools -> Downloads" menu item opening the panel
instead of the Library window, well, the behavior is still to be defined. On one
hand, it looks weird to open the panel when it's empty, on the other hand we need
an accessible and discoverable of opening the panel using the keyboard only. As
Marco suggested, feel free to file a specific bug to discuss the issue.
(In reply to Marco Bonardo [:mak] from comment #429)
> (In reply to Daniel Cater from comment #428)
> > To rephrase my question (as the opening of the panel wasn't what I was
> > concerned about): is the downloads panel meant to be empty in a new session
> > (if the previous session had downloads in it)?
> 
> It depends on the status of the downloads, completed downloads are expected
> to be removed on browser closed, ongoing or paused ones are not.

OK, well in that case the new download manager has introduced a regression.

There is now no way to "Go to Download Page" or "Open Containing Folder" on downloads completed in a previous session.

This could be fixed by:

a) adding these items back to download item context menu and showing all downloads in the panel, or
b) adding these items to the Downloads section in the library (bug 675902).

a) seems to be by design, so I'm guessing WONTFIX. b) is unassigned.

I suggest that this bug be backed out until that bug is fixed (it was a dependency before this bug was fixed) because it is effectively dataloss (information that you could access prior to this bug landing now cannot be accessed).

In the meantime, how can I get at this information using SQLite Manager?
(In reply to Daniel Cater from comment #431)
> There is now no way to "Go to Download Page" or "Open Containing Folder" on
> downloads completed in a previous session.

Will be added to the Library, as you said, don't have an ETA but should happen soon enough, at least as a context menu option.

> I suggest that this bug be backed out until that bug is fixed (it was a
> dependency before this bug was fixed) because it is effectively dataloss

By using Nightly you accept to use experimental/unfinished features, that may even cause dataloss or missing functionality.  Aurora is safer, if you are not comfortable with this kind of testing.
(In reply to Daniel Cater from comment #431)
> b) is unassigned.

Patches welcome! :-)  (I'll do it later, if no one beats me to it)

> In the meantime, how can I get at this information using SQLite Manager?

Getting at the download's target in SQLite Manager is a bit tricky, as it's an
"annotation" and requires joining three tables. To see the actual paths only, you
can open "places.sqlite" and look in the "moz_annos" table.
(In reply to Paolo Amadini [:paolo] from comment #433)
> (In reply to Daniel Cater from comment #431)
> > b) is unassigned.
> 
> Patches welcome! :-)  (I'll do it later, if no one beats me to it)
> 
> > In the meantime, how can I get at this information using SQLite Manager?
> 
> Getting at the download's target in SQLite Manager is a bit tricky, as it's
> an
> "annotation" and requires joining three tables. To see the actual paths
> only, you
> can open "places.sqlite" and look in the "moz_annos" table.

What about for "Download Page"?
Note: Whiteboard tags and keywords migrated to the appropriate implementation bugs.
Keywords: access, addon-compatmeta
Whiteboard: [strings][needs accessibility qa]
There is a new feature status page detailing some of the known issues:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager/Status

Note that I'm listing only the most noticeable issues there, while all the other
known issues are in bugs blocking this one. There is a query linked from the
page to see the list of all those bugs.
Whiteboard: [=== See the STATUS PAGE before posting - linked in the bug's URL field ===]
Attachment #461386 - Attachment is obsolete: true
Attachment #596492 - Attachment is obsolete: true
(In reply to Daniel Cater from comment #434)
> What about for "Download Page"?

The "download page" is the most recent referrer of the download. To find it
manually, you should identify the item corresponding to the download in
"moz_places", look for the most recent row (visit) in "moz_historyvisits"
pointing to that "place_id", find another row in the same table referenced by
the "from_visit" field of the original row, and then get back at the "place_id"
pointed to by that visit in "moz_places" again.

Or use the Places API :-)
Depends on: 726450
Depends on: 726451
Depends on: 726453
Depends on: 726454
Depends on: 726456
Depends on: 732924
Depends on: 726445
Depends on: 726447
Depends on: 746766
Depends on: 747310
Depends on: 747903
Alias: DownloadsPanel
Depends on: 748381
Depends on: 749323
Depends on: 750072
not going to lie i think its ****, a lot of the words get cutoff and its not very responsive to me hovering over for the rest of the info, the "go do download location" is no longer an option which bothers me as i used it a lot. i personally feel that the "show all downloads" should return to the normal window, or at the very least this be a default but ALWAYS optional feature
(In reply to Taylor Cheetham from comment #438)
> not going to lie i think its ****, a lot of the words get cutoff and its not
> very responsive to me hovering over for the rest of the info, the "go do
> download location" is no longer an option which bothers me as i used it a
> lot. i personally feel that the "show all downloads" should return to the
> normal window, or at the very least this be a default but ALWAYS optional
> feature

Type "  about:config  " in the Firefox location bar hit enter and paste this "  browser.download.useToolkitUI  " in the filter box, toggle it to true and you have the old download manager back.
oh i already knew about that, im just saying the average user not only doesn't know what about:config is but would most likely break firefox by trying to use it. So this should be the default assuming its implemented however it should be optional and easy to change in the options area of firefox. honestly just make a few changes like letting it be a bit wider to make room for the information and return the "open containing folder" to the right click and there would be (imo) nothing wrong with it. 

Perhaps make it resizable? so that we can manually choose how wide it goes?
I'm assuming aurora besides nightlies have this on by default for now as they are  testing versions and that's how they get feedback but it is important to be noted that the panel will mostly not be implemented in the final unless it is completed or unless people get out of their Metathesiophobia (fear of change) shell and would like to try new things out for a change. Our devs aren't that delusional to put in a broken feature as default in the final release and also it is important to note that 'One does not simply underestimate a Mozilla dev' :P
@441:

Actually, the first version released in the Aurora channel had it but, now, even with the about:config key set, the second version is using the old download manager. (Could just be the Mozilla Ubuntu PPA's version though)

It really annoys me because I'd found it reliable enough and polished enough that I'd already removed the Download Statusbar extension.
Im happy to say i am not a victim of Metathesiophobia, (what with me having jumped head first into win8 and loving metro just btw) but i like to know how fast a download is going, its full name, and site its coming from and ofc the ability to have it drag me right into the content folder. Sometimes with longer things this would get cut off, i agree it was nice. I actually even tho i only had it a few days find myself mistakenly moving my mouse to get at the downloads tab thinggy. So just fix the whole things getting cut off issue and i will be happy as pie and use it forever.
(In reply to Rakshith from comment #441)
> I'm assuming aurora besides nightlies have this on by default for now as

Aurora won't get the feature until we are happy about it in Nightly.
(In reply to Marco Bonardo [:mak] from comment #444)
> (In reply to Rakshith from comment #441)
> > I'm assuming aurora besides nightlies have this on by default for now as
> 
> Aurora won't get the feature until we are happy about it in Nightly.

It's already in Aurora, masked by the browser.download.useToolkitUI key.
The progress meters in the new UI aren't accessible. In the old download manager, NVDA used to regularly beep in an ascending tone as the download progressed. In the new UI, there seems to be such a visual indicator within the panel, but it's not accessible. how is this marked up?
(In reply to Marco Zehe (:MarcoZ) from comment #446)
> The progress meters in the new UI aren't accessible.

Hi, we will need a whole accessibility review before releasing the feature, it would be better if that is tracked in a new a11y related bug, blocking bug 747422.
The structure of the panel contents is about to change, so I think it's better to wait until the new one, before discussing technical details.
Though, probably the fact the old dm had its own window and was able to notify continuously is something we currently lack, likely we need more notifications if a11y is enabled.
(In reply to Marco Bonardo [:mak] from comment #447)
> The structure of the panel contents is about to change, so I think it's
> better to wait until the new one, 

Is there any mockups about the new panel content ?
Found it, sorry : http://cl.ly/442a3U0d1M1B1b411o12/o

The button is weird with the progress bar, the arrow and the remaining time.
Depends on: 751947
This design seems to frequently use the word "session" without ever defining what that session is, how it's managed, or what its significance is. From experience it looks like the lifetime of session is simply tied to a technical detail of how firefox process is started and stopped.

This is quite terrible imho. Firefox's UI does not have a concept of session at all. Colloquially there exists "session restore" which is about restoring windows and tabs on fresh start, but surprisingly(?), restoring a session this way does not actually restore your download panel, even though design docs call for it to be part of a session.

Many dependant bugs here can be summarised as "lifetime of a process is not related to my downloads workflow". Some people keep FF open for weeks, others (like me) frequently close and open windows without any regard to whether other windows are open.

This is terribly confusing. Can I please suggest, if you don't mind, that the lifetime of downloads button/doorhanger is completely redesigned in such a way that technical details of how OS manages processes is not involved in any way.

Thanks for reading.
(In reply to Radek 'sysKin' Czyz from comment #450)
> the lifetime of downloads button/doorhanger is completely redesigned in such
> a way that technical details of how OS manages processes is not involved in
> any way.

That's a good suggestion, and we're working on it as far as possible.

Thanks for asking.
Please update status-firefox15 to disabled if we end up disabling for 15.
(In reply to Alex Keybl [:akeybl] from comment #452)
> Please update status-firefox15 to disabled if we end up disabling for 15.

I was waiting to actually do the disabling before marking it as disabled, for sanity.
Depends on: 760623
Depends on: 760734
Depends on: 765999
Depends on: 766654
Depends on: 767322
Depends on: 765561
Depends on: 772259
Depends on: 773267
Depends on: 773273
Depends on: 776866
Depends on: 776870
Depends on: 782662
Depends on: 782664
Depends on: 784629
Depends on: 785054
-----------------------------------------------------
 The design of the Downloads Panel has been updated!
-----------------------------------------------------

The new version of the Downloads Panel should be available for testing in the
Nightly channel shortly. The status page now describes the latest changes:

https://wiki.mozilla.org/User:P.A./Panel-based_Download_Manager/Status

IMPORTANT: If you previously tested one of the temporary tryserver builds of the
Downloads Panel, and customized the navigation bar, you might need to reset the
toolbars in order to see the Downloads button in its default position.

Some highlights from the recent changes:
* If the Downloads button is invisible, the Downloads Panel is also disabled.
* The Downloads button is always visible in the navigation bar by default.
* The panel only displays a limited number of recent downloads.
* The old Downloads window temporarily replaces the new Library window view.

Feedback on the new design and on any new issues is welcome! Be sure to read
the status page first, as the issues may have already been reported.

For reference, the patches and detailed discussion corresponding to the recent
changes are available in bug 760607, bug 748381, bug 747903, and bug 748160.
Depends on: 785702
Depends on: 785703
Depends on: 785787
No longer depends on: 785787
Depends on: 786150
Depends on: 786662
Depends on: 788492
Depends on: 789912
Depends on: 794610
Blocks: fxPBnGen
No longer blocks: PBnGen
No longer blocks: fxPBnGen
Depends on: 794752
Depends on: 800219
Depends on: 800424
No longer depends on: 795806
Sorry if posted on the wrong place but not sure about the right place

The new Download panel has loads of free chrome above & below the progress bar
why can't we use the space to provide more detail's like Speed?(which was recently removed but is very useful)
or more options like auto-clear check box or url -info?

Also there is no compact mode(if user want's to see more download in less space) mode in default large icons or using small icons
Depends on: 812487
This may be the right place to suggest changes, for now. The only drawback it's sending mail to many persons (but who is not interested can un-cc too).

The fact is the panel is a notification, with some info on recent downloads, it's not intended to be a downloads manager. Thus the information it contains is kept to a minimum clutter.
Auto-clear doesn't appear to be extremely useful since this info is volatile (per session) and only 3 downloads are shown so far.
For speed we are evaluating to put somewhere a global indicator, though we are brainstorming how and where.
Not sure about a compact mode, we'll evaluate, though we prefer going with a default mode that works for most people for now.
No longer depends on: 812487
Depends on: 824265
Since we have a dedicated Downloads Panel component, removing some of the dependencies that don't need specific tracking here.
No longer depends on: 747018
No longer depends on: 747506
No longer depends on: 749323
No longer depends on: 760623
No longer depends on: 776866
No longer depends on: 785054
No longer depends on: 788492
No longer depends on: 747310
No longer depends on: 617128
No longer depends on: 492960
No longer depends on: 597155
All of the remaining open bugs are now tracked directly into a Firefox / Downloads component bug. Any new issue should be filed there.

This meta bug will stay open until the feature appears in an official release version, just for tracking purpose.
No longer depends on: 726445, 726447, 726450, 726451, 726453, 726456, 732924, 773273, 782664
I'd say it's implemented now, congrats!
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → WORKSFORME
Depends on: 844341
Depends on: 844541
Depends on: 844545
Depends on: 844546
Depends on: 844548
No longer blocks: 341057
Depends on: 874324
Component: General → Downloads Panel
Depends on: 958737
Depends on: 1115964
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: