diff --git a/src/components/icons/alert-message-o.tsx b/src/components/icons/alert-message-o.tsx new file mode 100644 index 000000000..a634afcdb --- /dev/null +++ b/src/components/icons/alert-message-o.tsx @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY +/* tslint:disable */ +/* 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 * as React from 'react' +import GenerateComponentForGraphic from './template' + +// Direct access to SVG +export const Graphic = ( + + + +) + +// Styled Component for SVG +export default GenerateComponentForGraphic(Graphic) diff --git a/src/components/icons/index.tsx b/src/components/icons/index.tsx index f5a72a36b..65bdc1581 100644 --- a/src/components/icons/index.tsx +++ b/src/components/icons/index.tsx @@ -18,6 +18,7 @@ function RotatedIconComponent ( // simple export { default as AlertCircleIcon } from './alert-circle' +export { default as AlertMessageIcon } from './alert-message-o' export const ArrowLeftIcon = RotatedIconComponent(ArrowIcon, 0) export const ArrowRightIcon = RotatedIconComponent(ArrowIcon, 180) export const ArrowDownIcon = RotatedIconComponent(ArrowIcon, -90) diff --git a/src/features/shields/data/index.ts b/src/features/shields/data/index.ts new file mode 100644 index 000000000..b6985db94 --- /dev/null +++ b/src/features/shields/data/index.ts @@ -0,0 +1,27 @@ +/* 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/. */ + +export const dummyData = { + thirdPartyCookiesBlocked: '2', + thirdPartyScriptsBlocked: '2', + thirdPartyDeviceRecognitionBlocked: '2', + pishingMalwareBlocked: '2', + connectionsEncrypted: '2', + noScriptsResouces: { + 'https://imasdk.googleapis.com/js/sdkloader/ima3.js': { + actuallyBlocked: true, + willBlock: true, + userInteracted: true + }, + 'https://scripts.dailymail.co.uk/rta2/v-0.37.min.js': { + actuallyBlocked: true, + willBlock: true, + userInteracted: true + } + }, + otherBlockedResources: [ + 'https://aaaa.com/abcdefghijklmnopqrstuwxyz/123456789', + 'https://bbbb.com/abcdefghijklmnopqrstuwxyz/123456789' + ] +} diff --git a/src/features/shields/display.ts b/src/features/shields/display.ts index 5c3166d95..588690eea 100644 --- a/src/features/shields/display.ts +++ b/src/features/shields/display.ts @@ -136,13 +136,14 @@ export const Link = styled<{}, 'button'>('button')` font-size: 13px; font-weight: 500; display: inline-block; + text-align: left; + width: fit-content; &:hover { text-decoration: underline; } &:focus { - outline-offset: 6px; outline-color: ${p => p.theme.color.brandBrave}; outline-width: 2px; } diff --git a/src/features/shields/index.ts b/src/features/shields/index.ts index 3bc88eea3..3daa63902 100644 --- a/src/features/shields/index.ts +++ b/src/features/shields/index.ts @@ -12,8 +12,12 @@ export { SiteInfo, // Controls BlockedInfoRow, + BlockedInfoRowDetails, + BlockedInfoRowSummary, BlockedInfoRowSingle, + BlockedInfoRowSingleText, BlockedInfoRowForSelect, + BlockedInfoRowForSelectSummary, BlockedInfoRowData, BlockedInfoRowDataForSelect, // footer @@ -31,7 +35,15 @@ export { BlockedListItemSummary, BlockedListFooter, BlockedListFooterWithOptions, - DisabledContentView + DisabledContentView, + // Static content + StaticHeader, + StaticResourcesControls, + StaticResourcesContainer, + // Overlay + Overlay, + WarningText, + WarningModal } from './structure' export { @@ -58,6 +70,7 @@ export { ShieldsButton } from './display' -export { ArrowDownIcon, ArrowUpIcon, ShieldIcon } from './media' +export { ArrowDownIcon, ArrowUpIcon, ShieldIcon, WarningIcon } from './media' export { Toggle } from './toggle' export { SelectBox } from './select' +export { dummyData } from './data' diff --git a/src/features/shields/media/index.ts b/src/features/shields/media/index.ts index 774024296..8c4a994ee 100644 --- a/src/features/shields/media/index.ts +++ b/src/features/shields/media/index.ts @@ -4,7 +4,7 @@ import styled from '../../../theme' import { StyledComponentClass } from 'styled-components' -import { CaratStrongDownIcon, ShieldAlertIcon } from '../../../components/icons' +import { CaratStrongDownIcon, ShieldAlertIcon, AlertMessageIcon } from '../../../components/icons' import { ComponentType } from 'react' @@ -26,11 +26,21 @@ export const ShieldIcon = styled(ShieldAlertIcon as ComponentType)` color: ${p => p.theme.color.lionLogo}; ` +export const WarningIcon = styled(AlertMessageIcon as ComponentType)` + box-sizing: border-box; + display: block; + width: 48px; + height: auto; + margin: 0 auto 12px; + color: ${p => p.theme.color.lionLogo}; +` + export const ArrowDownIcon = styled(CaratStrongDownIcon as ComponentType)` width: 24px; height: 24px; padding: 4px; color: ${p => p.theme.color.text}; + pointer-events: none; &:focus { outline-width: 2px; diff --git a/src/features/shields/select/index.ts b/src/features/shields/select/index.ts index 716bf9fc2..9c05110d6 100644 --- a/src/features/shields/select/index.ts +++ b/src/features/shields/select/index.ts @@ -11,6 +11,7 @@ export interface SelectBoxProps { multiple?: boolean autoFocus?: boolean disabled?: boolean + readOnly?: boolean value?: string onChange?: (e: any) => void children: React.ReactNode @@ -32,6 +33,7 @@ export const SelectBox = styled('select')` line-height: 18px; font-family: ${p => p.theme.fontFamily.heading}; border: 1px solid ${p => p.theme.color.inputBorder}; + pointer-events: ${p => p.readOnly && 'none'}; background: url(${caratUrl}) 97% / 16px no-repeat transparent; /* avoid text overflow w/ carat */ -webkit-padding-start: 10px; diff --git a/src/features/shields/structure/index.ts b/src/features/shields/structure/index.ts index b81cb7fb6..df77c8c32 100644 --- a/src/features/shields/structure/index.ts +++ b/src/features/shields/structure/index.ts @@ -71,10 +71,14 @@ export const SiteOverview = styled('div')` padding: 32px 0; ` -export const TotalBlockedStats = styled<{}, 'section'>('section')` +interface TotalBlockedStatsProps { + size?: 'large' +} + +export const TotalBlockedStats = styled('section')` box-sizing: border-box; display: grid; - grid-template-columns: 80px 140px; + grid-template-columns: ${p => p.size === 'large' ? '80px 210px' : '80px 140px'}; align-items: center; margin: 0px auto 5px; grid-gap: 10px; @@ -85,7 +89,7 @@ export const SiteInfo = styled<{}, 'div'>('div')` display: grid; grid-template-columns: auto 1fr; align-items: center; - margin: 0px auto 5px; + margin: 0px auto 7px; gap: 8px; ` @@ -122,19 +126,55 @@ export const BlockedInfoRow = styled('div')` } ` +export const BlockedInfoRowDetails = styled('details')` + box-sizing: border-box; +` + +export const BlockedInfoRowSummary = styled(BlockedInfoRow.withComponent('summary'))` + &::-webkit-details-marker { + display: none; + } + + &:focus { + outline-color: ${p => p.theme.color.brandBrave}; + outline-offset: -3px; + outline-width: 2px; + } +` + export const BlockedInfoRowSingle = styled(BlockedInfoRow)` padding: 8px 24px 8px 74px; cursor: default; grid-template-columns: 1fr; ` +export const BlockedInfoRowSingleText = styled(BlockedInfoRow)` + padding: 14px 24px 14px 84px; + cursor: default; + grid-template-columns: 1fr; +` + export const BlockedInfoRowForSelect = styled(BlockedInfoRow)` grid-template-columns: auto 1fr; padding-right: 24px; ` +export const BlockedInfoRowForSelectSummary = styled(BlockedInfoRowForSelect.withComponent('summary'))` + &::-webkit-details-marker { + display: none; + } + + &:focus { + outline-color: ${p => p.theme.color.brandBrave}; + outline-offset: -3px; + outline-width: 2px; + } + + box-sizing: border-box; +` + interface BlockedInfoRowDataProps { - disabled: boolean + disabled?: boolean } export const BlockedInfoRowData = styled('div')` @@ -194,6 +234,9 @@ export const BlockedInfoRowDataForSelect = styled(BlockedInfoRowData)` */ export const MainFooter = styled<{}, 'div'>('div')` box-sizing: border-box; + position: relative; + display: grid; + grid-gap: 16px; padding: 24px; ` @@ -246,10 +289,14 @@ export const BlockedListSummary = styled('su } ` -export const BlockedListStatic = styled<{}, 'ul'>('ul')` +interface BlockedListStaticProps { + fixedHeight?: boolean +} + +export const BlockedListStatic = styled('ul')` box-sizing: border-box; list-style-type: none; - height: 328px; + height: ${p => p.fixedHeight && '358px'}; overflow: auto; padding: 0 0 0 24px; margin: 0; @@ -387,3 +434,56 @@ export const DisabledContentView = styled<{}, 'section'>('section')` max-width: 80%; margin: 5px auto 8px; ` + +/** + * Static panel (learn more overlay) + */ +export const StaticHeader = styled<{}, 'header'>('header')` + padding: 0 20px 10px 24px; + line-height: 18px; +` + +export const StaticResourcesControls = styled<{}, 'div'>('div')` + box-sizing: border-box; + position: relative; + height: 216px; + overflow: auto; +` + +export const StaticResourcesContainer = styled<{}, 'div'>('div')` + box-sizing: border-box; + position: absolute; + width: 100%; +` + +/** + * Modals and overlays + */ +export const Overlay = styled<{}, 'div'>('div')` + box-sizing: border-box; + position: absolute; + z-index: 5; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + padding: 0 44px; + background-color: ${p => p.theme.color.modalOverlayBackground} +` +export const WarningText = styled<{}, 'p'>('p')` + margin: 0 0 24px; + line-height: 18px; +` + +export const WarningModal = styled<{}, 'div'>('div')` + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + text-align: center; + min-height: 100px; +` diff --git a/src/theme/shields-dark.ts b/src/theme/shields-dark.ts index 52df0f7bf..8ac8cfee9 100644 --- a/src/theme/shields-dark.ts +++ b/src/theme/shields-dark.ts @@ -12,9 +12,9 @@ const shieldsDarkTheme: ITheme = { panelBackground: '#17171F', panelBackgroundSecondary: colors.grey900, inputBorder: colors.grey700, - separatorLine: colors.grey800 + separatorLine: colors.grey800, + modalOverlayBackground: 'rgba(33, 37, 41, 70%)' } - } export default shieldsDarkTheme diff --git a/src/theme/shields-light.ts b/src/theme/shields-light.ts index af3a4c408..a9d32e6bc 100644 --- a/src/theme/shields-light.ts +++ b/src/theme/shields-light.ts @@ -8,7 +8,8 @@ const shieldsLightTheme: ITheme = { color: { ...defaultTheme.color, text: colors.neutral900, - panelBackgroundSecondary: colors.neutral000 + panelBackgroundSecondary: colors.neutral000, + modalOverlayBackground: 'rgba(255, 255, 255, 70%)' } } diff --git a/stories/features/shields/components/controls/adsTrackersControl.tsx b/stories/features/shields/components/advancedView/controls/adsTrackersControl.tsx similarity index 92% rename from stories/features/shields/components/controls/adsTrackersControl.tsx rename to stories/features/shields/components/advancedView/controls/adsTrackersControl.tsx index b02a7bab7..07c156af4 100644 --- a/stories/features/shields/components/controls/adsTrackersControl.tsx +++ b/stories/features/shields/components/advancedView/controls/adsTrackersControl.tsx @@ -12,17 +12,17 @@ import { BlockedInfoRowStats, BlockedInfoRowText, Toggle -} from '../../../../../src/features/shields' +} from '../../../../../../src/features/shields' // Group Components -import StaticList from '../list/static' +import StaticList from '../overlays/staticOverlay' // Fake data -import { getLocale } from '../../fakeLocale' -import data from '../../fakeData' +import { getLocale } from '../../../fakeLocale' +import data from '../../../fakeData' // Helpers -import { getTabIndexValueBasedOnProps } from '../../helpers' +import { getTabIndexValueBasedOnProps } from '../../../helpers' interface Props { favicon: string diff --git a/stories/features/shields/components/controls/cookiesControl.tsx b/stories/features/shields/components/advancedView/controls/cookiesControl.tsx similarity index 93% rename from stories/features/shields/components/controls/cookiesControl.tsx rename to stories/features/shields/components/advancedView/controls/cookiesControl.tsx index 18daa63cd..99b889714 100644 --- a/stories/features/shields/components/controls/cookiesControl.tsx +++ b/stories/features/shields/components/advancedView/controls/cookiesControl.tsx @@ -5,10 +5,10 @@ import * as React from 'react' // Feature-specific components -import { BlockedInfoRowSingle, SelectBox } from '../../../../../src/features/shields' +import { BlockedInfoRowSingle, SelectBox } from '../../../../../../src/features/shields' // Fake data -import { getLocale } from '../../fakeLocale' +import { getLocale } from '../../../fakeLocale' interface Props { isBlockedListOpen: boolean diff --git a/stories/features/shields/components/controls/deviceRecognitionControl.tsx b/stories/features/shields/components/advancedView/controls/deviceRecognitionControl.tsx similarity index 92% rename from stories/features/shields/components/controls/deviceRecognitionControl.tsx rename to stories/features/shields/components/advancedView/controls/deviceRecognitionControl.tsx index c17c26528..eb3bf3df0 100644 --- a/stories/features/shields/components/controls/deviceRecognitionControl.tsx +++ b/stories/features/shields/components/advancedView/controls/deviceRecognitionControl.tsx @@ -11,17 +11,17 @@ import { ArrowDownIcon, BlockedInfoRowStats, SelectBox -} from '../../../../../src/features/shields' +} from '../../../../../../src/features/shields' // Group Components -import StaticList from '../list/static' +import StaticList from '../overlays/staticOverlay' // Fake data -import { getLocale } from '../../fakeLocale' -import data from '../../fakeData' +import { getLocale } from '../../../fakeLocale' +import data from '../../../fakeData' // Helpers -import { getTabIndexValueBasedOnProps } from '../../helpers' +import { getTabIndexValueBasedOnProps } from '../../../helpers' interface Props { favicon: string diff --git a/stories/features/shields/components/controls/httpsUpgradesControl.tsx b/stories/features/shields/components/advancedView/controls/httpsUpgradesControl.tsx similarity index 92% rename from stories/features/shields/components/controls/httpsUpgradesControl.tsx rename to stories/features/shields/components/advancedView/controls/httpsUpgradesControl.tsx index a1c37f0dd..b728f38ca 100644 --- a/stories/features/shields/components/controls/httpsUpgradesControl.tsx +++ b/stories/features/shields/components/advancedView/controls/httpsUpgradesControl.tsx @@ -12,17 +12,17 @@ import { BlockedInfoRowStats, BlockedInfoRowText, Toggle -} from '../../../../../src/features/shields' +} from '../../../../../../src/features/shields' // Group Components -import StaticList from '../list/static' +import StaticList from '../overlays/staticOverlay' // Fake data -import { getLocale } from '../../fakeLocale' -import data from '../../fakeData' +import { getLocale } from '../../../fakeLocale' +import data from '../../../fakeData' // Helpers -import { getTabIndexValueBasedOnProps } from '../../helpers' +import { getTabIndexValueBasedOnProps } from '../../../helpers' interface Props { favicon: string diff --git a/stories/features/shields/components/controls/scriptsControl.tsx b/stories/features/shields/components/advancedView/controls/scriptsControl.tsx similarity index 92% rename from stories/features/shields/components/controls/scriptsControl.tsx rename to stories/features/shields/components/advancedView/controls/scriptsControl.tsx index c98534ba7..d6d253038 100644 --- a/stories/features/shields/components/controls/scriptsControl.tsx +++ b/stories/features/shields/components/advancedView/controls/scriptsControl.tsx @@ -13,17 +13,17 @@ import { BlockedInfoRowText, Toggle, LinkAction -} from '../../../../../src/features/shields' +} from '../../../../../../src/features/shields' // Group Components -import NoScriptDetails from '../list/noScriptDetails' +import NoScriptOverlay from '../overlays/noScriptOverlay' // Fake data -import { getLocale } from '../../fakeLocale' -import data from '../../fakeData' +import { getLocale } from '../../../fakeLocale' +import data from '../../../fakeData' // Helpers -import { getTabIndexValueBasedOnProps } from '../../helpers' +import { getTabIndexValueBasedOnProps } from '../../../helpers' interface Props { favicon: string @@ -108,7 +108,7 @@ export default class ScriptsControls extends React.PureComponent { { scriptsBlockedOpen && - void + fakeOnChangeShieldsEnabled: () => void } export default class Header extends React.PureComponent { @@ -69,7 +69,13 @@ export default class Header extends React.PureComponent { } render () { - const { fakeOnChange, enabled, favicon, hostname, isBlockedListOpen } = this.props + const { + enabled, + favicon, + hostname, + isBlockedListOpen, + fakeOnChangeShieldsEnabled + } = this.props return ( @@ -83,7 +89,7 @@ export default class Header extends React.PureComponent { {enabled ? {getLocale('enabledMessage')} : null} - + diff --git a/stories/features/shields/components/advancedView/index.tsx b/stories/features/shields/components/advancedView/index.tsx new file mode 100644 index 000000000..8629dc63e --- /dev/null +++ b/stories/features/shields/components/advancedView/index.tsx @@ -0,0 +1,103 @@ +/* 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 * as React from 'react' + +// Feature-specific components +import { ShieldsPanel } from '../../../../../src/features/shields' + +// Components group +import Header from './header' +import InterfaceControls from './interfaceControls' +import PrivacyControls from './privacyControls' +import Footer from '../shared/footer' +import WebCompatWarning from './overlays/webCompatWarningOverlay' + +interface Props { + enabled: boolean + firstAccess: boolean + hostname: string + advancedView: boolean + favicon: string + adsTrackersBlocked: number + httpsUpgrades: number + scriptsBlocked: number + fingerprintingBlocked: number + fakeOnChangeShieldsEnabled: () => void + fakeOnChangeAdvancedView: () => void + fakeToggleFirstAccess: () => void +} + +interface State { + isBlockedListOpen: boolean +} + +export default class ShieldsAdvancedView extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { isBlockedListOpen: false } + } + setBlockedListOpen = () => { + this.setState({ isBlockedListOpen: !this.state.isBlockedListOpen }) + } + render () { + const { + enabled, + firstAccess, + favicon, + hostname, + adsTrackersBlocked, + httpsUpgrades, + scriptsBlocked, + fingerprintingBlocked, + fakeOnChangeShieldsEnabled, + fakeOnChangeAdvancedView, + fakeToggleFirstAccess + } = this.props + const { isBlockedListOpen } = this.state + return ( + + {firstAccess ? : null} +
+ { + enabled ? ( + <> + + + + ) : null + } +