Skip to content

Commit

Permalink
Add base64 image support (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
gidztech authored and adamgruber committed Oct 23, 2017
1 parent 207a1bb commit 4278e4c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/components/test/context.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const cx = classNames.bind(styles);
const imgRegEx = /(?:png|jpe?g|gif)$/i;
const protocolRegEx = /^(?:(?:https?|ftp):\/\/)/i;
const urlRegEx = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/ // eslint-disable-line
const base64ImgRegEx = /^data:image\/([a-zA-Z0-9-_.])+;base64,([^"]*)$/i;

class TestContext extends Component {
static displayName = 'TestContext';
Expand Down Expand Up @@ -38,6 +39,8 @@ class TestContext extends Component {
);
}

renderBase64Image = (ctx, title) => <img src={ ctx } className={ cx('image') } alt={ title } />;

renderLink = (url, title) => {
const linkUrl = `${protocolRegEx.test(url) ? '' : 'http://'}${url}`;
return (
Expand All @@ -58,6 +61,11 @@ class TestContext extends Component {
return this.renderImage(content, title);
}

// Base64 Images
if (base64ImgRegEx.test(content)) {
return this.renderBase64Image(content, title);
}

// URLs
if (urlRegEx.test(content)) {
return this.renderLink(content, title);
Expand Down
65 changes: 55 additions & 10 deletions test/spec/components/test/context.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ describe('<TestContext />', () => {
wrapper,
ctx: wrapper.find(TestContext),
ctxItems: wrapper.find('.test-context-item'),
img: wrapper.find('.test-image-link'),
img: wrapper.find('.test-image'),
imgLink: wrapper.find('.test-image-link'),
link: wrapper.find('.test-text-link'),
snippet: wrapper.find(CodeSnippet)
};
Expand Down Expand Up @@ -57,29 +58,73 @@ describe('<TestContext />', () => {

it('renders image url with protocol', () => {
const context = 'http://test.url.com/testimage.png';
const { wrapper, snippet, img } = getInstance({
const { wrapper, snippet, imgLink } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
img.simulate('click', { stopPropagation: noop });
expect(imgLink).to.have.lengthOf(1);
imgLink.simulate('click', { stopPropagation: noop });
});

it('renders image url without protocol', () => {
const context = 'test.url.com/testimage.png';
const { wrapper, snippet, img } = getInstance({
const { wrapper, snippet, imgLink } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
expect(imgLink).to.have.lengthOf(1);
});

it('renders local image', () => {
const context = '/testimage.png';
const { wrapper, snippet, imgLink } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(imgLink).to.have.lengthOf(1);
});

it('renders base64 jpeg image', () => {
const context = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAPAAA/+4AJkFkb2JlAGTAAAAAAQMAFQQDBgoNAAABywAAAgsAAAJpAAACyf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoKDBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8IAEQgAEAAQAwERAAIRAQMRAf/EAJQAAQEBAAAAAAAAAAAAAAAAAAMFBwEAAwEAAAAAAAAAAAAAAAAAAAEDAhAAAQUBAQAAAAAAAAAAAAAAAgABAwQFESARAAIBAwIHAAAAAAAAAAAAAAERAgAhMRIDQWGRocEiIxIBAAAAAAAAAAAAAAAAAAAAIBMBAAMAAQQDAQAAAAAAAAAAAQARITHwQVGBYXGR4f/aAAwDAQACEQMRAAAB0UlMciEJn//aAAgBAQABBQK5bGtFn6pWi2K12wWTRkjb/9oACAECAAEFAvH/2gAIAQMAAQUCIuIJOqRndRiv/9oACAECAgY/Ah//2gAIAQMCBj8CH//aAAgBAQEGPwLWQzwHepfNbcUNfM4tUIbA9QL4AvnxTlAxacpWJReOlf/aAAgBAQMBPyHZDveuCyu4B4lz2lDKto2ca5uclPK0aoq32x8xgTSLeSgbyzT65n//2gAIAQIDAT8hlQjP/9oACAEDAwE/IaE9GcZFJ//aAAwDAQACEQMRAAAQ5F//2gAIAQEDAT8Q1oowKccI3KTdAWkPLw2ssIrwKYUzuJoUJsIHOCoG23ISlja+rU9QvCx//9oACAECAwE/EAuNIiKf/9oACAEDAwE/ECujJzHf7iwHOv5NhK+8efH50z//2Q==';
const { wrapper, snippet, img } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
});

it('renders base64 png image', () => {
const context = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtpJREFUeNqkk29IE3EYx5/bflO33d1uc3bbbaUtJNPK3BqRyrQhRGkJBYmgvgojLPKFEBX1KqIC39dbDQQJRJLQVxKGiANDTJmRkrS1yDnb3f7c/t31u2Vj+aYX/eDD3T2/3/O95/nePYQsy/A/CxGdOoDL2t9PGkKJgE6rO2Q32m6ymwbGsKrd0H5FEbwbxQTwC9cwQi6XA0mSABWS91YZKr1abz8xXLNbLQ803gBrZ4VViYe2t0OLCwu+xbm5WSEancUhvxJX/yWgIi45axpeUAJleXTsnumg2cKsrawgzmZDDEUxtsrKOkdtbf3G+roQj8XCuJKwCnLYAwUJODNlemjQ0qwTnVJbSXNec8nnK+jTWi0YTSZ7T3//AEnTbViAVkEsB5DBAmnpitVmrY4EduCM2YWLIfJJoigWFYj9KSkBkmHsjS0trdiH4yoQJYA4FklJTSWMhkxFkkCCEbbC4Tx+v79wr8Ank3nzGtxudzabrUIgw0vIyi4MiGUpJPFZGHx3C9xWJwyfewaCIECl2VyoIouTg5EIGBiGxQJGBGl5AiTZVXX9qCsOcYDzAIY3pdB++AJcbGsDr9cLvV1dQFFUHpIkwdnUBGebmwELqBBOnoafWfjy/OPjA0MOV/moFu633wVvVSu4xk9CT3c3vBobK1Sg/HbRdBoSPP8DC0QR97kCIClNYyPZ1NPdJ7evPeA8R1rzhw0mUz5ZuRa3IOK25mdmljOZzBayfCr/szdpTJsspy3OOzlJsiKVqiBSvBQDVaIYej0+/h5/hWU1y7KgzANGFHg+9sHnkz0ej4OmaWr/nKixKB+JhIYGB0cDgcAEQRBbRPEBnU4Her3eyXFcZ29fX2N7R0edhePKlUPfQ6Gdt1NTqyMjI/PBYHAyHo8vJRIJIPYNF4VhEUIWjUbjUKvVnNLF3l4Ul/wN972JzdtWNDH8foFSjF6ZqX9McRoTw6R+CTAA9jQ8CY45ChEAAAAASUVORK5CYII=';
const { wrapper, snippet, img } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
});

it('renders base64 animated gif image', () => {
const context = 'data:image/gif;base64,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';
const { wrapper, snippet, img } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
});

it('renders base64 x-icon image', () => {
const context = 'data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAAALCvr/zM96vMwOOnzLzXl8y804/MnLd7zBw3Z8wQN1/MeI9XzJSbU8yIiz/MgHszzHhvL8xYRtP8AAAAAPDnu/22X9v9NcvX/TXD1/0lr9P9FZvb/LEz0/4ia+f+Wpvr/ES/x/zFH+f8wPvj/Ljf4/yww+f8tKv//ExCy/zs57/poi/X/RF/y/0Vh8v9EXvH/KUXv/2R38////////////11r8f8ZKu3/Ljrt/ysw7P8nKez/Kif+/xQPtP8SAuluY3Xz/09x8/9FYvL/RGDx/y9L7/9XbvL/+fv+//v6//9OYPD/HzDu/y457v8rMe3/Ky35/yIe3f8LBpB4AAAAACkf6ulnivX/PVzy/0Rg8f9CW/H/JULv/z9S7/8/UvD/DSfs/zE/7/8uOO7/KzHt/ywt+/8RDanxAAAAAAAAAAAVBedTTFTu/09z9f9AW/H/MEzv/1Vq8v///////////0le8P8dL+7/Ljnt/y82/P8fHND/DgmcUgAAAAAAAAAAAAAAAEo+6MVqgfX/OVjy/yA97v9fdPP///////////9aa/H/Fyrt/zE99P8sMPD/EQukwQAAAAAAAAAAAAAAAAAAAABSR+chfX3x/3yW9/8/WPH/Y3f0////////////UWHx/xAj7f8rOvn/FxTF/wwBoiEAAAAAAAAAAAAAAAAAAAAAAAAAAE9D5Z+LmfT/aID1/4mX9v///////////3GA8/9BUfX/WF/v/0M7uJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRSOcMaGTp/3KK+f+Dk/b///////////+Gkvb/XGv5/1lW0f9XUcUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEg84FJzevD/hpz6////////////f4/7/1BX5v9NQ8FSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRSOAHWVHg1oCU9/+Lmfb/kZ32/15y+P9QSszWUUjJBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9E3TJvcej/b4r6/1t0/P9cX+L/UEfLMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATkbahXh96/9udOr/UEbPhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQSdhqUkvUeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAMADAADgBwAA4AcAAPAPAADwDwAA+B8AAPw/AAD+fwAA//8AAA==';
const { wrapper, snippet, img } = getInstance({
context: JSON.stringify(context),
className: 'test'
Expand Down Expand Up @@ -124,13 +169,13 @@ describe('<TestContext />', () => {
title: 'sample context',
value: 'http://test.url.com/testimage.png'
};
const { wrapper, snippet, img } = getInstance({
const { wrapper, snippet, imgLink } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(0);
expect(img).to.have.lengthOf(1);
expect(imgLink).to.have.lengthOf(1);
});

it('renders object value', () => {
Expand Down Expand Up @@ -160,13 +205,13 @@ describe('<TestContext />', () => {
value: { testing: true }
}
];
const { wrapper, snippet, img } = getInstance({
const { wrapper, snippet, imgLink } = getInstance({
context: JSON.stringify(context),
className: 'test'
});
expect(wrapper).to.have.className('test');
expect(snippet).to.have.lengthOf(1);
expect(img).to.have.lengthOf(1);
expect(imgLink).to.have.lengthOf(1);
});
});
});

0 comments on commit 4278e4c

Please sign in to comment.