Bug 1638156 - Make open downloaded file the default action in about:newtab download cards, and add key modifiers support. r=Mardak

Differential Revision: https://phabricator.services.mozilla.com/D76575
This commit is contained in:
Sam Foster 2020-05-28 01:11:48 +00:00
Родитель 5d4187bff2
Коммит d39d9cbb00
8 изменённых файлов: 73 добавлений и 28 удалений

Просмотреть файл

@ -138,15 +138,17 @@ export class _Card extends React.PureComponent {
onLinkClick(event) {
event.preventDefault();
const { altKey, button, ctrlKey, metaKey, shiftKey } = event;
if (this.props.link.type === "download") {
this.props.dispatch(
ac.OnlyToMain({
type: at.SHOW_DOWNLOAD_FILE,
data: this.props.link,
type: at.OPEN_DOWNLOAD_FILE,
data: Object.assign(this.props.link, {
event: { button, ctrlKey, metaKey, shiftKey },
}),
})
);
} else {
const { altKey, button, ctrlKey, metaKey, shiftKey } = event;
this.props.dispatch(
ac.OnlyToMain({
type: at.OPEN_LINK,
@ -274,7 +276,7 @@ export class _Card extends React.PureComponent {
{link.type === "download" && (
<div
className="card-host-name alternate"
data-l10n-id="newtab-menu-show-file"
data-l10n-id="newtab-menu-open-file"
/>
)}
{link.hostname && (

Просмотреть файл

@ -80,9 +80,9 @@ export class ContextMenuItem extends React.PureComponent {
this.focusFirst = this.focusFirst.bind(this);
}
onClick() {
onClick(event) {
this.props.hideContext();
this.props.option.onClick();
this.props.option.onClick(event);
}
// Focus the first menu item if the menu was accessed via the keyboard.

Просмотреть файл

@ -50,7 +50,17 @@ export class _LinkMenu extends React.PureComponent {
.map(option => {
const { action, impression, id, type, userEvent } = option;
if (!type && id) {
option.onClick = () => {
option.onClick = (event = {}) => {
const { ctrlKey, metaKey, shiftKey, button } = event;
// Only send along event info if there's something non-default to send
if (ctrlKey || metaKey || shiftKey || button) {
action.data = Object.assign(
{
event: { ctrlKey, metaKey, shiftKey, button },
},
action.data
);
}
props.dispatch(action);
if (userEvent) {
const userEventData = Object.assign(

Просмотреть файл

@ -5256,7 +5256,25 @@ class _LinkMenu extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureCompone
} = option;
if (!type && id) {
option.onClick = () => {
option.onClick = (event = {}) => {
const {
ctrlKey,
metaKey,
shiftKey,
button
} = event; // Only send along event info if there's something non-default to send
if (ctrlKey || metaKey || shiftKey || button) {
action.data = Object.assign({
event: {
ctrlKey,
metaKey,
shiftKey,
button
}
}, action.data);
}
props.dispatch(action);
if (userEvent) {
@ -5385,9 +5403,9 @@ class ContextMenuItem extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureC
this.focusFirst = this.focusFirst.bind(this);
}
onClick() {
onClick(event) {
this.props.hideContext();
this.props.option.onClick();
this.props.option.onClick(event);
} // Focus the first menu item if the menu was accessed via the keyboard.
@ -8737,20 +8755,27 @@ class _Card extends react__WEBPACK_IMPORTED_MODULE_5___default.a.PureComponent {
onLinkClick(event) {
event.preventDefault();
const {
altKey,
button,
ctrlKey,
metaKey,
shiftKey
} = event;
if (this.props.link.type === "download") {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].SHOW_DOWNLOAD_FILE,
data: this.props.link
type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].OPEN_DOWNLOAD_FILE,
data: Object.assign(this.props.link, {
event: {
button,
ctrlKey,
metaKey,
shiftKey
}
})
}));
} else {
const {
altKey,
button,
ctrlKey,
metaKey,
shiftKey
} = event;
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].OPEN_LINK,
data: Object.assign(this.props.link, {
@ -8866,7 +8891,7 @@ class _Card extends react__WEBPACK_IMPORTED_MODULE_5___default.a.PureComponent {
className: "card-details"
}, link.type === "download" && react__WEBPACK_IMPORTED_MODULE_5___default.a.createElement("div", {
className: "card-host-name alternate",
"data-l10n-id": "newtab-menu-show-file"
"data-l10n-id": "newtab-menu-open-file"
}), link.hostname && react__WEBPACK_IMPORTED_MODULE_5___default.a.createElement("div", {
className: "card-host-name"
}, link.hostname.slice(0, 100), link.type === "download" && ` \u2014 ${link.description}`), react__WEBPACK_IMPORTED_MODULE_5___default.a.createElement("div", {

Просмотреть файл

@ -172,8 +172,14 @@ this.DownloadsManager = class DownloadsManager {
});
break;
case at.OPEN_DOWNLOAD_FILE:
const win = action._target.browser.ownerGlobal;
const openWhere = action.data.event
? win.whereToOpenLink(action.data.event)
: "current";
doDownloadAction(download => {
DownloadsCommon.openDownload(download);
DownloadsCommon.openDownload(download, {
openWhere,
});
});
break;
case at.UNINIT:

Просмотреть файл

@ -167,7 +167,7 @@ describe("<Card>", () => {
"has active class"
);
});
it("should send SHOW_DOWNLOAD_FILE if we clicked on a download", () => {
it("should send OPEN_DOWNLOAD_FILE if we clicked on a download", () => {
const downloadLink = {
type: "download",
url: "download.mov",
@ -181,7 +181,7 @@ describe("<Card>", () => {
assert.equal(
DEFAULT_PROPS.dispatch.firstCall.args[0].type,
at.SHOW_DOWNLOAD_FILE
at.OPEN_DOWNLOAD_FILE
);
assert.deepEqual(
DEFAULT_PROPS.dispatch.firstCall.args[0].data,

Просмотреть файл

@ -302,6 +302,7 @@ describe("<LinkMenu>", () => {
assert.equal(option.action.data.index, index);
});
describe(".onClick", () => {
const FAKE_EVENT = {};
const FAKE_INDEX = 3;
const FAKE_SOURCE = "TOP_SITES";
const FAKE_SITE = {
@ -400,7 +401,7 @@ describe("<LinkMenu>", () => {
.filter(o => o.type !== "separator")
.forEach(option => {
it(`should fire a ${option.action.type} action for ${option.id} with the expected data`, () => {
option.onClick();
option.onClick(FAKE_EVENT);
if (option.impression && option.userEvent) {
assert.calledThrice(dispatch);
@ -439,7 +440,7 @@ describe("<LinkMenu>", () => {
});
it(`should fire a UserEvent action for ${option.id} if configured`, () => {
if (option.userEvent) {
option.onClick();
option.onClick(FAKE_EVENT);
const [action] = dispatch.secondCall.args;
assert.isUserEventAction(action);
assert.propertyVal(action.data, "source", FAKE_SOURCE);
@ -449,7 +450,7 @@ describe("<LinkMenu>", () => {
});
it(`should send impression stats for ${option.id}`, () => {
if (option.impression) {
option.onClick();
option.onClick(FAKE_EVENT);
const [action] = dispatch.thirdCall.args;
assert.deepEqual(action, option.impression);
}
@ -473,7 +474,7 @@ describe("<LinkMenu>", () => {
.filter(o => o.type !== "separator")
.forEach(option => {
if (option.impression) {
option.onClick();
option.onClick(FAKE_EVENT);
assert.calledTwice(dispatch);
assert.notEqual(dispatch.firstCall.args[0], option.impression);
assert.notEqual(dispatch.secondCall.args[0], option.impression);
@ -500,7 +501,7 @@ describe("<LinkMenu>", () => {
.props();
const [pinSpocOption] = spocOptions;
pinSpocOption.onClick();
pinSpocOption.onClick(FAKE_EVENT);
if (pinSpocOption.impression && pinSpocOption.userEvent) {
assert.calledThrice(dispatch);

Просмотреть файл

@ -78,6 +78,7 @@ describe("Downloads Manager", () => {
downloadsManager.onAction({
type: at.OPEN_DOWNLOAD_FILE,
data: { url: DOWNLOAD_URL, type: "download" },
_target: { browser: {} },
});
assert.calledOnce(global.DownloadsCommon.openDownload);
});