@highcharts/dashboards
Version:
Highcharts Dashboards framework
247 lines (246 loc) • 5.87 kB
JavaScript
/* *
*
* (c) 2009-2024 Highsoft AS
*
* License: www.highcharts.com/license
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* Authors:
* - Sebastian Bochan
* - Wojciech Chmiel
* - Gøran Slettemark
* - Sophie Bremer
*
* */
'use strict';
import AST from '../../Core/Renderer/HTML/AST.js';
import Component from './Component.js';
import U from '../../Core/Utilities.js';
const { merge, diffObjects } = U;
// TODO: This may affect the AST parsing in Highcharts
// should look into adding these as options if possible
// Needs to go in a composition in the Highcharts plugin
AST.allowedTags = [
...AST.allowedTags,
'option',
'select',
'label',
'input',
'textarea'
];
AST.allowedAttributes = [
...AST.allowedAttributes,
'for', 'value', 'checked', 'src', 'name', 'selected'
];
AST.allowedReferences = [...AST.allowedReferences, 'data:image/'];
/* *
*
* Class
*
* */
/**
*
* Class that represents a HTML component.
*
*/
class HTMLComponent extends Component {
/* *
*
* Static functions
*
* */
/**
* Creates component from JSON.
*
* @param json
* Set of component options, used for creating the HTML component.
*
* @param cell
* Instance of cell, where component is attached.
*
* @returns
* HTML component based on config from JSON.
*
* @internal
*/
static fromJSON(json, cell) {
const options = json.options;
const elements = (json.elements ?
json.elements.map((el) => JSON.parse(el)) :
[]);
// const connector = (
// json.connector ? DataJSON.fromJSON(json.connector) : void 0
// );
const component = new HTMLComponent(cell, merge(options, {
elements
// connector: (
// connector instanceof DataConnector ? connector : void 0
// )
}));
component.emit({
type: 'fromJSON',
json
});
return component;
}
/* *
*
* Constructor
*
* */
/**
* Creates a HTML component in the cell.
*
* @param options
* The options for the component.
*/
constructor(cell, options) {
options = merge(HTMLComponent.defaultOptions, options);
super(cell, options);
this.options = options;
this.type = 'HTML';
this.elements = [];
this.sync = new Component.Sync(this, this.syncHandlers);
}
/* *
*
* Functions
*
* */
/** @internal */
async load() {
this.emit({
type: 'load'
});
await super.load();
const options = this.options;
let isError = false;
if (options.elements) {
this.elements = options.elements.map(function (element) {
if (typeof element === 'string') {
return new AST(element).nodes[0];
}
if (!element.textContent &&
!element.tagName &&
element.attributes) {
isError = true;
}
return element;
});
}
this.constructTree();
this.emit({ type: 'afterLoad' });
if (isError) {
throw new Error('Missing tagName param in component: ' +
options.cell);
}
return this;
}
render() {
super.render();
this.constructTree();
this.emit({ type: 'afterRender' });
return this;
}
resize(width, height) {
super.resize(width, height);
return this;
}
/**
* Handles updating via options.
* @param options
* The options to apply.
*/
async update(options) {
await super.update(options);
this.emit({ type: 'afterUpdate' });
}
getOptionsOnDrop() {
return {
cell: '',
type: 'HTML',
elements: [{
tagName: 'img',
attributes: {
src: 'https://www.highcharts.com/samples/graphics/stock-dark.svg'
}
}]
};
}
/**
* TODO: Could probably use the serialize function moved on
* the exportdata branch
*
* @internal
*/
constructTree() {
// Remove old tree if rerendering.
while (this.contentElement.firstChild) {
this.contentElement.firstChild.remove();
}
const parser = new AST(this.elements);
parser.addToDOM(this.contentElement);
}
/**
* Converts the class instance to a class JSON.
*
* @returns
* Class JSON of this Component instance.
*
* @internal
*/
toJSON() {
const elements = (this.options.elements || [])
.map((el) => JSON.stringify(el));
const json = merge(super.toJSON(), {
elements,
options: this.options
});
this.emit({
type: 'toJSON',
json
});
return json;
}
/**
* Get the HTML component's options.
* @returns
* The JSON of HTML component's options.
*
* @internal
*
*/
getOptions() {
return {
...diffObjects(this.options, HTMLComponent.defaultOptions),
type: 'HTML'
};
}
/**
* @internal
*/
onTableChanged(e) {
if (e.detail?.sender !== this.id) {
this.render();
}
}
}
/* *
*
* Static properties
*
* */
/**
* Default options of the HTML component.
*/
HTMLComponent.defaultOptions = merge(Component.defaultOptions, {
type: 'HTML',
elements: []
});
/* *
*
* Default export
*
* */
export default HTMLComponent;