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

Commit

Permalink
Merge pull request #3244 from matrix-org/bwindels/diffhtmledits
Browse files Browse the repository at this point in the history
Show diff for formatted messages in the edit history
  • Loading branch information
bwindels authored Jul 24, 2019
2 parents e736904 + 3753e52 commit ac31b4b
Show file tree
Hide file tree
Showing 7 changed files with 345 additions and 45 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"classnames": "^2.1.2",
"commonmark": "^0.28.1",
"counterpart": "^0.18.0",
"diff-dom": "^4.1.3",
"diff-match-patch": "^1.0.4",
"emojibase-data": "^4.0.0",
"emojibase-regex": "^3.0.0",
Expand Down
4 changes: 2 additions & 2 deletions res/css/views/dialogs/_MessageEditHistoryDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ limitations under the License.
padding: 0px 2px;
}

span.mx_EditHistoryMessage_deletion {
.mx_EditHistoryMessage_deletion {
color: rgb(255, 76, 85);
background-color: rgba(255, 76, 85, 0.1);
}

span.mx_EditHistoryMessage_insertion {
.mx_EditHistoryMessage_insertion {
color: rgb(26, 169, 123);
background-color: rgba(26, 169, 123, 0.1);
}
Expand Down
37 changes: 36 additions & 1 deletion src/HtmlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ export function bodyToHtml(content, highlights, opts={}) {
// their username
(
content.formatted_body == undefined ||
!content.formatted_body.includes("https://matrix.to/")
!content.formatted_body.includes("https://matrix.to/")
);
}

Expand Down Expand Up @@ -513,3 +513,38 @@ export function linkifyElement(element, options = linkifyMatrix.options) {
export function linkifyAndSanitizeHtml(dirtyHtml) {
return sanitizeHtml(linkifyString(dirtyHtml), sanitizeHtmlParams);
}

/**
* Returns if a node is a block element or not.
* Only takes html nodes into account that are allowed in matrix messages.
*
* @param {Node} node
* @returns {bool}
*/
export function checkBlockNode(node) {
switch (node.nodeName) {
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
case "PRE":
case "BLOCKQUOTE":
case "DIV":
case "P":
case "UL":
case "OL":
case "LI":
case "HR":
case "TABLE":
case "THEAD":
case "TBODY":
case "TR":
case "TH":
case "TD":
return true;
default:
return false;
}
}
27 changes: 3 additions & 24 deletions src/components/views/messages/EditHistoryMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
import * as HtmlUtils from '../../../HtmlUtils';
import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils';
import {formatTime} from '../../../DateUtils';
import {MatrixEvent} from 'matrix-js-sdk';
import {pillifyLinks} from '../../../utils/pillify';
Expand All @@ -25,18 +26,12 @@ import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import Modal from '../../../Modal';
import classNames from 'classnames';
import DiffMatchPatch from 'diff-match-patch';

function getReplacedContent(event) {
const originalContent = event.getOriginalContent();
return originalContent["m.new_content"] || originalContent;
}

function isPlainMessage(event) {
const content = getReplacedContent(event);
return content.msgtype === "m.text" && !content.format;
}

export default class EditHistoryMessage extends React.PureComponent {
static propTypes = {
// the message event being edited
Expand Down Expand Up @@ -128,22 +123,6 @@ export default class EditHistoryMessage extends React.PureComponent {
);
}

_renderBodyDiff(oldBody, newBody) {
const dpm = new DiffMatchPatch();
const diff = dpm.diff_main(oldBody, newBody);
dpm.diff_cleanupSemantic(diff);
return diff.map(([modifier, text], i) => {
// not using del and ins tags here as del is used for strikethrough
if (modifier < 0) {
return (<span className="mx_EditHistoryMessage_deletion" key={i}>{text}</span>);
} else if (modifier > 0) {
return (<span className="mx_EditHistoryMessage_insertion" key={i}>{text}</span>);
} else {
return text;
}
});
}

render() {
const {mxEvent} = this.props;
const content = getReplacedContent(mxEvent);
Expand All @@ -153,8 +132,8 @@ export default class EditHistoryMessage extends React.PureComponent {
contentContainer = <UnknownBody mxEvent={this.props.mxEvent} />;
} else {
let contentElements;
if (isPlainMessage(mxEvent) && this.props.previousEdit && isPlainMessage(this.props.previousEdit)) {
contentElements = this._renderBodyDiff(getReplacedContent(this.props.previousEdit).body, content.body);
if (this.props.previousEdit) {
contentElements = editBodyDiffToHtml(getReplacedContent(this.props.previousEdit), content);
} else {
contentElements = HtmlUtils.bodyToHtml(content, null, {stripReplyFallback: true});
}
Expand Down
16 changes: 1 addition & 15 deletions src/editor/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.

import { MATRIXTO_URL_PATTERN } from '../linkify-matrix';
import { walkDOMDepthFirst } from "./dom";
import { checkBlockNode } from "../HtmlUtils";

const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN);

Expand Down Expand Up @@ -118,21 +119,6 @@ function checkDecendInto(node) {
}
}

function checkBlockNode(node) {
switch (node.nodeName) {
case "PRE":
case "BLOCKQUOTE":
case "DIV":
case "P":
case "UL":
case "OL":
case "LI":
return true;
default:
return false;
}
}

function checkIgnored(n) {
if (n.nodeType === Node.TEXT_NODE) {
// riot adds \n text nodes in a lot of places,
Expand Down
Loading

0 comments on commit ac31b4b

Please sign in to comment.