diff --git a/src/skins/vector/views/molecules/MNoticeTile.js b/src/skins/vector/views/molecules/MNoticeTile.js index e9ca85eab2..d173c728fc 100644 --- a/src/skins/vector/views/molecules/MNoticeTile.js +++ b/src/skins/vector/views/molecules/MNoticeTile.js @@ -35,43 +35,46 @@ module.exports = React.createClass({ // 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); - } + var originalBody = content.body; 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") { + + // XXX: rather than searching for the search term in the body, + // we should be looking at the match delimiters returned by the FTS engine + if (content.format === "org.matrix.custom.html") { + var safeBody = sanitizeHtml(content.formatted_body, sanitizeHtmlParams); + var safeSearchTerm = sanitizeHtml(this.props.searchTerm, sanitizeHtmlParams); + while ((offset = safeBody.indexOf(safeSearchTerm, lastOffset)) >= 0) { // 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 or whatever will break the HTML badly. - bodyList.push(); - bodyList.push(); + bodyList.push(); + bodyList.push(); + lastOffset = offset + safeSearchTerm.length; } - else { - bodyList.push({ body.substring(lastOffset, offset) }); - bodyList.push({ this.props.searchTerm }); - } - lastOffset = offset + this.props.searchTerm.length; - } - if (content.format === "org.matrix.custom.html") { - bodyList.push(); + bodyList.push(); } else { - bodyList.push({ body.substring(lastOffset) }); + while ((offset = originalBody.indexOf(this.props.searchTerm, lastOffset)) >= 0) { + bodyList.push({ originalBody.substring(lastOffset, offset) }); + bodyList.push({ this.props.searchTerm }); + lastOffset = offset + this.props.searchTerm.length; + } + bodyList.push({ originalBody.substring(lastOffset) }); } body = bodyList; } else { if (content.format === "org.matrix.custom.html") { - body = ; + var safeBody = sanitizeHtml(content.formatted_body, sanitizeHtmlParams); + body = ; + } + else { + body = originalBody; } } diff --git a/src/skins/vector/views/molecules/MTextTile.js b/src/skins/vector/views/molecules/MTextTile.js index 6e04088eb8..626ee5b907 100644 --- a/src/skins/vector/views/molecules/MTextTile.js +++ b/src/skins/vector/views/molecules/MTextTile.js @@ -32,45 +32,49 @@ module.exports = React.createClass({ displayName: 'MTextTile', mixins: [MTextTileController], + // 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); - } + var originalBody = content.body; 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") { + + // XXX: rather than searching for the search term in the body, + // we should be looking at the match delimiters returned by the FTS engine + if (content.format === "org.matrix.custom.html") { + var safeBody = sanitizeHtml(content.formatted_body, sanitizeHtmlParams); + var safeSearchTerm = sanitizeHtml(this.props.searchTerm, sanitizeHtmlParams); + while ((offset = safeBody.indexOf(safeSearchTerm, lastOffset)) >= 0) { // 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 or whatever will break the HTML badly. - bodyList.push(); - bodyList.push(); + bodyList.push(); + bodyList.push(); + lastOffset = offset + safeSearchTerm.length; } - else { - bodyList.push({ body.substring(lastOffset, offset) }); - bodyList.push({ this.props.searchTerm }); - } - lastOffset = offset + this.props.searchTerm.length; - } - if (content.format === "org.matrix.custom.html") { - bodyList.push(); + bodyList.push(); } else { - bodyList.push({ body.substring(lastOffset) }); + while ((offset = originalBody.indexOf(this.props.searchTerm, lastOffset)) >= 0) { + bodyList.push({ originalBody.substring(lastOffset, offset) }); + bodyList.push({ this.props.searchTerm }); + lastOffset = offset + this.props.searchTerm.length; + } + bodyList.push({ originalBody.substring(lastOffset) }); } body = bodyList; } else { if (content.format === "org.matrix.custom.html") { - body = ; + var safeBody = sanitizeHtml(content.formatted_body, sanitizeHtmlParams); + body = ; + } + else { + body = originalBody; } }