2016-01-05 08:46:52 +08:00
|
|
|
/*
|
|
|
|
Copyright 2015 OpenMarket Ltd
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2016-01-06 10:29:08 +08:00
|
|
|
// The colour keys to be replaced as referred to in SVGs
|
2016-01-05 08:46:52 +08:00
|
|
|
var keyRgb = [
|
2016-01-06 10:29:08 +08:00
|
|
|
"rgb(118, 207, 166)", // Vector Green
|
|
|
|
"rgb(234, 245, 240)", // Vector Light Green
|
|
|
|
"rgba(118, 207, 166, 0.2)", // BottomLeftMenu overlay (20% Vector Green)
|
2016-01-05 08:46:52 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
// Some algebra workings for calculating the tint % of Vector Green & Light Green
|
|
|
|
// x * 118 + (1 - x) * 255 = 234
|
|
|
|
// x * 118 + 255 - 255 * x = 234
|
|
|
|
// x * 118 - x * 255 = 234 - 255
|
|
|
|
// (255 - 118) x = 255 - 234
|
|
|
|
// x = (255 - 234) / (255 - 118) = 0.16
|
|
|
|
|
2016-01-06 10:29:08 +08:00
|
|
|
// The colour keys to be replaced as referred to in SVGs
|
2016-01-05 08:46:52 +08:00
|
|
|
var keyHex = [
|
2016-01-06 10:29:08 +08:00
|
|
|
"#76CFA6", // Vector Green
|
|
|
|
"#EAF5F0", // Vector Light Green
|
|
|
|
"#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on Vector Light Green)
|
2016-01-05 11:34:52 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
// cache of our replacement colours
|
|
|
|
// defaults to our keys.
|
|
|
|
var colors = [
|
|
|
|
keyHex[0],
|
|
|
|
keyHex[1],
|
|
|
|
keyHex[2],
|
2016-01-05 08:46:52 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
var cssFixups = [
|
|
|
|
// {
|
|
|
|
// style: a style object that should be fixed up taken from a stylesheet
|
|
|
|
// attr: name of the attribute to be clobbered, e.g. 'color'
|
|
|
|
// index: ordinal of primary, secondary or tertiary
|
|
|
|
// }
|
|
|
|
];
|
|
|
|
|
|
|
|
// CSS attributes to be fixed up
|
|
|
|
var cssAttrs = [
|
|
|
|
"color",
|
|
|
|
"backgroundColor",
|
|
|
|
"borderColor",
|
|
|
|
];
|
|
|
|
|
|
|
|
var svgFixups = [
|
|
|
|
// {
|
|
|
|
// node: a SVG node that needs to be fixed up
|
|
|
|
// attr: name of the attribute to be clobbered, e.g. 'fill'
|
|
|
|
// index: ordinal of primary, secondary
|
|
|
|
// }
|
|
|
|
];
|
|
|
|
|
|
|
|
var svgAttrs = [
|
|
|
|
"fill",
|
|
|
|
"stroke",
|
|
|
|
];
|
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
var svgNodes = {};
|
|
|
|
|
2016-01-05 08:46:52 +08:00
|
|
|
var cached = false;
|
|
|
|
|
|
|
|
function calcCssFixups() {
|
|
|
|
for (var i = 0; i < document.styleSheets.length; i++) {
|
|
|
|
var ss = document.styleSheets[i];
|
|
|
|
for (var j = 0; j < ss.cssRules.length; j++) {
|
|
|
|
var rule = ss.cssRules[j];
|
2016-01-06 10:29:08 +08:00
|
|
|
if (!rule.style) continue;
|
2016-01-05 08:46:52 +08:00
|
|
|
for (var k = 0; k < cssAttrs.length; k++) {
|
|
|
|
var attr = cssAttrs[k];
|
|
|
|
for (var l = 0; l < keyRgb.length; l++) {
|
2016-01-06 10:29:08 +08:00
|
|
|
if (rule.style[attr] === keyRgb[l]) {
|
2016-01-05 08:46:52 +08:00
|
|
|
cssFixups.push({
|
|
|
|
style: rule.style,
|
|
|
|
attr: attr,
|
|
|
|
index: l,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
function calcSvgFixups(nodes) {
|
2016-01-06 10:11:07 +08:00
|
|
|
var svgs = nodes || document.getElementsByClassName("mx_TintableSvg");
|
2016-01-05 11:34:52 +08:00
|
|
|
var fixups = [];
|
2016-01-05 08:46:52 +08:00
|
|
|
for (var i = 0; i < svgs.length; i++) {
|
2016-01-05 11:34:52 +08:00
|
|
|
|
2016-01-05 08:46:52 +08:00
|
|
|
var svgDoc = svgs[i].contentDocument;
|
|
|
|
if (!svgDoc) continue;
|
|
|
|
var tags = svgDoc.getElementsByTagName("*");
|
|
|
|
for (var j = 0; j < tags.length; j++) {
|
|
|
|
var tag = tags[j];
|
|
|
|
for (var k = 0; k < svgAttrs.length; k++) {
|
|
|
|
var attr = svgAttrs[k];
|
|
|
|
for (var l = 0; l < keyHex.length; l++) {
|
|
|
|
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
|
2016-01-05 11:34:52 +08:00
|
|
|
fixups.push({
|
2016-01-05 08:46:52 +08:00
|
|
|
node: tag,
|
|
|
|
attr: attr,
|
|
|
|
index: l,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
return fixups;
|
|
|
|
}
|
2016-01-05 08:46:52 +08:00
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
function applyCssFixups() {
|
2016-01-05 08:46:52 +08:00
|
|
|
for (var i = 0; i < cssFixups.length; i++) {
|
|
|
|
var cssFixup = cssFixups[i];
|
|
|
|
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
function applySvgFixups(fixups) {
|
|
|
|
for (var i = 0; i < fixups.length; i++) {
|
|
|
|
var svgFixup = fixups[i];
|
2016-01-05 08:46:52 +08:00
|
|
|
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function hexToRgb(color) {
|
|
|
|
if (color[0] === '#') color = color.slice(1);
|
|
|
|
if (color.length === 3) {
|
|
|
|
color = color[0] + color[0] +
|
|
|
|
color[1] + color[1] +
|
|
|
|
color[2] + color[2];
|
|
|
|
}
|
|
|
|
var val = parseInt(color, 16);
|
|
|
|
var r = (val >> 16) & 255;
|
|
|
|
var g = (val >> 8) & 255;
|
|
|
|
var b = val & 255;
|
|
|
|
return [r, g, b];
|
|
|
|
}
|
|
|
|
|
|
|
|
function rgbToHex(rgb) {
|
|
|
|
var val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
|
|
|
return '#' + (0x1000000 + val).toString(16).slice(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
|
|
|
if (!cached) {
|
|
|
|
calcCssFixups();
|
2016-01-05 11:34:52 +08:00
|
|
|
svgFixups = calcSvgFixups();
|
2016-01-05 08:46:52 +08:00
|
|
|
cached = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!secondaryColor) {
|
|
|
|
var x = 0.16; // average weighting factor calculated from vector green & light green
|
|
|
|
var rgb = hexToRgb(primaryColor);
|
|
|
|
rgb[0] = x * rgb[0] + (1 - x) * 255;
|
|
|
|
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
|
|
|
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
|
|
|
secondaryColor = rgbToHex(rgb);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tertiaryColor) {
|
|
|
|
var x = 0.19;
|
|
|
|
var rgb1 = hexToRgb(primaryColor);
|
|
|
|
var rgb2 = hexToRgb(secondaryColor);
|
|
|
|
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
|
|
|
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
|
|
|
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
|
|
|
tertiaryColor = rgbToHex(rgb1);
|
|
|
|
}
|
|
|
|
|
2016-01-05 11:34:52 +08:00
|
|
|
colors = [primaryColor, secondaryColor, tertiaryColor];
|
|
|
|
|
2016-01-05 08:46:52 +08:00
|
|
|
// go through manually fixing up the stylesheets.
|
2016-01-05 11:34:52 +08:00
|
|
|
applyCssFixups();
|
2016-01-05 08:46:52 +08:00
|
|
|
|
|
|
|
// 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.
|
2016-01-05 11:34:52 +08:00
|
|
|
applySvgFixups(svgFixups);
|
2016-01-06 10:29:08 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
tintSvg: function(svg) {
|
|
|
|
// 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([ svg ]);
|
|
|
|
if (fixups.length) {
|
|
|
|
svgFixups = svgFixups.concat(fixups); // XXX: this leaks fixups
|
|
|
|
applySvgFixups(fixups);
|
|
|
|
}
|
|
|
|
},
|
2016-01-05 08:46:52 +08:00
|
|
|
};
|