Bug 1441984 - Only show OpenInPrivateBrowsing option if private browsing enabled
This commit is contained in:
Родитель
9df2a5ee0d
Коммит
1623117fcb
|
@ -1,4 +1,5 @@
|
|||
import {actionCreators as ac} from "common/Actions.jsm";
|
||||
import {connect} from "react-redux";
|
||||
import {ContextMenu} from "content-src/components/ContextMenu/ContextMenu";
|
||||
import {injectIntl} from "react-intl";
|
||||
import {LinkMenuOptions} from "content-src/lib/link-menu-options";
|
||||
|
@ -9,12 +10,12 @@ const DEFAULT_SITE_MENU_OPTIONS = ["CheckPinTopSite", "EditTopSite", "Separator"
|
|||
export class _LinkMenu extends React.PureComponent {
|
||||
getOptions() {
|
||||
const {props} = this;
|
||||
const {site, index, source} = props;
|
||||
const {site, index, source, isPrivateBrowsingEnabled} = props;
|
||||
|
||||
// Handle special case of default site
|
||||
const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS;
|
||||
|
||||
const options = propOptions.map(o => LinkMenuOptions[o](site, index, source)).map(option => {
|
||||
const options = propOptions.map(o => LinkMenuOptions[o](site, index, source, isPrivateBrowsingEnabled)).map(option => {
|
||||
const {action, impression, id, string_id, type, userEvent} = option;
|
||||
if (!type && id) {
|
||||
option.label = props.intl.formatMessage({id: string_id || id});
|
||||
|
@ -50,4 +51,5 @@ export class _LinkMenu extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
export const LinkMenu = injectIntl(_LinkMenu);
|
||||
const getState = state => ({isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled});
|
||||
export const LinkMenu = connect(getState)(injectIntl(_LinkMenu));
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
|
||||
|
||||
const _OpenInPrivateWindow = site => ({
|
||||
id: "menu_action_open_private_window",
|
||||
icon: "new-window-private",
|
||||
action: ac.OnlyToMain({
|
||||
type: at.OPEN_PRIVATE_WINDOW,
|
||||
data: {url: site.url, referrer: site.referrer}
|
||||
}),
|
||||
userEvent: "OPEN_PRIVATE_WINDOW"
|
||||
});
|
||||
|
||||
/**
|
||||
* List of functions that return items that can be included as menu options in a
|
||||
* LinkMenu. All functions take the site as the first parameter, and optionally
|
||||
|
@ -35,15 +45,6 @@ export const LinkMenuOptions = {
|
|||
}),
|
||||
userEvent: "OPEN_NEW_WINDOW"
|
||||
}),
|
||||
OpenInPrivateWindow: site => ({
|
||||
id: "menu_action_open_private_window",
|
||||
icon: "new-window-private",
|
||||
action: ac.AlsoToMain({
|
||||
type: at.OPEN_PRIVATE_WINDOW,
|
||||
data: {url: site.url, referrer: site.referrer}
|
||||
}),
|
||||
userEvent: "OPEN_PRIVATE_WINDOW"
|
||||
}),
|
||||
BlockUrl: (site, index, eventSource) => ({
|
||||
id: "menu_action_dismiss",
|
||||
icon: "dismiss",
|
||||
|
@ -152,5 +153,6 @@ export const LinkMenuOptions = {
|
|||
CheckPinTopSite: (site, index) => (site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index)),
|
||||
CheckSavedToPocket: (site, index) => (site.pocket_id ? LinkMenuOptions.DeleteFromPocket(site) : LinkMenuOptions.SaveToPocket(site, index)),
|
||||
CheckBookmarkOrArchive: site => (site.pocket_id ? LinkMenuOptions.ArchiveFromPocket(site) : LinkMenuOptions.CheckBookmark(site)),
|
||||
CheckDeleteHistoryOrEmpty: (site, index, eventSource) => (site.pocket_id ? LinkMenuOptions.EmptyItem() : LinkMenuOptions.DeleteUrl(site, index, eventSource))
|
||||
CheckDeleteHistoryOrEmpty: (site, index, eventSource) => (site.pocket_id ? LinkMenuOptions.EmptyItem() : LinkMenuOptions.DeleteUrl(site, index, eventSource)),
|
||||
OpenInPrivateWindow: (site, index, eventSource, isEnabled) => (isEnabled ? _OpenInPrivateWindow(site) : LinkMenuOptions.EmptyItem())
|
||||
};
|
||||
|
|
|
@ -8,6 +8,9 @@ const {Prefs} = ChromeUtils.import("resource://activity-stream/lib/ActivityStrea
|
|||
const {PrerenderData} = ChromeUtils.import("resource://activity-stream/common/PrerenderData.jsm", {});
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
|
||||
|
||||
this.PrefsFeed = class PrefsFeed {
|
||||
|
@ -63,6 +66,9 @@ this.PrefsFeed = class PrefsFeed {
|
|||
values[name] = this._prefs.get(name);
|
||||
}
|
||||
|
||||
// Not a pref, but we need this to determine whether to show private-browsing-related stuff
|
||||
values.isPrivateBrowsingEnabled = PrivateBrowsingUtils.enabled;
|
||||
|
||||
// Set the initial state of all prefs in redux
|
||||
this.store.dispatch(ac.BroadcastToContent({type: at.PREFS_INITIAL_VALUES, data: values}));
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
|
||||
import {Card, PlaceholderCard} from "content-src/components/Card/Card";
|
||||
import {combineReducers, createStore} from "redux";
|
||||
import {INITIAL_STATE, reducers} from "common/Reducers.jsm";
|
||||
import {cardContextTypes} from "content-src/components/Card/types";
|
||||
import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
|
||||
import {mountWithIntl} from "test/unit/utils";
|
||||
import {Provider} from "react-redux";
|
||||
import React from "react";
|
||||
import {shallow} from "enzyme";
|
||||
|
||||
|
@ -23,10 +26,15 @@ let DEFAULT_PROPS = {
|
|||
contextMenuOptions: ["Separator"]
|
||||
};
|
||||
|
||||
function mountCardWithProps(props) {
|
||||
const store = createStore(combineReducers(reducers), INITIAL_STATE);
|
||||
return mountWithIntl(<Provider store={store}><Card {...props} /></Provider>);
|
||||
}
|
||||
|
||||
describe("<Card>", () => {
|
||||
let wrapper;
|
||||
beforeEach(() => {
|
||||
wrapper = mountWithIntl(<Card {...DEFAULT_PROPS} />);
|
||||
wrapper = mountCardWithProps(DEFAULT_PROPS);
|
||||
});
|
||||
it("should render a Card component", () => assert.ok(wrapper.exists()));
|
||||
it("should add the right url", () => assert.propertyVal(wrapper.find("a").props(), "href", DEFAULT_PROPS.link.url));
|
||||
|
@ -42,7 +50,7 @@ describe("<Card>", () => {
|
|||
const link = Object.assign({}, DEFAULT_PROPS.link);
|
||||
delete link.image;
|
||||
|
||||
wrapper = mountWithIntl(<Card {...Object.assign({}, DEFAULT_PROPS, {link})} />);
|
||||
wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {link}));
|
||||
|
||||
assert.lengthOf(wrapper.find(".card-preview-image"), 0);
|
||||
});
|
||||
|
@ -68,7 +76,7 @@ describe("<Card>", () => {
|
|||
const link = Object.assign({}, DEFAULT_PROPS.link);
|
||||
link.contextMenuOptions = ["CheckBookmark"];
|
||||
|
||||
wrapper = mountWithIntl(<Card {...Object.assign({}, DEFAULT_PROPS, {link})} />);
|
||||
wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {link}));
|
||||
wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
|
||||
const {options} = wrapper.find(LinkMenu).props();
|
||||
assert.equal(options, link.contextMenuOptions);
|
||||
|
@ -103,13 +111,6 @@ describe("<Card>", () => {
|
|||
button.simulate("click", {preventDefault: () => {}});
|
||||
assert.isTrue(wrapper.find(".card-outer").hasClass("active"));
|
||||
});
|
||||
it("should have a loaded preview image when the image is loaded", () => {
|
||||
assert.isFalse(wrapper.find(".card-preview-image").hasClass("loaded"));
|
||||
|
||||
wrapper.setState({imageLoaded: true});
|
||||
|
||||
assert.isTrue(wrapper.find(".card-preview-image").hasClass("loaded"));
|
||||
});
|
||||
describe("image loading", () => {
|
||||
let link;
|
||||
let triggerImage = {};
|
||||
|
@ -123,7 +124,14 @@ describe("<Card>", () => {
|
|||
|
||||
link = Object.assign({}, DEFAULT_PROPS.link);
|
||||
link.image += uniqueLink++;
|
||||
wrapper = mountWithIntl(<Card {...Object.assign({}, DEFAULT_PROPS, {link})} />);
|
||||
wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
|
||||
});
|
||||
it("should have a loaded preview image when the image is loaded", () => {
|
||||
assert.isFalse(wrapper.find(".card-preview-image").hasClass("loaded"));
|
||||
|
||||
wrapper.setState({imageLoaded: true});
|
||||
|
||||
assert.isTrue(wrapper.find(".card-preview-image").hasClass("loaded"));
|
||||
});
|
||||
it("should start not loaded", () => {
|
||||
assert.isFalse(wrapper.state("imageLoaded"));
|
||||
|
@ -196,7 +204,7 @@ describe("<Card>", () => {
|
|||
}));
|
||||
});
|
||||
it("should notify Web Extensions with WEBEXT_CLICK if props.isWebExtension is true", () => {
|
||||
wrapper = mountWithIntl(<Card {...DEFAULT_PROPS} isWebExtension={true} eventSource={"MyExtension"} index={3} />);
|
||||
wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {isWebExtension: true, eventSource: "MyExtension", index: 3}));
|
||||
const card = wrapper.find(".card");
|
||||
const event = {preventDefault() {}};
|
||||
card.simulate("click", event);
|
||||
|
|
|
@ -39,7 +39,7 @@ describe("<LinkMenu>", () => {
|
|||
}
|
||||
});
|
||||
it("should show the correct options for default sites", () => {
|
||||
wrapper = shallowWithIntl(<LinkMenu site={{url: "", isDefault: true}} options={["CheckBookmark"]} source={"TOP_SITES"} dispatch={() => {}} />);
|
||||
wrapper = shallowWithIntl(<LinkMenu site={{url: "", isDefault: true}} options={["CheckBookmark"]} source={"TOP_SITES"} isPrivateBrowsingEnabled={true} dispatch={() => {}} />);
|
||||
const {options} = wrapper.find(ContextMenu).props();
|
||||
let i = 0;
|
||||
assert.propertyVal(options[i++], "id", "menu_action_pin");
|
||||
|
@ -157,7 +157,14 @@ describe("<LinkMenu>", () => {
|
|||
menu_action_archive_pocket: {pocket_id: "1234"}
|
||||
};
|
||||
|
||||
const {options} = shallowWithIntl(<LinkMenu site={FAKE_SITE} dispatch={dispatch} index={FAKE_INDEX} options={propOptions} source={FAKE_SOURCE} shouldSendImpressionStats={true} />)
|
||||
const {options} = shallowWithIntl(<LinkMenu
|
||||
site={FAKE_SITE}
|
||||
dispatch={dispatch}
|
||||
index={FAKE_INDEX}
|
||||
isPrivateBrowsingEnabled={true}
|
||||
options={propOptions}
|
||||
source={FAKE_SOURCE}
|
||||
shouldSendImpressionStats={true} />)
|
||||
.find(ContextMenu).props();
|
||||
afterEach(() => dispatch.reset());
|
||||
options.filter(o => o.type !== "separator").forEach(option => {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
|
||||
import {GlobalOverrider} from "test/unit/utils";
|
||||
import {PrefsFeed} from "lib/PrefsFeed.jsm";
|
||||
import {PrerenderData} from "common/PrerenderData.jsm";
|
||||
const {initialPrefs} = PrerenderData;
|
||||
|
@ -6,6 +7,8 @@ const {initialPrefs} = PrerenderData;
|
|||
const PRERENDER_PREF_NAME = "prerender";
|
||||
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
|
||||
|
||||
let overrider = new GlobalOverrider();
|
||||
|
||||
describe("PrefsFeed", () => {
|
||||
let feed;
|
||||
let FAKE_PREFS;
|
||||
|
@ -21,16 +24,23 @@ describe("PrefsFeed", () => {
|
|||
ignore: sinon.spy(),
|
||||
ignoreBranch: sinon.spy()
|
||||
};
|
||||
overrider.set({PrivateBrowsingUtils: {enabled: true}});
|
||||
});
|
||||
afterEach(() => {
|
||||
overrider.restore();
|
||||
});
|
||||
it("should set a pref when a SET_PREF action is received", () => {
|
||||
feed.onAction(ac.SetPref("foo", 2));
|
||||
assert.calledWith(feed._prefs.set, "foo", 2);
|
||||
});
|
||||
it("should dispatch PREFS_INITIAL_VALUES on init", () => {
|
||||
it("should dispatch PREFS_INITIAL_VALUES on init with pref values and .isPrivateBrowsingEnabled", () => {
|
||||
feed.onAction({type: at.INIT});
|
||||
assert.calledOnce(feed.store.dispatch);
|
||||
assert.equal(feed.store.dispatch.firstCall.args[0].type, at.PREFS_INITIAL_VALUES);
|
||||
assert.deepEqual(feed.store.dispatch.firstCall.args[0].data, {foo: 1, bar: 2});
|
||||
const [{data}] = feed.store.dispatch.firstCall.args;
|
||||
assert.equal(data.foo, 1);
|
||||
assert.equal(data.bar, 2);
|
||||
assert.isTrue(data.isPrivateBrowsingEnabled);
|
||||
});
|
||||
it("should add one branch observer on init", () => {
|
||||
feed.onAction({type: at.INIT});
|
||||
|
|
Загрузка…
Ссылка в новой задаче