Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move highlight_html.js #45372

Merged
merged 9 commits into from
Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import _ from 'lodash';
import { getHighlightHtml } from '../../highlight/highlight_html';
import { getHighlightHtml } from '../../../../../../plugins/data/common/highlight/highlight_html';

const templateMatchRE = /{{([\s\S]+?)}}/g;
const whitelistUrlSchemes = ['http://', 'https://'];
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import { FieldFormatConvert, IFieldFormat, HtmlConventTypeConvert } from '../typ

// @ts-ignore
import { asPrettyString } from '../../../core_plugins/kibana/common/utils/as_pretty_string';
// @ts-ignore
import { getHighlightHtml } from '../../../core_plugins/kibana/common/highlight/highlight_html';
import { getHighlightHtml } from '../../../../plugins/data/common/highlight/highlight_html';

const CONTEXT_TYPE = 'html';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import { SearchRequestProvider } from '../fetch/request';
import { searchRequestQueue } from '../search_request_queue';
import { FetchSoonProvider } from '../fetch';
import { FieldWildcardProvider } from '../../field_wildcard';
import { getHighlightRequest } from '../../../../core_plugins/kibana/common/highlight';
import { getHighlightRequest } from '../../../../../plugins/data/common/highlight';

const FIELDS = [
'type',
Expand Down
124 changes: 124 additions & 0 deletions src/plugins/data/common/highlight/highlight_html.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you 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.
*/

import { highlightTags } from './highlight_tags';
import { htmlTags } from './html_tags';
import { getHighlightHtml } from './highlight_html';

describe('getHighlightHtml', function() {
const text =
'' +
'Bacon ipsum dolor amet pork loin pork cow pig beef chuck ground round shankle sirloin landjaeger kevin ' +
'venison sausage ribeye tongue. Chicken bacon ball tip pork. Brisket pork capicola spare ribs pastrami rump ' +
'sirloin, t-bone ham shoulder jerky turducken bresaola. Chicken cow beef picanha. Picanha hamburger alcatra ' +
'cupim. Salami capicola boudin pork belly shank picanha.';

test('should not modify text if highlight is empty', function() {
expect(getHighlightHtml(text, undefined)).toBe(text);
expect(getHighlightHtml(text, null)).toBe(text);
expect(getHighlightHtml(text, [])).toBe(text);
});

test('should preserve escaped text', function() {
const highlights = ['<foo>'];
const result = getHighlightHtml('&lt;foo&gt;', highlights);
expect(result.indexOf('<foo>')).toBe(-1);
expect(result.indexOf('&lt;foo&gt;')).toBeGreaterThan(-1);
});

test('should highlight a single result', function() {
const highlights = [
highlightTags.pre +
'hamburger' +
highlightTags.post +
' alcatra cupim. Salami capicola boudin pork belly shank picanha.',
];
const result = getHighlightHtml(text, highlights);
expect(result.indexOf(htmlTags.pre + 'hamburger' + htmlTags.post)).toBeGreaterThan(-1);
expect(result.split(htmlTags.pre + 'hamburger' + htmlTags.post).length).toBe(
text.split('hamburger').length
);
});

test('should highlight multiple results', function() {
const highlights = [
'kevin venison sausage ribeye tongue. ' +
highlightTags.pre +
'Chicken' +
highlightTags.post +
' bacon ball tip pork. Brisket ' +
'pork capicola spare ribs pastrami rump sirloin, t-bone ham shoulder jerky turducken bresaola. ' +
highlightTags.pre +
'Chicken' +
highlightTags.post +
' cow beef picanha. Picanha',
];
const result = getHighlightHtml(text, highlights);
expect(result.indexOf(htmlTags.pre + 'Chicken' + htmlTags.post)).toBeGreaterThan(-1);
expect(result.split(htmlTags.pre + 'Chicken' + htmlTags.post).length).toBe(
text.split('Chicken').length
);
});

test('should highlight multiple hits in a result', function() {
const highlights = [
'Bacon ipsum dolor amet ' +
highlightTags.pre +
'pork' +
highlightTags.post +
' loin ' +
'' +
highlightTags.pre +
'pork' +
highlightTags.post +
' cow pig beef chuck ground round shankle ' +
'sirloin landjaeger',
'kevin venison sausage ribeye tongue. Chicken bacon ball tip ' +
'' +
highlightTags.pre +
'pork' +
highlightTags.post +
'. Brisket ' +
'' +
highlightTags.pre +
'pork' +
highlightTags.post +
' capicola spare ribs',
'hamburger alcatra cupim. Salami capicola boudin ' +
highlightTags.pre +
'pork' +
highlightTags.post +
' ' +
'belly shank picanha.',
];
const result = getHighlightHtml(text, highlights);
expect(result.indexOf(htmlTags.pre + 'pork' + htmlTags.post)).toBeGreaterThan(-1);
expect(result.split(htmlTags.pre + 'pork' + htmlTags.post).length).toBe(
text.split('pork').length
);
});

test('should accept an object and return a string containing its properties', function() {
const obj = { foo: 1, bar: 2 };
const result = getHighlightHtml(obj, null);
expect(result.indexOf('' + obj)).toBe(-1);
expect(result.indexOf('foo')).toBeGreaterThan(-1);
expect(result.indexOf('bar')).toBeGreaterThan(-1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,25 @@ import _ from 'lodash';
import { highlightTags } from './highlight_tags';
import { htmlTags } from './html_tags';

export function getHighlightHtml(fieldValue, highlights) {
let highlightHtml = (typeof fieldValue === 'object')
? JSON.stringify(fieldValue)
: fieldValue;
export function getHighlightHtml(fieldValue: any, highlights: any) {
let highlightHtml = typeof fieldValue === 'object' ? JSON.stringify(fieldValue) : fieldValue;

_.each(highlights, function (highlight) {
_.each(highlights, function(highlight) {
const escapedHighlight = _.escape(highlight);

// Strip out the highlight tags to compare against the field text
const untaggedHighlight = escapedHighlight
.split(highlightTags.pre).join('')
.split(highlightTags.post).join('');
.split(highlightTags.pre)
.join('')
.split(highlightTags.post)
.join('');

// Replace all highlight tags with proper html tags
const taggedHighlight = escapedHighlight
.split(highlightTags.pre).join(htmlTags.pre)
.split(highlightTags.post).join(htmlTags.post);
.split(highlightTags.pre)
.join(htmlTags.pre)
.split(highlightTags.post)
.join(htmlTags.post);

// Replace all instances of the untagged string with the properly tagged string
highlightHtml = highlightHtml.split(untaggedHighlight).join(taggedHighlight);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,39 @@
* under the License.
*/

import expect from '@kbn/expect';
import { getHighlightRequest } from '../highlight_request';
import { getHighlightRequest } from './highlight_request';

describe('getHighlightRequest', () => {
let configMock;
const getConfig = (key) => configMock[key];
let configMock: Record<string, any>;
const getConfig = (key: string) => configMock[key];
const queryStringQuery = { query_string: { query: 'foo' } };

beforeEach(function () {
beforeEach(function() {
configMock = {};
configMock['doc_table:highlight'] = true;
});

it('should be a function', () => {
expect(getHighlightRequest).to.be.a(Function);
test('should be a function', () => {
expect(getHighlightRequest).toBeInstanceOf(Function);
});

it('should not modify the original query', () => {
test('should not modify the original query', () => {
getHighlightRequest(queryStringQuery, getConfig);
expect(queryStringQuery.query_string).to.not.have.property('highlight');
expect(queryStringQuery.query_string).not.toHaveProperty('highlight');
});

it('should return undefined if highlighting is turned off', () => {
test('should return undefined if highlighting is turned off', () => {
configMock['doc_table:highlight'] = false;
const request = getHighlightRequest(queryStringQuery, getConfig);
expect(request).to.be(undefined);
expect(request).toBe(undefined);
});

it('should enable/disable highlighting if config is changed', () => {
test('should enable/disable highlighting if config is changed', () => {
let request = getHighlightRequest(queryStringQuery, getConfig);
expect(request).to.not.be(undefined);
expect(request).not.toBe(undefined);

configMock['doc_table:highlight'] = false;
request = getHighlightRequest(queryStringQuery, getConfig);
expect(request).to.be(undefined);
expect(request).toBe(undefined);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ import { highlightTags } from './highlight_tags';

const FRAGMENT_SIZE = Math.pow(2, 31) - 1; // Max allowed value for fragment_size (limit of a java int)

export function getHighlightRequest(query, getConfig) {
export function getHighlightRequest(query: any, getConfig: Function) {
if (!getConfig('doc_table:highlight')) return;

return {
pre_tags: [highlightTags.pre],
post_tags: [highlightTags.post],
fields: {
'*': {}
'*': {},
},
fragment_size: FRAGMENT_SIZE
fragment_size: FRAGMENT_SIZE,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
// inside a field value.
export const highlightTags = {
pre: '@kibana-highlighted-field@',
post: '@/kibana-highlighted-field@'
post: '@/kibana-highlighted-field@',
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
// These are the html tags that will replace the highlight tags.
export const htmlTags = {
pre: '<mark>',
post: '</mark>'
post: '</mark>',
};