Added MarkdownImage component (#6774)
* Added MarkdownImage component * Fixed unit tests
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
0f69920342
Коммит
2dea567dcf
19
webapp/components/markdown_image.jsx
Обычный файл
19
webapp/components/markdown_image.jsx
Обычный файл
@@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import React, {PureComponent} from 'react';
|
||||||
|
|
||||||
|
import {postListScrollChange} from 'actions/global_actions.jsx';
|
||||||
|
|
||||||
|
export default class MarkdownImage extends PureComponent {
|
||||||
|
handleLoad = () => {
|
||||||
|
postListScrollChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const props = {...this.props};
|
||||||
|
props.onLoad = this.handleLoad;
|
||||||
|
|
||||||
|
return <img {...props}/>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import React from 'react';
|
|||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import AtMention from 'components/at_mention';
|
import AtMention from 'components/at_mention';
|
||||||
|
import MarkdownImage from 'components/markdown_image';
|
||||||
|
|
||||||
import store from 'stores/redux_store.jsx';
|
import store from 'stores/redux_store.jsx';
|
||||||
|
|
||||||
@@ -113,6 +114,22 @@ export default class PostMessageView extends React.PureComponent {
|
|||||||
return <AtMention mentionName={mentionName}/>;
|
return <AtMention mentionName={mentionName}/>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
shouldProcessNode: (node) => node.type === 'tag' && node.name === 'img',
|
||||||
|
processNode: (node) => {
|
||||||
|
const {
|
||||||
|
class: className,
|
||||||
|
...attribs
|
||||||
|
} = node.attribs;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MarkdownImage
|
||||||
|
className={className}
|
||||||
|
{...attribs}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
shouldProcessNode: () => true,
|
shouldProcessNode: () => true,
|
||||||
processNode: processNodeDefinitions.processDefaultNode
|
processNode: processNodeDefinitions.processDefaultNode
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('Markdown.Imgs', function() {
|
|||||||
it('Inline mage', function(done) {
|
it('Inline mage', function(done) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
Markdown.format('').trim(),
|
Markdown.format('').trim(),
|
||||||
'<p><img src="/images/icon.png" alt="Mattermost" onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"></p>'
|
'<p><img src="/images/icon.png" alt="Mattermost" class="markdown-inline-img"></p>'
|
||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -18,7 +18,7 @@ describe('Markdown.Imgs', function() {
|
|||||||
it('Image with hover text', function(done) {
|
it('Image with hover text', function(done) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
Markdown.format('').trim(),
|
Markdown.format('').trim(),
|
||||||
'<p><img src="/images/icon.png" alt="Mattermost" title="Mattermost Icon" onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"></p>'
|
'<p><img src="/images/icon.png" alt="Mattermost" title="Mattermost Icon" class="markdown-inline-img"></p>'
|
||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -27,7 +27,7 @@ describe('Markdown.Imgs', function() {
|
|||||||
it('Image with link', function(done) {
|
it('Image with link', function(done) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
Markdown.format('[](https://github.com/mattermost/platform)').trim(),
|
Markdown.format('[](https://github.com/mattermost/platform)').trim(),
|
||||||
'<p><a class="theme markdown__link" href="https://github.com/mattermost/platform" rel="noreferrer" target="_blank"><img src="../../images/icon-76x76.png" alt="Mattermost" onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"></a></p>'
|
'<p><a class="theme markdown__link" href="https://github.com/mattermost/platform" rel="noreferrer" target="_blank"><img src="../../images/icon-76x76.png" alt="Mattermost" class="markdown-inline-img"></a></p>'
|
||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -36,7 +36,7 @@ describe('Markdown.Imgs', function() {
|
|||||||
it('Image with width and height', function(done) {
|
it('Image with width and height', function(done) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
Markdown.format('').trim(),
|
Markdown.format('').trim(),
|
||||||
'<p><img src="../../images/icon-76x76.png" alt="Mattermost" title="Mattermost Icon" width="50" height="76" onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"></p>'
|
'<p><img src="../../images/icon-76x76.png" alt="Mattermost" title="Mattermost Icon" width="50" height="76" class="markdown-inline-img"></p>'
|
||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -45,7 +45,7 @@ describe('Markdown.Imgs', function() {
|
|||||||
it('Image with width', function(done) {
|
it('Image with width', function(done) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
Markdown.format('').trim(),
|
Markdown.format('').trim(),
|
||||||
'<p><img src="../../images/icon-76x76.png" alt="Mattermost" title="Mattermost Icon" width="50" onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"></p>'
|
'<p><img src="../../images/icon-76x76.png" alt="Mattermost" title="Mattermost Icon" width="50" class="markdown-inline-img"></p>'
|
||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -4,29 +4,9 @@
|
|||||||
import * as TextFormatting from './text_formatting.jsx';
|
import * as TextFormatting from './text_formatting.jsx';
|
||||||
import * as SyntaxHighlighting from './syntax_highlighting.jsx';
|
import * as SyntaxHighlighting from './syntax_highlighting.jsx';
|
||||||
|
|
||||||
import {postListScrollChange} from 'actions/global_actions.jsx';
|
|
||||||
|
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
import katex from 'katex';
|
import katex from 'katex';
|
||||||
|
|
||||||
function markdownImageLoaded(image) {
|
|
||||||
if (image.hasAttribute('height') && image.attributes.height.value !== 'auto') {
|
|
||||||
const maxHeight = parseInt(global.getComputedStyle(image).maxHeight, 10);
|
|
||||||
|
|
||||||
if (image.attributes.height.value > maxHeight) {
|
|
||||||
image.style.height = maxHeight + 'px';
|
|
||||||
image.style.width = ((maxHeight * image.attributes.width.value) / image.attributes.height.value) + 'px';
|
|
||||||
} else {
|
|
||||||
image.style.height = image.attributes.height.value + 'px';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
image.style.height = 'auto';
|
|
||||||
}
|
|
||||||
|
|
||||||
postListScrollChange();
|
|
||||||
}
|
|
||||||
global.markdownImageLoaded = markdownImageLoaded;
|
|
||||||
|
|
||||||
class MattermostMarkdownRenderer extends marked.Renderer {
|
class MattermostMarkdownRenderer extends marked.Renderer {
|
||||||
constructor(options, formattingOptions = {}) {
|
constructor(options, formattingOptions = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
@@ -155,7 +135,7 @@ class MattermostMarkdownRenderer extends marked.Renderer {
|
|||||||
if (dimensions.length > 1) {
|
if (dimensions.length > 1) {
|
||||||
out += ' height="' + dimensions[1] + '"';
|
out += ' height="' + dimensions[1] + '"';
|
||||||
}
|
}
|
||||||
out += ' onload="window.markdownImageLoaded(this)" onerror="window.markdownImageLoaded(this)" class="markdown-inline-img"';
|
out += ' class="markdown-inline-img"';
|
||||||
out += this.options.xhtml ? '/>' : '>';
|
out += this.options.xhtml ? '/>' : '>';
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user