display search results correct; support HTML markup

This commit is contained in:
Matthew Hodgson
2015-10-30 04:10:37 +00:00
parent d315e4afcd
commit fdfa0cbd0e
7 changed files with 116 additions and 7 deletions

View File

@@ -17,18 +17,67 @@ limitations under the License.
'use strict';
var React = require('react');
var sanitizeHtml = require('sanitize-html');
var MNoticeTileController = require('matrix-react-sdk/lib/controllers/molecules/MNoticeTile')
var allowedAttributes = sanitizeHtml.defaults.allowedAttributes;
allowedAttributes['font'] = ['color'];
var sanitizeHtmlParams = {
allowedTags: sanitizeHtml.defaults.allowedTags.concat([ 'font' ]),
allowedAttributes: allowedAttributes,
};
module.exports = React.createClass({
displayName: 'MNoticeTile',
mixins: [MNoticeTileController],
// FIXME: this entire class is copy-pasted from MTextTile :(
render: function() {
var content = this.props.mxEvent.getContent();
var body = content.body;
if (content.format === "org.matrix.custom.html") {
body = sanitizeHtml(content.formatted_body, sanitizeHtmlParams);
}
if (this.props.searchTerm) {
var lastOffset = 0;
var bodyList = [];
var k = 0;
var offset;
// XXX: this probably doesn't handle stemming very well.
while ((offset = body.indexOf(this.props.searchTerm, lastOffset)) >= 0) {
if (content.format === "org.matrix.custom.html") {
// FIXME: we need to apply the search highlighting to only the text elements of HTML, which means
// hooking into the sanitizer parser rather than treating it as a string. Otherwise
// the act of highlighting a <b/> or whatever will break the HTML badly.
bodyList.push(<span key={ k++ } dangerouslySetInnerHTML={{ __html: body.substring(lastOffset, offset) }} />);
bodyList.push(<span key={ k++ } dangerouslySetInnerHTML={{ __html: this.props.searchTerm }} className="mx_MessageTile_searchHighlight" />);
}
else {
bodyList.push(<span key={ k++ } >{ body.substring(lastOffset, offset) }</span>);
bodyList.push(<span key={ k++ } className="mx_MessageTile_searchHighlight">{ this.props.searchTerm }</span>);
}
lastOffset = offset + this.props.searchTerm.length;
}
if (content.format === "org.matrix.custom.html") {
bodyList.push(<span key={ k++ } dangerouslySetInnerHTML={{ __html: body.substring(lastOffset) }} />);
}
else {
bodyList.push(<span key={ k++ }>{ body.substring(lastOffset) }</span>);
}
body = bodyList;
}
else {
if (content.format === "org.matrix.custom.html") {
body = <span dangerouslySetInnerHTML={{ __html: body }} />;
}
}
return (
<span ref="content" className="mx_MNoticeTile mx_MessageTile_content">
{content.body}
{ body }
</span>
);
},