Consolidate the code copy button

Adding the code code button was done by manipulating the HTML of
the event body to add a span tag, then adding the onclick handler
after the thing was mounted. Apart from splitting the code between
two places, adding the span tag was, according to Chrome's
profiler, taking up quite a lot of CPU cycles (apparently as soon
as you set the innerHTML on a div). Instead, just build the whole
lot together after the component mounts.
This commit is contained in:
David Baker 2017-09-10 14:23:33 +01:00
parent e1aefd2119
commit 876257f4e2
2 changed files with 9 additions and 24 deletions

View file

@ -393,7 +393,6 @@ export function bodyToHtml(content, highlights, opts) {
}
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
safeBody = unicodeToImage(safeBody);
if (isHtml) safeBody = addCodeCopyButton(safeBody);
}
finally {
delete sanitizeHtmlParams.textFilter;
@ -412,23 +411,6 @@ export function bodyToHtml(content, highlights, opts) {
return <span className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" />;
}
function addCodeCopyButton(safeBody) {
// Adds 'copy' buttons to pre blocks
// Note that this only manipulates the markup to add the buttons:
// we need to add the event handlers once the nodes are in the DOM
// since we can't save functions in the markup.
// This is done in TextualBody
const el = document.createElement("div");
el.innerHTML = safeBody;
const codeBlocks = Array.from(el.getElementsByTagName("pre"));
codeBlocks.forEach(p => {
const button = document.createElement("span");
button.className = "mx_EventTile_copyButton";
p.appendChild(button);
});
return el.innerHTML;
}
export function emojifyText(text) {
return {
__html: unicodeToImage(escape(text)),

View file

@ -113,14 +113,17 @@ module.exports = React.createClass({
}
}, 10);
}
// add event handlers to the 'copy code' buttons
const buttons = ReactDOM.findDOMNode(this).getElementsByClassName("mx_EventTile_copyButton");
for (let i = 0; i < buttons.length; i++) {
buttons[i].onclick = (e) => {
const copyCode = buttons[i].parentNode.getElementsByTagName("code")[0];
// Add 'copy' buttons to pre blocks
ReactDOM.findDOMNode(this).querySelectorAll('.mx_EventTile_body pre').forEach((p) => {
const button = document.createElement("span");
button.className = "mx_EventTile_copyButton";
button.onclick = (e) => {
const copyCode = button.parentNode.getElementsByTagName("code")[0];
this.copyToClipboard(copyCode.textContent);
};
}
p.appendChild(button);
});
}
},