Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(PPDSC-2605): safari svg filters fix #487

Merged
merged 23 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1bdad21
fix(PPDSC-2605): safari svg filters fix
evgenitsn Nov 23, 2022
e9dc2da
fix(PPDSC-2605): fix tests
evgenitsn Nov 23, 2022
0cf16e0
Merge branch 'main' into fix/PPDSC-2605-svg-shadow-elements-missing-i…
evgenitsn Nov 23, 2022
b83a76a
fix(PPDSC-2605): dynamically import the sanitizer lib for Safari
evgenitsn Nov 25, 2022
059251e
fix(PPDSC-2605): dynamically import the sanitizer lib for Safari
evgenitsn Nov 25, 2022
f2a5928
fix(PPDSC-2605): dynamically import the sanitizer lib for Safari
evgenitsn Nov 25, 2022
4186822
fix(PPDSC-2605): update safari logic
evgenitsn Nov 25, 2022
8c548bc
fix(PPDSC-2605): fixing e2e test
evgenitsn Nov 28, 2022
14d5184
fix(PPDSC-2605): update svg styles
evgenitsn Nov 28, 2022
d6ac30d
fix(PPDSC-2605): update snapshots
evgenitsn Nov 28, 2022
d4e0419
Merge branch 'main' into fix/PPDSC-2605-svg-shadow-elements-missing-i…
evgenitsn Nov 28, 2022
ba10871
fix(PPDSC-2605): clean code
evgenitsn Nov 29, 2022
8efb824
Merge branch 'main' into fix/PPDSC-2605-svg-shadow-elements-missing-i…
evgenitsn Nov 29, 2022
d3f1b99
fix(PPDSC-2605): fix opacity state
evgenitsn Nov 29, 2022
612b7c3
fix(PPDSC-2605): fix opacity state
evgenitsn Nov 29, 2022
f7eecee
fix(PPDSC-2605): revert last commit
evgenitsn Nov 29, 2022
d8af58b
Merge branch 'main' into fix/PPDSC-2605-svg-shadow-elements-missing-i…
evgenitsn Nov 29, 2022
beecfd8
fix(PPDSC-2605): add opacity state again
evgenitsn Nov 29, 2022
d9b0b97
fix(PPDSC-2605): merge branch 'main' into fix/PPDSC-2605
evgenitsn Nov 29, 2022
c51bcf6
fix(PPDSC-2605): update raw-loader usage
evgenitsn Nov 29, 2022
de01b06
fix(PPDSC-2605): update raw-loader
evgenitsn Nov 29, 2022
b36ef3d
Merge branch 'main' into fix/PPDSC-2605-svg-shadow-elements-missing-i…
evgenitsn Nov 29, 2022
3b7a029
fix(PPDSC-2605): add wait time to the percy docs tests
evgenitsn Nov 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
"package-change-checker": "^1.2.4",
"prettier": "2.2.1",
"pretty-proptypes": "^0.6.0",
"raw-loader": "^4.0.2",
mutebg marked this conversation as resolved.
Show resolved Hide resolved
"react": "18",
"react-codesandboxer": "^3.1.1",
"react-dom": "18",
Expand Down Expand Up @@ -222,12 +223,12 @@
"date-fns": "^2.6.0",
"debounce": "^1.2.0",
"dequal": "^1.0.0",
"dompurify": "^2.3.1",
"downshift": "^6.1.7",
"file-saver": "^2.0.5",
"glob": "^8.0.3",
"globby": "^13.1.2",
"googleapis": "^109.0.1",
"isomorphic-dompurify": "^0.24.0",
"jszip": "^3.7.1",
"next-seo": "^4.28.1",
"react-focus-lock": "^2.5.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/build-package-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const allowedPackageProperties = [
const dependenciesNotToBeIncluded = [
'jszip',
'file-saver',
'dompurify',
'isomorphic-dompurify',
'@storybook/react',
'@babel/runtime-corejs3',
'semver',
Expand Down
66 changes: 63 additions & 3 deletions site/components/illustrations/illustration-loader.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,78 @@
import React from 'react';
import {pathToID} from './utils';
import React, {useEffect, useState} from 'react';
import {isNotSafari, isSafari, pathToID} from './utils';

/**
* Only for Safari. It reads the svg file as raw string and returns the problematic <defs> .. </defs> part as additional svg which solves the problem. If the browser is not Safari then all of this is skipped.
*/
const getSafariSVGFilters = (
sanitize: (source: string) => string,
path: string,
) => {
const rawSVG = sanitize(
// eslint-disable-next-line import/no-dynamic-require, global-require
require(`../../public/static/illustrations/${path}.svg`).default,
);

const defsStart = '<defs>';
evgenitsn marked this conversation as resolved.
Show resolved Hide resolved
const defsEnd = '</defs>';
const startIndex = rawSVG.indexOf(defsStart);
const endIndex = rawSVG.indexOf(defsEnd);
const result = rawSVG.substring(startIndex, endIndex + defsEnd.length);

return startIndex > -1 ? (
<svg
width="0"
height="0"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: result}}
/>
) : null;
};

