|
@ -93,46 +93,6 @@
|
|||
left: $feed-gutter-h - 2;
|
||||
}
|
||||
|
||||
.action-items-container {
|
||||
background: $bg-grey;
|
||||
border: solid 1px $faintest-black;
|
||||
border-radius: $border-radius;
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
bottom: -5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
border-right: solid 1px $faintest-black;
|
||||
padding: 10px 8px;
|
||||
|
||||
&:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
&.icon-more {
|
||||
background-image: url('img/glyph-more-16.svg');
|
||||
}
|
||||
|
||||
&.icon-delete {
|
||||
background-image: url('img/glyph-delete-16.svg');
|
||||
}
|
||||
|
||||
&.icon-share {
|
||||
background-image: url('img/glyph-share-16.svg');
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background: $feed-hover-color;
|
||||
|
|
|
@ -34,6 +34,7 @@ const ContextMenu = React.createClass({
|
|||
this.props.onUserEvent(option.userEvent);
|
||||
}
|
||||
}}>
|
||||
{option.icon && <span className={"icon icon-spacer icon-" + option.icon} />}
|
||||
{option.label}
|
||||
</a></li>);
|
||||
})}
|
||||
|
@ -49,6 +50,7 @@ ContextMenu.propTypes = {
|
|||
options: React.PropTypes.arrayOf(React.PropTypes.shape({
|
||||
type: React.PropTypes.string,
|
||||
label: React.PropTypes.string,
|
||||
icon: React.PropTypes.string,
|
||||
onClick: React.PropTypes.func,
|
||||
userEvent: React.PropTypes.string,
|
||||
ref: React.PropTypes.string
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
> a {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
padding: $context-menu-item-padding;
|
||||
line-height: 1;
|
||||
line-height: $icon-size;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background: $star-blue;
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
const React = require("react");
|
||||
const {connect} = require("react-redux");
|
||||
const {actions} = require("common/action-manager");
|
||||
const ContextMenu = require("components/ContextMenu/ContextMenu");
|
||||
|
||||
const DeleteMenu = React.createClass({
|
||||
userEvent(event) {
|
||||
if (this.props.page && this.props.source) {
|
||||
let payload = {
|
||||
event,
|
||||
page: this.props.page,
|
||||
source: this.props.source,
|
||||
action_position: this.props.index
|
||||
};
|
||||
|
||||
if (this.props.experimentData.reverseMenuOptions) {
|
||||
payload.experiment_id = this.props.experimentData.id;
|
||||
}
|
||||
this.props.dispatch(actions.NotifyEvent(payload));
|
||||
}
|
||||
},
|
||||
onDeleteHistory() {
|
||||
this.props.dispatch(actions.NotifyHistoryDelete(this.props.url));
|
||||
this.userEvent("DELETE");
|
||||
},
|
||||
onDeleteBookmark() {
|
||||
this.props.dispatch(actions.NotifyBookmarkDelete(this.props.bookmarkGuid));
|
||||
this.userEvent("BOOKMARK_DELETE");
|
||||
},
|
||||
onBlock(url, index) {
|
||||
this.props.dispatch(actions.NotifyBlockURL(this.props.url));
|
||||
this.userEvent("BLOCK");
|
||||
},
|
||||
render() {
|
||||
const menuOptions = [];
|
||||
|
||||
// Add the correct remove option for either a bookmark or a history link
|
||||
if (this.props.bookmarkGuid) {
|
||||
menuOptions.push({label: "Remove from Bookmarks", onClick: this.onDeleteBookmark});
|
||||
} else {
|
||||
menuOptions.push({label: "Remove from History", onClick: this.onDeleteHistory});
|
||||
}
|
||||
|
||||
menuOptions.push({label: "Never show on this page", onClick: this.onBlock});
|
||||
|
||||
if (this.props.experimentData.reverseMenuOptions) {
|
||||
menuOptions.reverse();
|
||||
}
|
||||
|
||||
return (<ContextMenu
|
||||
visible={this.props.visible}
|
||||
onUpdate={this.props.onUpdate}
|
||||
options={menuOptions} />);
|
||||
}
|
||||
});
|
||||
|
||||
DeleteMenu.propTypes = {
|
||||
visible: React.PropTypes.bool,
|
||||
onUpdate: React.PropTypes.func.isRequired,
|
||||
url: React.PropTypes.string.isRequired,
|
||||
|
||||
// For user event tracking
|
||||
page: React.PropTypes.string,
|
||||
source: React.PropTypes.string,
|
||||
index: React.PropTypes.number
|
||||
};
|
||||
|
||||
module.exports = connect(state => {
|
||||
return {experimentData: state.Experiments.data};
|
||||
})(DeleteMenu);
|
|
@ -24,7 +24,7 @@ const Header = React.createClass({
|
|||
|
||||
<section ref="clickElement" className={classNames("nav", {"disabled": props.disabled})} onClick={this.onClick}>
|
||||
<h1>
|
||||
<span hidden={!props.icon} className={`icon ${props.icon}`} />
|
||||
<span hidden={!props.icon} className={`icon icon-spacer icon-${props.icon}`} />
|
||||
<span>{props.title}</span>
|
||||
<span ref="caret" hidden={props.disabled} className="arrow" />
|
||||
</h1>
|
||||
|
|
|
@ -14,31 +14,6 @@
|
|||
h1 {
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
|
||||
span {
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
|
||||
&.timeline {
|
||||
background-image: url('img/list-icon.svg');
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-image: url('img/glyph-showmore-16.svg');
|
||||
background-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
|
|
|
@ -37,12 +37,14 @@ const LinkMenu = React.createClass({
|
|||
allowBlock && {
|
||||
ref: "dismiss",
|
||||
label: "Dismiss",
|
||||
icon: "dismiss",
|
||||
userEvent: "BLOCK",
|
||||
onClick: () => dispatch(actions.NotifyBlockURL(site.url))
|
||||
},
|
||||
{
|
||||
ref: "delete",
|
||||
label: "Delete from History",
|
||||
icon: "delete",
|
||||
userEvent: "DELETE",
|
||||
onClick: () => dispatch(actions.NotifyHistoryDelete(site.url))
|
||||
}
|
||||
|
@ -56,11 +58,13 @@ const LinkMenu = React.createClass({
|
|||
(site.bookmarkGuid ? {
|
||||
ref: "removeBookmark",
|
||||
label: "Remove Bookmark",
|
||||
icon: "bookmark-remove",
|
||||
userEvent: "BOOKMARK_DELETE",
|
||||
onClick: () => dispatch(actions.NotifyBookmarkDelete(site.bookmarkGuid))
|
||||
} : {
|
||||
ref: "addBookmark",
|
||||
label: "Bookmark",
|
||||
icon: "bookmark",
|
||||
userEvent: "BOOKMARK_ADD",
|
||||
onClick: () => dispatch(actions.NotifyBookmarkAdd(site.url))
|
||||
}),
|
||||
|
@ -68,12 +72,14 @@ const LinkMenu = React.createClass({
|
|||
{
|
||||
ref: "openWindow",
|
||||
label: "Open in a New Window",
|
||||
icon: "new-window",
|
||||
userEvent: "OPEN_NEW_WINDOW",
|
||||
onClick: () => dispatch(actions.NotifyOpenWindow({url: site.url}))
|
||||
},
|
||||
{
|
||||
ref: "openPrivate",
|
||||
label: "Open in a Private Window",
|
||||
icon: "new-window-private",
|
||||
userEvent: "OPEN_PRIVATE_WINDOW",
|
||||
onClick: () => dispatch(actions.NotifyOpenWindow({url: site.url, isPrivate: true}))
|
||||
}]
|
||||
|
|
|
@ -66,13 +66,13 @@ const NewTabPage = React.createClass({
|
|||
</section>
|
||||
|
||||
<section className="bottom-links-container">
|
||||
<Link className="bottom-link" to="/timeline"><span className="icon timeline" /> See all activity</Link>
|
||||
<Link className="bottom-link" to="/timeline"><span className="icon icon-spacer icon-activity-stream" /> See all activity</Link>
|
||||
<span className="link-wrapper-right">
|
||||
<a
|
||||
ref="settingsLink"
|
||||
className={classNames("bottom-link expand", {active: this.state.showSettingsMenu})}
|
||||
onClick={() => this.setState({showSettingsMenu: !this.state.showSettingsMenu})} >
|
||||
<span className="icon settings" /> <span className="text">Settings</span>
|
||||
<span className="icon icon-spacer icon-settings" /> <span className="text">Settings</span>
|
||||
</a>
|
||||
<ContextMenu
|
||||
ref="settingsMenu"
|
||||
|
|
|
@ -63,19 +63,7 @@
|
|||
|
||||
.icon {
|
||||
float: left;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
width: 16px;
|
||||
margin-right: 8px;
|
||||
opacity: 0.4;
|
||||
|
||||
&.timeline {
|
||||
background-image: url('img/glyph-activityStream-16.svg');
|
||||
}
|
||||
|
||||
&.settings {
|
||||
background-image: url('img/glyph-settings-16.svg');
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
|
|
|
@ -13,8 +13,8 @@ const TimelinePage = React.createClass({
|
|||
const props = this.props;
|
||||
const pathname = props.location && props.location.pathname;
|
||||
const navItems = [
|
||||
{title: "All", to: "/timeline", active: true, icon: "firefox"},
|
||||
{title: "Bookmarks", to: "/timeline/bookmarks", icon: "star"}
|
||||
{title: "All", to: "/timeline", active: true, icon: "firefox-white"},
|
||||
{title: "Bookmarks", to: "/timeline/bookmarks", icon: "bookmark-white"}
|
||||
];
|
||||
return (<div className="outer-wrapper">
|
||||
<Header
|
||||
|
@ -29,7 +29,7 @@ const TimelinePage = React.createClass({
|
|||
{navItems.map(item => {
|
||||
return (<li key={item.to}>
|
||||
<Link to={item.to} className={classNames({active: item.to === pathname})}>
|
||||
<span className={`icon ${item.icon}`} />
|
||||
<span className={`icon icon-${item.icon}`} />
|
||||
<span className="link-title">{item.title}</span>
|
||||
</Link>
|
||||
</li>);
|
||||
|
|
|
@ -32,20 +32,6 @@ main.timeline {
|
|||
|
||||
.icon {
|
||||
margin-right: 10px;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
display: inline-block;
|
||||
background: transparent no-repeat center center;
|
||||
background-size: 18px;
|
||||
|
||||
&.firefox {
|
||||
background-image: url('img/glyph-firefox-16.svg');
|
||||
}
|
||||
|
||||
&.star {
|
||||
background-image: url('img/glyph-bookmark-16-white.svg');
|
||||
background-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
|
|
|
@ -62,6 +62,8 @@ a {
|
|||
}
|
||||
}
|
||||
|
||||
@import './styles/icons';
|
||||
|
||||
// Components
|
||||
@import './components/Header/Header';
|
||||
@import './components/Base/Base';
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M198.992,18a0.955,0.955,0,0,0-.772.651l-1.984,4.122-4.332.72a0.851,0.851,0,0,0-.53,1.563l3.112,3.262-0.69,4.589c-0.1.69,0.173,1.094,0.658,1.094a1.4,1.4,0,0,0,.635-0.181l3.9-2.075,3.9,2.075a1.4,1.4,0,0,0,.634.181c0.485,0,.761-0.4.659-1.094L203.5,28.317l3.108-3.259a0.853,0.853,0,0,0-.53-1.566l-4.3-.719-2.016-4.122A0.953,0.953,0,0,0,198.992,18h0Z" transform="translate(-191 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 844 B |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M199.008,47.642l0.983,2.01,0.452,0.924,1.015,0.17,2.324,0.389-1.719,1.8-0.676.708,0.145,0.968,0.36,2.4-1.953-1.038-0.938-.5-0.939.5-1.951,1.037,0.36-2.4,0.146-.969-0.676-.709-1.718-1.8,2.349-.39,1.024-.17,0.45-.935,0.962-2M199,44a0.953,0.953,0,0,0-.772.651l-1.984,4.122-4.332.72a0.851,0.851,0,0,0-.53,1.563l3.112,3.262-0.69,4.589c-0.1.69,0.172,1.094,0.658,1.094a1.394,1.394,0,0,0,.634-0.181L199,57.744l3.9,2.075a1.4,1.4,0,0,0,.635.181c0.485,0,.761-0.4.658-1.094l-0.687-4.589,3.108-3.259a0.853,0.853,0,0,0-.53-1.566l-4.3-.72-2.016-4.122A0.953,0.953,0,0,0,199,44h0Z" transform="translate(-191 -44)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.0 KiB |
|
@ -1,14 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
line {
|
||||
stroke: #4d4d4d;
|
||||
stroke-width: 2px;
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
|
||||
<g>
|
||||
<line x1="2" y1="2" x2="14" y2="14"/>
|
||||
<line x1="14" y1="2" x2="2" y2="14"/>
|
||||
</g>
|
||||
</svg>
|
||||
<path d="M426,22H416a1,1,0,0,1,0-2h3a1,1,0,0,1,1-1h2a1,1,0,0,1,1,1h3A1,1,0,0,1,426,22Zm-0.9,10a1.132,1.132,0,0,1-1.1,1H418a1.125,1.125,0,0,1-1.1-1L416,23h10Z" transform="translate(-413 -18)"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 358 B После Ширина: | Высота: | Размер: 647 B |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M422.414,52l3.531-3.531a1,1,0,1,0-1.414-1.414L421,50.586l-3.531-3.531a1,1,0,1,0-1.414,1.414L419.586,52l-3.531,3.531a1,1,0,1,0,1.414,1.414L421,53.414l3.531,3.531a1,1,0,1,0,1.414-1.414Z" transform="translate(-413 -44)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 682 B |
До Ширина: | Высота: | Размер: 3.3 KiB После Ширина: | Высота: | Размер: 3.3 KiB |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M382,20.007A1,1,0,0,1,383,19h14a1,1,0,0,1,1,1.007V31.993A1,1,0,0,1,397,33H383a1,1,0,0,1-1-1.007V20.007ZM384,23h12v8H384V23Zm0.5-3a0.5,0.5,0,1,1-.5.5A0.5,0.5,0,0,1,384.5,20Zm2,0a0.5,0.5,0,1,1-.5.5A0.5,0.5,0,0,1,386.5,20Zm2,0a0.5,0.5,0,1,1-.5.5A0.5,0.5,0,0,1,388.5,20Z" transform="translate(-382 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 765 B |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M356.994,24.619c-1.954.47-1.714,1.625-1.714,1.625s2.264,0.849,3.368.258a8.76,8.76,0,0,0,1.167-.668s-1.493-1.534-2.821-1.215m-5.987,0c-1.328-.32-2.821,1.215-2.821,1.215a8.76,8.76,0,0,0,1.167.668c1.1,0.591,3.368-.258,3.368-0.258s0.24-1.155-1.714-1.625M362,24.667c0,2.006-.647,5.334-3.755,5.333-1.143,0-3.1-1.993-4.245-1.993S350.9,30,349.755,30C346.647,30,346,26.673,346,24.667c0-2.094.984-2.813,3.628-2.638,2.739,0.181,3.066,1.087,4.372,1.087s1.8-.906,4.373-1.087c2.713-.191,3.627.544,3.627,2.638" transform="translate(-346 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 993 B |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M328,32H318a1,1,0,0,1-1-1V27a1,1,0,0,1,2,0v3h8V27a1,1,0,0,1,2,0v4A1,1,0,0,1,328,32Zm-2.859-8.462L324,22.4V27a1,1,0,0,1-2,0V22.415l-1.127,1.127a1,1,0,0,1-1.414-1.414l2.829-2.828h0a0.986,0.986,0,0,1,1.062-.231,0.972,0.972,0,0,1,.1.046,0.992,0.992,0,0,1,.189.126,0.792,0.792,0,0,1,.086.057l2.829,2.828A1,1,0,0,1,325.141,23.538Z" transform="translate(-315 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 823 B |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M298.938,26.682a8.469,8.469,0,0,1-.4,1.7,5.793,5.793,0,0,1-2.5,3.3,7.683,7.683,0,0,0,1.3.9,31.431,31.431,0,0,1-4.1.3l-0.1-.1v0.1a10.659,10.659,0,0,1-3-.6,6.524,6.524,0,0,0,1.6-2.1,8.029,8.029,0,0,0,.6-3,24.178,24.178,0,0,0,1.4,2.1,3.821,3.821,0,0,0,2.1-3,3.462,3.462,0,0,0-.6-2.3,3.33,3.33,0,0,0-1.7-1.4,9.129,9.129,0,0,1,.8-1.3,3.559,3.559,0,0,1,1.3-1.2,6.375,6.375,0,0,1,3.3,6.6h0Zm-6.9-2s-1.1-1.5-1.6-2a4.142,4.142,0,0,0-2.2,3.5,3.982,3.982,0,0,0,2.4,3.3,7.1,7.1,0,0,1-1,1.4,10.974,10.974,0,0,1-1.2,1.1,6.927,6.927,0,0,1-3.4-6.7,11.7,11.7,0,0,1,.5-2,5.557,5.557,0,0,1,2.1-2.7c0.1-.1.2-0.1,0.3-0.2a5.7,5.7,0,0,0-1.6-.8,17.645,17.645,0,0,1,6.8-.3c-1.2,1.7-1.1,5.4-1.1,5.4h0Z" transform="translate(-284 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path {
|
||||
fill-rule: evenodd;
|
||||
fill:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
<path d="M253,31h16V29c-3,0-2-8-5-8h-6c-3,0-2,8-5,8v2Z" transform="translate(-253 -18)"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 544 B |
|
@ -0,0 +1,74 @@
|
|||
.icon {
|
||||
display: inline-block;
|
||||
width: $icon-size;
|
||||
height: $icon-size;
|
||||
background-size: $icon-size;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
vertical-align: middle;
|
||||
|
||||
&.icon-spacer {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&.icon-activity-stream {
|
||||
background-image: url('img/glyph-activityStream-16.svg');
|
||||
}
|
||||
|
||||
&.icon-arrow {
|
||||
background-image: url('img/glyph-showmore-16.svg');
|
||||
}
|
||||
|
||||
&.icon-bookmark {
|
||||
background-image: url('img/glyph-bookmark-16.svg');
|
||||
}
|
||||
|
||||
&.icon-bookmark-white {
|
||||
background-image: url('img/glyph-bookmark-16-white.svg');
|
||||
}
|
||||
|
||||
&.icon-bookmark-remove {
|
||||
background-image: url('img/glyph-bookmark-remove-16.svg');
|
||||
}
|
||||
|
||||
&.icon-delete {
|
||||
background-image: url('img/glyph-delete-16.svg');
|
||||
}
|
||||
|
||||
&.icon-dismiss {
|
||||
background-image: url('img/glyph-dismiss-16.svg');
|
||||
}
|
||||
|
||||
&.icon-firefox-white {
|
||||
background-image: url('img/glyph-firefox-white-16.svg');
|
||||
}
|
||||
|
||||
&.icon-new-window {
|
||||
background-image: url('img/glyph-newWindow-16.svg');
|
||||
}
|
||||
|
||||
&.icon-new-window-private {
|
||||
background-image: url('img/glyph-newWindow-private-16.svg');
|
||||
}
|
||||
|
||||
&.icon-forward {
|
||||
background-image: url('img/glyph-forward-16.svg');
|
||||
}
|
||||
|
||||
&.icon-search {
|
||||
background-image: url('img/glyph-search-16.svg');
|
||||
}
|
||||
|
||||
&.icon-settings {
|
||||
background-image: url('img/glyph-settings-16.svg');
|
||||
}
|
||||
|
||||
&.icon-showMore {
|
||||
background-image: url('img/glyph-show-more-16.svg');
|
||||
}
|
||||
|
||||
&.icon-timeline {
|
||||
background-image: url('img/list-icon.svg');
|
||||
}
|
||||
|
||||
}
|
|
@ -103,7 +103,9 @@ $context-menu-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px $context-menu-bor
|
|||
$context-menu-font-size: 14px;
|
||||
$context-menu-border-radius: 5px;
|
||||
$context-menu-outer-padding: 5px;
|
||||
$context-menu-item-padding: 3px 20px;
|
||||
$context-menu-item-padding: 3px 12px;
|
||||
|
||||
$icon-size: 16px;
|
||||
|
||||
@mixin item-shadow {
|
||||
box-shadow: $item-shadow;
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
const {assert} = require("chai");
|
||||
const React = require("react");
|
||||
const ReactDOM = require("react-dom");
|
||||
const TestUtils = require("react-addons-test-utils");
|
||||
const {renderWithProvider, rawMockData} = require("test/test-utils");
|
||||
const DeleteMenu = require("components/DeleteMenu/DeleteMenu");
|
||||
|
||||
const DEFAULT_PROPS = {
|
||||
onUpdate: () => {},
|
||||
url: "https://foo.com",
|
||||
visible: false
|
||||
};
|
||||
|
||||
// Bookmark guid for testing
|
||||
const BOOKMARK_GUID = "testBookmark";
|
||||
|
||||
// In the menu, the delete option is first,
|
||||
// and the block option is second.
|
||||
const DELETE_INDEX = 0;
|
||||
const BLOCK_INDEX = 1;
|
||||
|
||||
describe("DeleteMenu", () => {
|
||||
let instance;
|
||||
let el;
|
||||
let blockLink;
|
||||
let deleteLink;
|
||||
|
||||
function setup(custom = {}, customProvider = {}) {
|
||||
const props = Object.assign({}, DEFAULT_PROPS, custom);
|
||||
instance = renderWithProvider(<DeleteMenu {...props} />, customProvider);
|
||||
const links = TestUtils.scryRenderedDOMComponentsWithClass(instance, "context-menu-link");
|
||||
blockLink = links[BLOCK_INDEX];
|
||||
deleteLink = links[DELETE_INDEX];
|
||||
el = ReactDOM.findDOMNode(instance);
|
||||
}
|
||||
|
||||
beforeEach(setup);
|
||||
|
||||
it("should render the component", () => {
|
||||
TestUtils.isCompositeComponentWithType(instance, DeleteMenu);
|
||||
});
|
||||
it("should be hidden by default", () => {
|
||||
assert.equal(el.hidden, true);
|
||||
});
|
||||
it("should be visible if props.visible is true", () => {
|
||||
setup({visible: true});
|
||||
assert.equal(el.hidden, false);
|
||||
});
|
||||
it("should have two links", () => {
|
||||
const links = TestUtils.scryRenderedDOMComponentsWithClass(instance, "context-menu-link");
|
||||
assert.lengthOf(links, 2);
|
||||
});
|
||||
it("should fire a delete history event when Remove from History is clicked", done => {
|
||||
setup(null, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_HISTORY_DELETE") {
|
||||
assert.equal(a.data, DEFAULT_PROPS.url);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
assert.equal(deleteLink.innerHTML, "Remove from History");
|
||||
TestUtils.Simulate.click(deleteLink);
|
||||
});
|
||||
it("should fire a delete bookmark event when Remove from Bookmarks is clicked", done => {
|
||||
setup({
|
||||
bookmarkGuid: BOOKMARK_GUID,
|
||||
}, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_BOOKMARK_DELETE") {
|
||||
assert.equal(a.data, BOOKMARK_GUID);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
assert.equal(deleteLink.innerHTML, "Remove from Bookmarks");
|
||||
TestUtils.Simulate.click(deleteLink);
|
||||
});
|
||||
it("should fire a user event for Remove from History", done => {
|
||||
setup({
|
||||
page: "NEW_TAB",
|
||||
source: "FEATURED",
|
||||
index: 3
|
||||
}, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_USER_EVENT") {
|
||||
assert.equal(a.data.event, "DELETE");
|
||||
assert.equal(a.data.page, "NEW_TAB");
|
||||
assert.equal(a.data.source, "FEATURED");
|
||||
assert.equal(a.data.action_position, 3);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
TestUtils.Simulate.click(deleteLink);
|
||||
});
|
||||
it("should fire a user event with experiment_id when the experiment is enabled", done => {
|
||||
setup({
|
||||
page: "NEW_TAB",
|
||||
source: "FEATURED",
|
||||
index: 3
|
||||
}, {
|
||||
getState() {
|
||||
return Object.assign({}, rawMockData,
|
||||
{Experiments: {data: {id: "exp-001", reverseMenuOptions: true}, error: false}});
|
||||
},
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_USER_EVENT") {
|
||||
assert.equal(a.data.event, "DELETE");
|
||||
assert.equal(a.data.page, "NEW_TAB");
|
||||
assert.equal(a.data.source, "FEATURED");
|
||||
assert.equal(a.data.action_position, 3);
|
||||
assert.equal(a.data.experiment_id, "exp-001");
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
// The menu options will be reversed in the experiment, click on the blockLink should
|
||||
// trigger the "DELETE" event
|
||||
TestUtils.Simulate.click(blockLink);
|
||||
});
|
||||
it("should fire a user event for Remove from Bookmarks", done => {
|
||||
setup({
|
||||
page: "NEW_TAB",
|
||||
source: "FEATURED",
|
||||
bookmarkGuid: BOOKMARK_GUID,
|
||||
index: 3
|
||||
}, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_USER_EVENT") {
|
||||
assert.equal(a.data.event, "BOOKMARK_DELETE");
|
||||
assert.equal(a.data.page, "NEW_TAB");
|
||||
assert.equal(a.data.source, "FEATURED");
|
||||
assert.equal(a.data.action_position, 3);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
TestUtils.Simulate.click(deleteLink);
|
||||
});
|
||||
it("should fire a block event when Never show on this page is clicked", done => {
|
||||
setup(null, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_BLOCK_URL") {
|
||||
assert.equal(a.data, DEFAULT_PROPS.url);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
assert.equal(blockLink.innerHTML, "Never show on this page");
|
||||
TestUtils.Simulate.click(blockLink);
|
||||
});
|
||||
it("should fire a user event for Never show on this page", done => {
|
||||
setup({
|
||||
page: "NEW_TAB",
|
||||
source: "FEATURED",
|
||||
index: 2
|
||||
}, {
|
||||
dispatch(a) {
|
||||
if (a.type === "NOTIFY_USER_EVENT") {
|
||||
assert.equal(a.data.event, "BLOCK");
|
||||
assert.equal(a.data.page, "NEW_TAB");
|
||||
assert.equal(a.data.source, "FEATURED");
|
||||
assert.equal(a.data.action_position, 2);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
TestUtils.Simulate.click(blockLink);
|
||||
});
|
||||
|
||||
});
|