Getting Download links working
This commit is contained in:
parent
6bc4306ca3
commit
06a90429ff
@ -157,6 +157,7 @@
|
|||||||
"react-i18next": "^7.3.6",
|
"react-i18next": "^7.3.6",
|
||||||
"style-loader": "^0.20.1",
|
"style-loader": "^0.20.1",
|
||||||
"svg-react-loader": "^0.4.5",
|
"svg-react-loader": "^0.4.5",
|
||||||
|
"throttle-debounce": "^1.0.1",
|
||||||
"uglifyjs-webpack-plugin": "^1.1.8",
|
"uglifyjs-webpack-plugin": "^1.1.8",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"webpack-merge": "^4.1.1",
|
"webpack-merge": "^4.1.1",
|
||||||
|
@ -3,22 +3,7 @@
|
|||||||
exports[`App rendering 1`] = `
|
exports[`App rendering 1`] = `
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Translate(Form)
|
<Translate(Form)
|
||||||
downloadUrls={
|
downloadUrls={Array []}
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"filename": "image.svg",
|
|
||||||
"label": "Download SVG",
|
|
||||||
"type": "image/svg+xml",
|
|
||||||
"url": "#svg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"filename": "image.png",
|
|
||||||
"label": "Download PNG",
|
|
||||||
"type": "image/png",
|
|
||||||
"url": "#png",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
permalinkUrl="#permalink"
|
permalinkUrl="#permalink"
|
||||||
syntaxes={
|
syntaxes={
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { translate } from 'react-i18next';
|
||||||
|
import { debounce } from 'throttle-debounce';
|
||||||
|
|
||||||
import style from './style.css';
|
import style from './style.css';
|
||||||
|
|
||||||
@ -10,19 +13,75 @@ import { syntaxes, demoImage } from 'devel';
|
|||||||
class App extends React.PureComponent {
|
class App extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
syntaxes,
|
syntaxes,
|
||||||
image: demoImage,
|
image: demoImage
|
||||||
downloadUrls: [
|
|
||||||
{ url: '#svg', filename: 'image.svg', type: 'image/svg+xml', label: 'Download SVG' },
|
|
||||||
{ url: '#png', filename: 'image.png', type: 'image/png', label: 'Download PNG' }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSvgUrl({ markup }) {
|
||||||
|
try {
|
||||||
|
const type = 'image/svg+xml';
|
||||||
|
const blob = new Blob([markup], { type });
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
svgUrl: {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: this.props.t('Download SVG'),
|
||||||
|
filename: 'image.svg',
|
||||||
|
type
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async setPngUrl({ element, markup }) {
|
||||||
|
try {
|
||||||
|
const type = 'image/png';
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
const loader = new Image();
|
||||||
|
|
||||||
|
loader.width = canvas.width = Number(element.getAttribute('width')) * 2;
|
||||||
|
loader.height = canvas.height = Number(element.getAttribute('height')) * 2;
|
||||||
|
|
||||||
|
await new Promise(resolve => {
|
||||||
|
loader.onload = resolve;
|
||||||
|
loader.src = 'data:image/svg+xml,' + encodeURIComponent(markup);
|
||||||
|
});
|
||||||
|
|
||||||
|
context.drawImage(loader, 0, 0, loader.width, loader.height);
|
||||||
|
const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
pngUrl: {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: this.props.t('Download PNG'),
|
||||||
|
filename: 'image.png',
|
||||||
|
type
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRender = debounce(0, result => {
|
||||||
|
this.setSvgUrl(result);
|
||||||
|
this.setPngUrl(result);
|
||||||
|
})
|
||||||
|
|
||||||
handleSubmit = ({expr, syntax}) => {
|
handleSubmit = ({expr, syntax}) => {
|
||||||
console.log(syntax, expr); // eslint-disable-line no-console
|
console.log(syntax, expr); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { downloadUrls, syntaxes, image } = this.state;
|
const { svgUrl, pngUrl, syntaxes, image } = this.state;
|
||||||
|
const downloadUrls = [
|
||||||
|
svgUrl,
|
||||||
|
pngUrl
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<Form
|
<Form
|
||||||
@ -37,10 +96,15 @@ class App extends React.PureComponent {
|
|||||||
<p>Sample warning message</p>
|
<p>Sample warning message</p>
|
||||||
</Message>
|
</Message>
|
||||||
<div className={ style.render }>
|
<div className={ style.render }>
|
||||||
{ renderImage(image) }
|
{ renderImage(image, { onRender: this.handleRender }) }
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
App.propTypes = {
|
||||||
|
t: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
export default translate()(App);
|
||||||
|
export { App };
|
||||||
|
@ -3,14 +3,15 @@ jest.mock('components/SVG');
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
import App from 'components/App';
|
import { App } from 'components/App';
|
||||||
import renderImage from 'components/SVG';
|
import renderImage from 'components/SVG';
|
||||||
|
import { translate } from '__mocks__/i18n';
|
||||||
|
|
||||||
describe('App', () => {
|
describe('App', () => {
|
||||||
test('rendering', () => {
|
test('rendering', () => {
|
||||||
renderImage.mockReturnValue('Testing image');
|
renderImage.mockReturnValue('Testing image');
|
||||||
const component = shallow(
|
const component = shallow(
|
||||||
<App/>
|
<App t={ translate }/>
|
||||||
);
|
);
|
||||||
expect(component).toMatchSnapshot();
|
expect(component).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,7 @@ class Image extends Base {
|
|||||||
|
|
||||||
if (onRender && this.publishedMarkup !== markup) {
|
if (onRender && this.publishedMarkup !== markup) {
|
||||||
this.publishedMarkup = markup;
|
this.publishedMarkup = markup;
|
||||||
onRender(this.svg.outerHTML);
|
onRender({ element: this.svg, markup: this.svg.outerHTML });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,17 +25,17 @@ const renderChildren = children => {
|
|||||||
|
|
||||||
return children.length === 1 ?
|
return children.length === 1 ?
|
||||||
renderImage(children[0]) :
|
renderImage(children[0]) :
|
||||||
children.map(renderImage);
|
children.map((node, i) => renderImage(node, { key: i }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderImage = (node, key) => {
|
const renderImage = (node, extraProps = {}) => {
|
||||||
if (typeof node === 'string') {
|
if (typeof node === 'string') {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, props, children } = node;
|
const { type, props, children } = node;
|
||||||
|
|
||||||
return React.createElement(nodeTypes[type], { key, ...props }, renderChildren(children));
|
return React.createElement(nodeTypes[type], { ...extraProps, ...props }, renderChildren(children));
|
||||||
};
|
};
|
||||||
|
|
||||||
export default renderImage;
|
export default renderImage;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
An error has occurred: An error has occurred
|
An error has occurred: An error has occurred
|
||||||
Created by <1>Jeff Avallone</1>: Created by <1>Jeff Avallone</1>
|
Created by <1>Jeff Avallone</1>: Created by <1>Jeff Avallone</1>
|
||||||
Display: Display
|
Display: Display
|
||||||
|
Download PNG: Download PNG
|
||||||
|
Download SVG: Download SVG
|
||||||
Enter regular expression to display: Enter regular expression to display
|
Enter regular expression to display: Enter regular expression to display
|
||||||
Generated images licensed: 'Generated images licensed: <1><0></0></1>'
|
Generated images licensed: 'Generated images licensed: <1><0></0></1>'
|
||||||
Permalink: Permalink
|
Permalink: Permalink
|
||||||
|
@ -38,7 +38,7 @@ exports[`Index page component rendering 1`] = `
|
|||||||
</p>
|
</p>
|
||||||
</Message>
|
</Message>
|
||||||
</noscript>
|
</noscript>
|
||||||
<App />
|
<Translate(App) />
|
||||||
<Translate(Footer) />
|
<Translate(Footer) />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
`;
|
`;
|
||||||
|
@ -7785,6 +7785,10 @@ throat@^4.0.0:
|
|||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
|
||||||
|
|
||||||
|
throttle-debounce@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-1.0.1.tgz#dad0fe130f9daf3719fdea33dc36a8e6ba7f30b5"
|
||||||
|
|
||||||
throttleit@^1.0.0:
|
throttleit@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
||||||
|
Loading…
Reference in New Issue
Block a user