diff --git a/app/panel/components/About.jsx b/app/panel/components/About.jsx index 66bc2017d..4688c5e04 100644 --- a/app/panel/components/About.jsx +++ b/app/panel/components/About.jsx @@ -12,64 +12,34 @@ */ import React from 'react'; import globals from '../../../src/classes/Globals'; -import { sendMessage } from '../utils/msg'; +import PanelToTabLink from './BuildingBlocks/PanelToTabLink'; const { BROWSER_INFO, EXTENSION_VERSION } = globals; /** - * @class Implement About view which opens from the main drop-down menu. - * @memberof PanelClasses + * Render About view which opens from the main drop-down menu. */ -class About extends React.Component { - /** - * Open internal Licenses page with licenses of - * all third-party packages used by Ghostery. - * @static - */ - static openNewTab() { - sendMessage('openNewTab', { - url: chrome.runtime.getURL('./app/templates/licenses.html'), - become_active: true, - }); - window.close(); - } +const About = () => { + const licensesUrl = chrome.runtime.getURL('./app/templates/licenses.html'); - /** - * Render About panel. - * @return {ReactComponent} ReactComponent instance - */ - render() { - return ( -
-
-
-

{ t('panel_about_panel_header') }

-
-

{ t('panel_about_version_header', [BROWSER_INFO.displayName, EXTENSION_VERSION]) }

- - { t('panel_about_release_notes') } - - - { t('panel_about_license') } - - - { t('panel_about_privacy_statement') } - - - { t('panel_about_terms_and_conditions') } - - - { t('panel_about_imprint') } - -
- { t('panel_about_licenses') } -
- Ghostery.com -
+ return ( +
+
+
+

{ t('panel_about_panel_header') }

+
+

{ t('panel_about_version_header', [BROWSER_INFO.displayName, EXTENSION_VERSION]) }

+ {t('panel_about_release_notes')} + {t('panel_about_license')} + {t('panel_about_privacy_statement')} + {t('panel_about_terms_and_conditions')} + {t('panel_about_imprint')} + {t('panel_about_licenses')} + Ghostery.com
- ); - } -} +
+ ); +}; export default About; diff --git a/app/panel/components/BuildingBlocks/PanelToTabLink.jsx b/app/panel/components/BuildingBlocks/PanelToTabLink.jsx new file mode 100644 index 000000000..32748e1b1 --- /dev/null +++ b/app/panel/components/BuildingBlocks/PanelToTabLink.jsx @@ -0,0 +1,29 @@ +/** + * PanelToTabLink Component + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * 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 React from 'react'; +import { handleClickOnNewTabLink } from '../../utils/msg'; + +/** + * Implement panel -> new tab links. Used in Help, About, and other panel views + * @memberof PanelBuildingBlocks + */ +const PanelToTabLink = (props) => { + const { href, children } = props; + + return ( + {children} + ); +}; + +export default PanelToTabLink; diff --git a/app/panel/components/CreateAccount.jsx b/app/panel/components/CreateAccount.jsx index fab828e02..4c2530ff9 100644 --- a/app/panel/components/CreateAccount.jsx +++ b/app/panel/components/CreateAccount.jsx @@ -16,6 +16,7 @@ import { Link } from 'react-router-dom'; import ClassNames from 'classnames'; import RSVP from 'rsvp'; import { validateEmail, validateConfirmEmail, validatePassword } from '../utils/utils'; +import I18nWithLink from '../../shared-components/I18nWithLink'; /** * @class Implement Create Account view which opens @@ -215,7 +216,9 @@ class CreateAccount extends React.Component {
diff --git a/app/panel/components/Help.jsx b/app/panel/components/Help.jsx index e1b0e3e0f..057a47736 100644 --- a/app/panel/components/Help.jsx +++ b/app/panel/components/Help.jsx @@ -12,61 +12,37 @@ */ import React from 'react'; -import { sendMessage, openSupportPage } from '../utils/msg'; +import { openSupportPage } from '../utils/msg'; +import PanelToTabLink from './BuildingBlocks/PanelToTabLink'; + /** - * @class Implement Help view which opens from the main drop-down menu. - * @memberof PanelClasses + * Render Help view that user can open from the header drop-down menu */ -class Help extends React.Component { - /** - * Handle click on 'Set Up Ghostery' menu item - */ - openHubTab = (e) => { - e.preventDefault(); - sendMessage('openNewTab', { - url: chrome.runtime.getURL('./app/templates/hub.html'), - become_active: true, - }); - window.close(); - } - - /** - * Handle click on 'Support' menu item - */ - openSupportTab = (e) => { - e.preventDefault(); - openSupportPage(); - window.close(); - } +const Help = () => { + const hubUrl = chrome.runtime.getURL('./app/templates/hub.html'); - /** - * Render Help view. - * @return {ReactComponent} ReactComponent instance - */ - render() { - return ( -
-
-
-

{ t('panel_help_panel_header') }

-
- { t('panel_help_setup') } -
-
-

{ t('panel_help_questions_header') }

- { t('panel_help_faq') } - { t('panel_help_feedback') } - { t('panel_help_support') } -
-
-

{ t('panel_help_contact_header') }

- info@ghostery.com -
+ return ( +
+
+
+

{ t('panel_help_panel_header') }

+
+ {t('panel_help_setup')} +
+
+

{ t('panel_help_questions_header') }

+ {t('panel_help_faq')} + {t('panel_help_feedback')} + { t('panel_help_support') } +
+
+

{ t('panel_help_contact_header') }

+ info@ghostery.com
- ); - } -} +
+ ); +}; export default Help; diff --git a/app/panel/components/Subscribe.jsx b/app/panel/components/Subscribe.jsx index b1cfc6834..62797e8e2 100644 --- a/app/panel/components/Subscribe.jsx +++ b/app/panel/components/Subscribe.jsx @@ -12,8 +12,10 @@ */ import React from 'react'; import { NavLink } from 'react-router-dom'; +import PanelToTabLink from './BuildingBlocks/PanelToTabLink'; import { sendMessage, openSubscriptionPage } from '../utils/msg'; + /** * Helper function to handle clicking on the Become a Subscriber button */ @@ -34,9 +36,9 @@ const Subscribe = (props) => {
- + {t('subscribe_pitch_learn_more')} - +
{t('subscribe_pitch_button_label')}
diff --git a/app/panel/utils/msg.js b/app/panel/utils/msg.js index 3ac8904dd..c417f1194 100644 --- a/app/panel/utils/msg.js +++ b/app/panel/utils/msg.js @@ -140,6 +140,24 @@ export function sendRewardMessage(name, message, callback = defaultCallback()) { }, callback); } +/** + * Handle clicks on links with a fixed destination + */ +export function handleClickOnNewTabLink(e) { + e.preventDefault(); + + let linkTag = e.target; + while (!linkTag.href) { + linkTag = linkTag.parentElement; + } + const { href } = linkTag; + + sendMessage('openNewTab', { + url: href, + become_active: true, + }); +} + /** * Send a message to open a Subscription or Subscribe tab. * Which one is determined in background based on the current user state. @@ -157,7 +175,8 @@ export function openSubscriptionPage() { * This should be used for messages that don't require a callback. * @memberOf PanelUtils */ -export function openSupportPage() { +export function openSupportPage(e) { + e.preventDefault(); sendMessage('account.openSupportPage'); window.close(); } diff --git a/app/shared-components/I18nWithLink/I18nWithLink.jsx b/app/shared-components/I18nWithLink/I18nWithLink.jsx new file mode 100644 index 000000000..16f60e996 --- /dev/null +++ b/app/shared-components/I18nWithLink/I18nWithLink.jsx @@ -0,0 +1,52 @@ +/** + * I18nWithLink Component + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * 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 React, { Component, createRef } from 'react'; +import PropTypes from 'prop-types'; + +import { handleClickOnNewTabLink } from '../../panel/utils/msg'; + +/** + * A React component for i18n strings that need to include links + * @return {JSX} JSX for rendering an i18n string with embedded links + * @memberof SharedComponents + */ +class I18nWithLink extends Component { + constructor(props) { + super(props); + this.containerRef = createRef(); + } + + componentDidMount() { + const { current: { children } } = this.containerRef; + for (let i = 0; i < children.length; i++) { + const ele = children[i]; + if (ele.nodeName.toLowerCase() === 'a') { + ele.onclick = e => handleClickOnNewTabLink(e); + } + } + } + + render() { + const { value } = this.props; + return ( + + ); + } +} + +export default I18nWithLink; + +I18nWithLink.propTypes = { + value: PropTypes.string.isRequired, +}; diff --git a/app/shared-components/I18nWithLink/index.js b/app/shared-components/I18nWithLink/index.js new file mode 100644 index 000000000..c8dfa5de1 --- /dev/null +++ b/app/shared-components/I18nWithLink/index.js @@ -0,0 +1,16 @@ +/** + * Point of entry index.js file for I18nWithLink + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * 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 I18nWithLink from './I18nWithLink'; + +export default I18nWithLink;