Skip to content

Commit

Permalink
Replace lodash templates with static react renderer for field formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
legrego committed Apr 1, 2021
1 parent 6238ef7 commit 0eb8790
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 43 deletions.
14 changes: 7 additions & 7 deletions src/plugins/data/common/field_formats/converters/color.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ describe('Color Format', () => {

expect(colorer.convert(99, HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>99</span>');
expect(colorer.convert(100, HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">100</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">100</span></span>'
);
expect(colorer.convert(150, HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">150</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">150</span></span>'
);
expect(colorer.convert(151, HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>151</span>');
});
Expand Down Expand Up @@ -74,22 +74,22 @@ describe('Color Format', () => {

expect(converter('B', HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>B</span>');
expect(converter('AAA', HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">AAA</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">AAA</span></span>'
);
expect(converter('AB', HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">AB</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">AB</span></span>'
);
expect(converter('a', HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>a</span>');

expect(converter('B', HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>B</span>');
expect(converter('AAA', HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">AAA</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">AAA</span></span>'
);
expect(converter('AB', HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">AB</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">AB</span></span>'
);
expect(converter('AB <', HTML_CONTEXT_TYPE)).toBe(
'<span ng-non-bindable><span style="color: blue;background-color: yellow;">AB &lt;</span></span>'
'<span ng-non-bindable><span style="color:blue;background-color:yellow">AB &lt;</span></span>'
);
expect(converter('a', HTML_CONTEXT_TYPE)).toBe('<span ng-non-bindable>a</span>');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
*/

import { i18n } from '@kbn/i18n';
import { findLast, cloneDeep, template, escape } from 'lodash';
import React from 'react';
import ReactDOM from 'react-dom/server';
import { findLast, cloneDeep, escape } from 'lodash';
import { KBN_FIELD_TYPES } from '../../kbn_field_types/types';
import { FieldFormat } from '../field_format';
import { HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types';
import { asPrettyString } from '../utils';
import { DEFAULT_CONVERTER_COLOR } from '../constants/color_default';

const convertTemplate = template('<span style="<%- style %>"><%- val %></span>');

export class ColorFormat extends FieldFormat {
static id = FIELD_FORMAT_IDS.COLOR;
static title = i18n.translate('data.fieldFormats.color.title', {
Expand Down Expand Up @@ -51,11 +51,18 @@ export class ColorFormat extends FieldFormat {

htmlConvert: HtmlContextTypeConvert = (val) => {
const color = this.findColorRuleForVal(val) as typeof DEFAULT_CONVERTER_COLOR;
if (!color) return escape(asPrettyString(val));

let style = '';
if (color.text) style += `color: ${color.text};`;
if (color.background) style += `background-color: ${color.background};`;
return convertTemplate({ val, style });
const displayVal = escape(asPrettyString(val));
if (!color) return displayVal;

return ReactDOM.renderToStaticMarkup(
<span
style={{
color: color.text,
backgroundColor: color.background,
}}
dangerouslySetInnerHTML={{ __html: displayVal }} // eslint-disable-line react/no-danger
/>
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,34 @@
* Side Public License, v 1.
*/

import { template, escape, keys } from 'lodash';
import React, { Fragment } from 'react';
import ReactDOM from 'react-dom/server';
import { escape, keys } from 'lodash';
import { shortenDottedString } from '../../utils';
import { KBN_FIELD_TYPES } from '../../kbn_field_types/types';
import { FieldFormat } from '../field_format';
import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types';
import { UI_SETTINGS } from '../../constants';

/**
* Remove all of the whitespace between html tags
* so that inline elements don't have extra spaces.
*
* If you have inline elements (span, a, em, etc.) and any
* amount of whitespace around them in your markup, then the
* browser will push them apart. This is ugly in certain
* scenarios and is only fixed by removing the whitespace
* from the html in the first place (or ugly css hacks).
*
* @param {string} html - the html to modify
* @return {string} - modified html
*/
function noWhiteSpace(html: string) {
const TAGS_WITH_WS = />\s+</g;
return html.replace(TAGS_WITH_WS, '><');
interface Props {
defPairs: Array<[string, string]>;
}

const templateHtml = `
<dl class="source truncate-by-height">
<% defPairs.forEach(function (def) { %>
<dt><%- def[0] %>:</dt>
<dd><%= def[1] %></dd>
<%= ' ' %>
<% }); %>
</dl>`;
const doTemplate = template(noWhiteSpace(templateHtml));
const TemplateComponent = ({ defPairs }: Props) => {
return (
<dl className={'source truncate-by-height'}>
{defPairs.map((pair, idx) => (
<Fragment key={idx}>
<dt
dangerouslySetInnerHTML={{ __html: `${pair[0]}:` }} // eslint-disable-line react/no-danger
/>
<dd
dangerouslySetInnerHTML={{ __html: `${pair[1]}` }} // eslint-disable-line react/no-danger
/>{' '}
</Fragment>
))}
</dl>
);
};

export class SourceFormat extends FieldFormat {
static id = FIELD_FORMAT_IDS._SOURCE;
Expand Down Expand Up @@ -70,6 +64,8 @@ export class SourceFormat extends FieldFormat {
pairs.push([newField, val]);
}, []);

return doTemplate({ defPairs: highlightPairs.concat(sourcePairs) });
return ReactDOM.renderToStaticMarkup(
<TemplateComponent defPairs={highlightPairs.concat(sourcePairs)} />
);
};
}

0 comments on commit 0eb8790

Please sign in to comment.