1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
import { actionCreators as ac } from "common/Actions.sys.mjs";
import { connect } from "react-redux";
import { ContextMenu } from "content-src/components/ContextMenu/ContextMenu";
import { LinkMenuOptions } from "content-src/lib/link-menu-options";
import React from "react";
const DEFAULT_SITE_MENU_OPTIONS = [
"CheckPinTopSite",
"EditTopSite",
"Separator",
"OpenInNewWindow",
"OpenInPrivateWindow",
"Separator",
"BlockUrl",
];
export class _LinkMenu extends React.PureComponent {
getOptions() {
const { props } = this;
const {
site,
index,
source,
isPrivateBrowsingEnabled,
siteInfo,
platform,
userEvent = ac.UserEvent,
} = props;
// Handle special case of default site
const propOptions =
site.isDefault && !site.searchTopSite && !site.sponsored_position
? DEFAULT_SITE_MENU_OPTIONS
: props.options;
const options = propOptions
.map(o =>
LinkMenuOptions[o](
site,
index,
source,
isPrivateBrowsingEnabled,
siteInfo,
platform
)
)
.map(option => {
const { action, impression, id, type, userEvent: eventName } = option;
if (!type && id) {
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 === 1) {
action.data = Object.assign(
{
event: { ctrlKey, metaKey, shiftKey, button },
},
action.data
);
}
props.dispatch(action);
if (eventName) {
const userEventData = Object.assign(
{
event: eventName,
source,
action_position: index,
value: { card_type: site.flight_id ? "spoc" : "organic" },
},
siteInfo
);
props.dispatch(userEvent(userEventData));
}
if (impression && props.shouldSendImpressionStats) {
props.dispatch(impression);
}
};
}
return option;
});
// This is for accessibility to support making each item tabbable.
// We want to know which item is the first and which item
// is the last, so we can close the context menu accordingly.
options[0].first = true;
options[options.length - 1].last = true;
return options;
}
render() {
return (
<ContextMenu
onUpdate={this.props.onUpdate}
onShow={this.props.onShow}
options={this.getOptions()}
keyboardAccess={this.props.keyboardAccess}
/>
);
}
}
const getState = state => ({
isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled,
platform: state.Prefs.values.platform,
});
export const LinkMenu = connect(getState)(_LinkMenu);
|