- Electron version: 1.3.5
- Operating system: macOS/Windows

Alt-clicking a link is a default shortcut for downloading a file without a save prompt, and we make use of it in our app. But for links that end in a trailing slash, the resulting filename isn't consistent with the default file name in the save prompt.

The save prompt constructs a name from the word "download" and the extension for the mime type of the file, but the prompt-less savepath is just the domain name of the link. This leads to unusable files (e.g. with a .com file extension) being saved to the filesystem.

Here's my current workaround, but given the prompt does get a useful path, and Chrome behaves correctly, I imagine this might be straightforward to fix if you know where to look:

``` javascript
const mime = require('mime-types');
const _ = require('lodash');
const path = require('path');
const unusedFilename = require('unused-filename');

win.webContents.session.on('will-download', function (e, item, webContents) {
  if (item.getSavePath() && _.last(item.getURL()) === '/') {
      var savePath = unusedFilename.sync(path.format({
        dir: path.dirname(item.getSavePath()),
        name: 'download',
        ext: '.' + mime.extension(item.getMimeType())
      }));
      item.setSavePath(savePath);
    }
});
```

atom/browser/api/atom_api_web_contents.cc
.SetMethod("enableDeviceEmulation",
                 &WebContents::EnableDeviceEmulation)
      .SetMethod("disableDeviceEmulation",
                 &WebContents::DisableDeviceEmulation)
      .SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
      .SetMethod("inspectElement", &WebContents::InspectElement)
      .SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
      .SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
      .SetMethod("undo", &WebContents::Undo)
      .SetMethod("redo", &WebContents::Redo)
      .SetMethod("cut", &WebContents::Cut)
      .SetMethod("copy", &WebContents::Copy)
      .SetMethod("paste", &WebContents::Paste)
      .SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
      .SetMethod("delete", &WebContents::Delete)
      .SetMethod("selectAll", &WebContents::SelectAll)
      .SetMethod("unselect", &WebContents::Unselect)
      .SetMethod("replace", &WebContents::Replace)
      .SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
      .SetMethod("findInPage", &WebContents::FindInPage)
      .SetMethod("stopFindInPage", &WebContents::StopFindInPage)
      .SetMethod("focus", &WebContents::Focus)
      .SetMethod("isFocused", &WebContents::IsFocused)
      .SetMethod("tabTraverse", &WebContents::TabTraverse)
      .SetMethod("_send", &WebContents::SendIPCMessage)
      .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
      .SetMethod("beginFrameSubscription",
                 &WebContents::BeginFrameSubscription)
      .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
      .SetMethod("startDrag", &WebContents::StartDrag)