Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Replace <p>s with <br/>s consistently
Browse files Browse the repository at this point in the history
Also, allow newlines in /commands.
Fixes element-hq/element-web#2114, element-hq/element-web#2165.
  • Loading branch information
aviraldg committed Sep 16, 2016
1 parent 2b9258d commit 6befb09
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 69 deletions.
132 changes: 76 additions & 56 deletions src/HtmlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,30 @@ export function unicodeToImage(str) {
});

return str;
};
}

export function stripParagraphs(html: string): string {
const contentDiv = document.createElement('div');
contentDiv.innerHTML = html;

if (contentDiv.children.length === 0) {
return contentDiv.innerHTML;
}

let contentHTML = "";
for (let i=0; i<contentDiv.children.length; i++) {
const element = contentDiv.children[i];
if (element.tagName.toLowerCase() === 'p') {
contentHTML += element.innerHTML + '<br />';
} else {
const temp = document.createElement('div');
temp.appendChild(element.cloneNode(true));
contentHTML += temp.innerHTML;
}
}

return contentHTML;
}

var sanitizeHtmlParams = {
allowedTags: [
Expand Down Expand Up @@ -153,8 +176,8 @@ class BaseHighlighter {
}

// handle postamble
if (lastOffset != safeSnippet.length) {
var subSnippet = safeSnippet.substring(lastOffset, undefined);
if (lastOffset !== safeSnippet.length) {
subSnippet = safeSnippet.substring(lastOffset, undefined);
nodes = nodes.concat(this._applySubHighlights(subSnippet, safeHighlights));
}
return nodes;
Expand Down Expand Up @@ -219,15 +242,14 @@ class TextHighlighter extends BaseHighlighter {
</span>;

if (highlight && this.highlightLink) {
node = <a key={key} href={this.highlightLink}>{node}</a>
node = <a key={key} href={this.highlightLink}>{node}</a>;
}

return node;
}
}


module.exports = {
/* turn a matrix event body into html
*
* content: 'content' of the MatrixEvent
Expand All @@ -236,59 +258,57 @@ module.exports = {
*
* opts.highlightLink: optional href to add to highlighted words
*/
bodyToHtml: function(content, highlights, opts) {
opts = opts || {};

var isHtml = (content.format === "org.matrix.custom.html");
let body = isHtml ? content.formatted_body : escape(content.body);

var safeBody;
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
// are interrupted by HTML tags (not that we did before) - e.g. foo<span/>bar won't get highlighted
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
try {
if (highlights && highlights.length > 0) {
var highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
var safeHighlights = highlights.map(function(highlight) {
return sanitizeHtml(highlight, sanitizeHtmlParams);
});
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeHtmlParams structure.
sanitizeHtmlParams.textFilter = function(safeText) {
return highlighter.applyHighlights(safeText, safeHighlights).join('');
};
}
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
safeBody = unicodeToImage(safeBody);
}
finally {
delete sanitizeHtmlParams.textFilter;
export function bodyToHtml(content, highlights, opts) {
opts = opts || {};

var isHtml = (content.format === "org.matrix.custom.html");
let body = isHtml ? content.formatted_body : escape(content.body);

var safeBody;
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
// are interrupted by HTML tags (not that we did before) - e.g. foo<span/>bar won't get highlighted
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
try {
if (highlights && highlights.length > 0) {
var highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
var safeHighlights = highlights.map(function(highlight) {
return sanitizeHtml(highlight, sanitizeHtmlParams);
});
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeHtmlParams structure.
sanitizeHtmlParams.textFilter = function(safeText) {
return highlighter.applyHighlights(safeText, safeHighlights).join('');
};
}
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
safeBody = unicodeToImage(safeBody);
}
finally {
delete sanitizeHtmlParams.textFilter;
}

EMOJI_REGEX.lastIndex = 0;
let contentBodyTrimmed = content.body.trim();
let match = EMOJI_REGEX.exec(contentBodyTrimmed);
let emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;

const className = classNames({
'mx_EventTile_body': true,
'mx_EventTile_bigEmoji': emojiBody,
'markdown-body': isHtml,
});
return <span className={className} dangerouslySetInnerHTML={{ __html: safeBody }} />;
},
EMOJI_REGEX.lastIndex = 0;
let contentBodyTrimmed = content.body.trim();
let match = EMOJI_REGEX.exec(contentBodyTrimmed);
let emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;

highlightDom: function(element) {
var blocks = element.getElementsByTagName("code");
for (var i = 0; i < blocks.length; i++) {
highlight.highlightBlock(blocks[i]);
}
},
const className = classNames({
'mx_EventTile_body': true,
'mx_EventTile_bigEmoji': emojiBody,
'markdown-body': isHtml,
});
return <span className={className} dangerouslySetInnerHTML={{ __html: safeBody }} />;
}

emojifyText: function(text) {
return {
__html: unicodeToImage(escape(text)),
};
},
};
export function highlightDom(element) {
var blocks = element.getElementsByTagName("code");
for (var i = 0; i < blocks.length; i++) {
highlight.highlightBlock(blocks[i]);
}
}

export function emojifyText(text) {
return {
__html: unicodeToImage(escape(text)),
};
}
2 changes: 1 addition & 1 deletion src/SlashCommands.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ module.exports = {
// IRC-style commands
input = input.replace(/\s+$/, "");
if (input[0] === "/" && input[1] !== "/") {
var bits = input.match(/^(\S+?)( +(.*))?$/);
var bits = input.match(/^(\S+?)( +((.|\n)*))?$/);
var cmd, args;
if (bits) {
cmd = bits[1].substring(1).toLowerCase();
Expand Down
18 changes: 6 additions & 12 deletions src/components/views/rooms/MessageComposerInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import KeyCode from '../../../KeyCode';
import UserSettingsStore from '../../../UserSettingsStore';

import * as RichText from '../../../RichText';
import * as HtmlUtils from '../../../HtmlUtils';
import Autocomplete from './Autocomplete';
import {Completion} from "../../../autocomplete/Autocompleter";

Expand All @@ -63,18 +64,9 @@ function stateToMarkdown(state) {
''); // this is *not* a zero width space, trust me :)
}


// FIXME Breaks markdown with multiple paragraphs, since it only strips first and last <p>
function mdownToHtml(mdown: string): string {
let html = marked(mdown) || "";
html = html.trim();
// strip start and end <p> tags else you get 'orrible spacing
if (html.indexOf("<p>") === 0) {
html = html.substring("<p>".length);
}
if (html.lastIndexOf("</p>") === (html.length - "</p>".length)) {
html = html.substring(0, html.length - "</p>".length);
}
return html;
}

Expand Down Expand Up @@ -547,6 +539,8 @@ export default class MessageComposerInput extends React.Component {
contentHTML = mdownToHtml(contentText);
}

contentHTML = HtmlUtils.stripParagraphs(contentHTML);

let sendFn = this.client.sendHtmlMessage;

if (contentText.startsWith('/me')) {
Expand All @@ -561,16 +555,16 @@ export default class MessageComposerInput extends React.Component {

sendMessagePromise.then(() => {
dis.dispatch({
action: 'message_sent'
action: 'message_sent',
});
}, () => {
dis.dispatch({
action: 'message_send_failed'
action: 'message_send_failed',
});
});

this.setState({
editorState: this.createEditorState()
editorState: this.createEditorState(),
});

return true;
Expand Down

0 comments on commit 6befb09

Please sign in to comment.