From 001dc8612b992ef4ead906e8563eddeb7046d6cd Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 5 Jan 2016 03:34:52 +0000 Subject: [PATCH] support fixing up dynamically loaded SVGs --- src/SlashCommands.js | 1 + src/Tinter.js | 59 ++++++++++++++----- src/components/structures/RoomView.js | 12 ++-- src/components/views/messages/MFileBody.js | 7 ++- src/components/views/messages/MImageBody.js | 2 +- src/components/views/rooms/MessageComposer.js | 10 +++- src/components/views/rooms/RoomHeader.js | 8 ++- 7 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index d8588170b7..4b915d00ce 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -45,6 +45,7 @@ var commands = { tint: function(room_id, args) { Tinter.tint(args); + return success(); }, encrypt: function(room_id, args) { diff --git a/src/Tinter.js b/src/Tinter.js index be81abd9c2..b2d7b3347a 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -14,6 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +var dis = require('./dispatcher'); + +var registered = false; +if (!registered) { + dis.register(_onAction); +} + var keyRgb = [ "rgb(118, 207, 166)", "rgb(234, 245, 240)", @@ -30,6 +37,15 @@ var keyRgb = [ var keyHex = [ "#76CFA6", "#EAF5F0", + "#D3EFE1", +]; + +// cache of our replacement colours +// defaults to our keys. +var colors = [ + keyHex[0], + keyHex[1], + keyHex[2], ]; var cssFixups = [ @@ -60,6 +76,8 @@ var svgAttrs = [ "stroke", ]; +var svgNodes = {}; + var cached = false; function calcCssFixups() { @@ -83,9 +101,11 @@ function calcCssFixups() { } } -function calcSvgFixups() { - var svgs = document.getElementsByClassName("mx_Svg"); +function calcSvgFixups(nodes) { + var svgs = nodes || document.getElementsByClassName("mx_Svg"); + var fixups = []; for (var i = 0; i < svgs.length; i++) { + var svgDoc = svgs[i].contentDocument; if (!svgDoc) continue; var tags = svgDoc.getElementsByTagName("*"); @@ -95,7 +115,7 @@ function calcSvgFixups() { var attr = svgAttrs[k]; for (var l = 0; l < keyHex.length; l++) { if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) { - svgFixups.push({ + fixups.push({ node: tag, attr: attr, index: l, @@ -105,26 +125,35 @@ function calcSvgFixups() { } } } + + return fixups; } -function applyCssFixups(primaryColor, secondaryColor, tertiaryColor) { - var colors = [primaryColor, secondaryColor, tertiaryColor]; - +function applyCssFixups() { for (var i = 0; i < cssFixups.length; i++) { var cssFixup = cssFixups[i]; cssFixup.style[cssFixup.attr] = colors[cssFixup.index]; } } -function applySvgFixups(primaryColor, secondaryColor, tertiaryColor) { - var colors = [primaryColor, secondaryColor, tertiaryColor]; - - for (var i = 0; i < svgFixups.length; i++) { - var svgFixup = svgFixups[i]; +function applySvgFixups(fixups) { + for (var i = 0; i < fixups.length; i++) { + var svgFixup = fixups[i]; svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]); } } +function _onAction(payload) { + if (payload.action !== "svg_onload") return; + // XXX: we should probably faff around with toggling the visibility of the node to avoid flashing the wrong colour. + // (although this would result in an even worse flicker as the element redraws) + var fixups = calcSvgFixups([ payload.svg ]); + if (fixups.length) { + svgFixups = svgFixups.concat(fixups); // XXX: this leaks fixups + applySvgFixups(fixups); + } +} + function hexToRgb(color) { if (color[0] === '#') color = color.slice(1); if (color.length === 3) { @@ -148,7 +177,7 @@ module.exports = { tint: function(primaryColor, secondaryColor, tertiaryColor) { if (!cached) { calcCssFixups(); - calcSvgFixups(); + svgFixups = calcSvgFixups(); cached = true; } @@ -171,13 +200,15 @@ module.exports = { tertiaryColor = rgbToHex(rgb1); } + colors = [primaryColor, secondaryColor, tertiaryColor]; + // go through manually fixing up the stylesheets. - applyCssFixups(primaryColor, secondaryColor, tertiaryColor); + applyCssFixups(); // go through manually fixing up SVG colours. // we could do this by stylesheets, but keeping the stylesheets // updated would be a PITA, so just brute-force search for the // key colour; cache the element and apply. - applySvgFixups(primaryColor, secondaryColor, tertiaryColor); + applySvgFixups(svgFixups); } }; diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5dec8c6139..93d4b0dc2a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1093,6 +1093,10 @@ module.exports = React.createClass({ }); }, + onSvgLoad: function(event) { + dis.dispatch({ action: "svg_onload", svg: event.target }); + }, + render: function() { var RoomHeader = sdk.getComponent('rooms.RoomHeader'); var MessageComposer = sdk.getComponent('rooms.MessageComposer'); @@ -1194,7 +1198,7 @@ module.exports = React.createClass({
- + Auto-complete @@ -1268,7 +1272,7 @@ module.exports = React.createClass({ if (this.state.draggingFile) { fileDropTarget =
-
+
Drop File Here ; @@ -1306,7 +1310,7 @@ module.exports = React.createClass({ if (call.type === "video") { zoomButton = (
- + ); @@ -1338,7 +1342,7 @@ module.exports = React.createClass({ { videoMuteButton } { zoomButton } { statusBar } - + } diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 193cafe255..7d6cd3d557 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -19,6 +19,7 @@ limitations under the License. var React = require('react'); var filesize = require('filesize'); var MatrixClientPeg = require('../../../MatrixClientPeg'); +var dis = require("../../../dispatcher"); module.exports = React.createClass({ displayName: 'MFileBody', @@ -45,6 +46,10 @@ module.exports = React.createClass({ return linkText; }, + onSvgLoad: function(event) { + dis.dispatch({ action: "svg_onload", svg: event.target }); + }, + render: function() { var content = this.props.mxEvent.getContent(); var cli = MatrixClientPeg.get(); @@ -57,7 +62,7 @@ module.exports = React.createClass({
- + Download {text} diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 6afdddc307..520a36501c 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -118,7 +118,7 @@ module.exports = React.createClass({
- + Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" }) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 512b2eb109..8aa5513bcd 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -457,6 +457,10 @@ module.exports = React.createClass({ }); }, + onSvgLoad: function(event) { + dis.dispatch({ action: "svg_onload", svg: event.target }); + }, + render: function() { var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); var uploadInputStyle = {display: 'none'}; @@ -474,11 +478,11 @@ module.exports = React.createClass({ else { callButton =
- + videoCallButton =
- + } @@ -493,7 +497,7 @@ module.exports = React.createClass({