export const getIllustrationComponent = (
path: string,
props?: React.SVGProps<SVGSVGElement>,
) => {
const id = pathToID(path);

const Component = () => (
const renderInlineSVG = () => (
<svg viewBox="0 0 1490 838" width="100%" {...props}>
<use href={`static/illustrations/${path}.svg#${id}`} />
</svg>
);

const Component = () => {
mstuartf marked this conversation as resolved.
Show resolved Hide resolved
const [safariSVGFilters, setSafariSVGFilters] = useState<
JSX.Element | undefined | null
>(undefined);

useEffect(() => {
if (isSafari && safariSVGFilters === undefined) {
// Dynamically importing 'isomorphic-dompurify' only for Safari to avoid bloating the bundle size for other browsers.
const importSanitizer = async () => {
const dompurify = await (await import('isomorphic-dompurify'))
.default;
const value = getSafariSVGFilters(dompurify.sanitize, path);
setSafariSVGFilters(value);
};
importSanitizer();
}
}, [safariSVGFilters]);

// If the browser is Safari and there are filters, we render an svg with filters, otherwise we render a clean svg.
const safariSVG = (
<>
{isSafari && safariSVGFilters}
{renderInlineSVG()}
</>
);

// If the browser is not Safari we will render a clean svg without checking for filters. There is an explicit isNotSafari call because of the server side nature of the component we have to handle a race condition where the window object is not loaded yet.
const nonSafariSVG = isNotSafari ? renderInlineSVG() : null;

return safariSVGFilters !== undefined ? safariSVG : nonSafariSVG;
};

return Component;
};

Expand Down
8 changes: 8 additions & 0 deletions site/components/illustrations/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ export const pathToID = (path: string) => {
}
return '';
};

const safariUACheck = /^((?!chrome|android).)*safari/i;
const isWindowLoaded = typeof window !== 'undefined';

export const isSafari =
isWindowLoaded && safariUACheck.test(window.navigator.userAgent);
export const isNotSafari =
isWindowLoaded && !safariUACheck.test(window.navigator.userAgent);
evgenitsn marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions site/components/tools/svg-previewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useEffect, useState} from 'react';
import {getColorCssFromTheme, getSSRId, P} from 'newskit';
import dompurify from 'dompurify';
import dompurify from 'isomorphic-dompurify';
Vanals marked this conversation as resolved.
Show resolved Hide resolved
import {themeList, ThemeNames} from './colors-theme-list';
import {
StyledButtonsContainer,
Expand All @@ -12,7 +12,7 @@ import {DownloadControls} from './controls/download-controls';
import {ThemeControls} from './controls/theme-controls';

export const SvgPreviewer: React.FC = () => {
const sanitizer = dompurify.sanitize;
const {sanitize} = dompurify;

// The name of the theme being currently used, the initial value will decide the default theme.
const [currentThemeName, setCurrentThemeName] = useState<ThemeNames>(
Expand Down Expand Up @@ -180,7 +180,7 @@ export const SvgPreviewer: React.FC = () => {
<StyledSingleSvgWrapper key={baseSvgCodeGroup[index].name}>
<P>{baseSvgCodeGroup[index].name}</P>
{/* eslint-disable-next-line react/no-danger */}
<div dangerouslySetInnerHTML={{__html: sanitizer(svgCode)}} />
<div dangerouslySetInnerHTML={{__html: sanitize(svgCode)}} />
</StyledSingleSvgWrapper>
))}
</StyledSvgGroupContainer>
Expand Down
4 changes: 4 additions & 0 deletions site/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ module.exports = withMDX({
},
]),
];
config.module.rules.push({
test: /\.svg$/,
use: 'raw-loader',
});

return config;
},
Expand Down
6 changes: 6 additions & 0 deletions src/test/test-framework-setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import {matchers, createSerializer} from '@emotion/jest';
import failOnConsole from 'jest-fail-on-console';
import {TextEncoder, TextDecoder} from 'util';

// @ts-ignore
global.TextEncoder = TextEncoder;
// @ts-ignore
global.TextDecoder = TextDecoder;

failOnConsole({
silenceMessage: errorMessage => {
Expand Down
Loading