UNPKG

@grafana/ui

Version:
1 lines • 21.1 kB
{"version":3,"file":"json_explorer.mjs","sources":["../../../../../src/components/JSONFormatter/json_explorer/json_explorer.ts"],"sourcesContent":["// Based on work https://github.com/mohsen1/json-formatter-js\n// License MIT, Copyright (c) 2015 Mohsen Azimi\n\nimport { isNumber } from 'lodash';\n\nimport { isObject, getObjectName, getType, getValuePreview, cssClass, createElement } from './helpers';\n\nconst DATE_STRING_REGEX =\n /(^\\d{1,4}[\\.|\\\\/|-]\\d{1,2}[\\.|\\\\/|-]\\d{1,4})(\\s*(?:0?[1-9]:[0-5]|1(?=[012])\\d:[0-5])\\d\\s*[ap]m)?$/;\nconst PARTIAL_DATE_REGEX = /\\d{2}:\\d{2}:\\d{2} GMT-\\d{4}/;\nconst JSON_DATE_REGEX = /\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}Z/;\n\n// When toggling, don't animated removal or addition of more than a few items\nconst MAX_ANIMATED_TOGGLE_ITEMS = 10;\n\nconst requestAnimationFrame =\n (typeof window !== 'undefined' && window.requestAnimationFrame) ||\n ((cb: () => void) => {\n cb();\n return 0;\n });\n\nexport interface JsonExplorerConfig {\n animateOpen?: boolean;\n animateClose?: boolean;\n theme?: string;\n}\n\nconst _defaultConfig: JsonExplorerConfig = {\n animateOpen: true,\n animateClose: true,\n};\n\n/**\n * @class JsonExplorer\n *\n * JsonExplorer allows you to render JSON objects in HTML with a\n * **collapsible** navigation.\n */\nexport class JsonExplorer {\n // Hold the open state after the toggler is used\n private _isOpen: boolean | null = null;\n\n // A reference to the element that we render to\n private element: HTMLDivElement | null = null;\n\n private skipChildren = false;\n\n /**\n * @param {object} json The JSON object you want to render. It has to be an\n * object or array. Do NOT pass raw JSON string.\n *\n * @param {number} [open=1] his number indicates up to how many levels the\n * rendered tree should expand. Set it to `0` to make the whole tree collapsed\n * or set it to `Infinity` to expand the tree deeply\n *\n * @param {object} [config=defaultConfig] -\n * defaultConfig = {\n * hoverPreviewEnabled: false,\n * hoverPreviewArrayCount: 100,\n * hoverPreviewFieldCount: 5\n * }\n *\n * Available configurations:\n * #####Hover Preview\n * * `hoverPreviewEnabled`: enable preview on hover\n * * `hoverPreviewArrayCount`: number of array items to show in preview Any\n * array larger than this number will be shown as `Array[XXX]` where `XXX`\n * is length of the array.\n * * `hoverPreviewFieldCount`: number of object properties to show for object\n * preview. Any object with more properties that thin number will be\n * truncated.\n *\n * @param {string} [key=undefined] The key that this object in its parent\n * context\n */\n constructor(\n public json: any,\n private open = 1,\n private config: JsonExplorerConfig = _defaultConfig,\n private key?: string\n ) {}\n\n /*\n * is formatter open?\n */\n private get isOpen(): boolean {\n if (this._isOpen !== null) {\n return this._isOpen;\n } else {\n return this.open > 0;\n }\n }\n\n /*\n * set open state (from toggler)\n */\n private set isOpen(value: boolean) {\n this._isOpen = value;\n }\n\n /*\n * is this a date string?\n */\n private get isDate(): boolean {\n return (\n this.type === 'string' &&\n (DATE_STRING_REGEX.test(this.json) || JSON_DATE_REGEX.test(this.json) || PARTIAL_DATE_REGEX.test(this.json))\n );\n }\n\n /*\n * is this a URL string?\n */\n private get isUrl(): boolean {\n return this.type === 'string' && this.json.indexOf('http') === 0;\n }\n\n /*\n * is this an array?\n */\n private get isArray(): boolean {\n return Array.isArray(this.json);\n }\n\n /*\n * is this an object?\n * Note: In this context arrays are object as well\n */\n private get isObject(): boolean {\n return isObject(this.json);\n }\n\n /*\n * is this an empty object with no properties?\n */\n private get isEmptyObject(): boolean {\n return !this.keys.length && !this.isArray;\n }\n\n /*\n * is this an empty object or array?\n */\n private get isEmpty(): boolean {\n return this.isEmptyObject || (this.keys && !this.keys.length && this.isArray);\n }\n\n /*\n * did we receive a key argument?\n * This means that the formatter was called as a sub formatter of a parent formatter\n */\n private get hasKey(): boolean {\n return typeof this.key !== 'undefined';\n }\n\n /*\n * if this is an object, get constructor function name\n */\n private get constructorName(): string {\n return getObjectName(this.json);\n }\n\n /*\n * get type of this value\n * Possible values: all JavaScript primitive types plus \"array\" and \"null\"\n */\n private get type(): string {\n return getType(this.json);\n }\n\n /*\n * get object keys\n * If there is an empty key we pad it wit quotes to make it visible\n */\n private get keys(): string[] {\n if (this.isObject) {\n return Object.keys(this.json).map((key) => (key ? key : '\"\"'));\n } else {\n return [];\n }\n }\n\n /**\n * Toggles `isOpen` state\n *\n */\n toggleOpen() {\n this.isOpen = !this.isOpen;\n\n if (this.element) {\n if (this.isOpen) {\n this.appendChildren(this.config.animateOpen);\n } else {\n this.removeChildren(this.config.animateClose);\n }\n this.element.classList.toggle(cssClass('open'));\n }\n }\n\n /**\n * Open all children up to a certain depth.\n * Allows actions such as expand all/collapse all\n *\n */\n openAtDepth(depth = 1) {\n if (depth < 0) {\n return;\n }\n\n this.open = depth;\n this.isOpen = depth !== 0;\n\n if (this.element) {\n this.removeChildren(false);\n\n if (depth === 0) {\n this.element.classList.remove(cssClass('open'));\n } else {\n this.appendChildren(this.config.animateOpen);\n this.element.classList.add(cssClass('open'));\n }\n }\n }\n\n isNumberArray() {\n return this.json.length > 0 && this.json.length < 4 && (isNumber(this.json[0]) || isNumber(this.json[1]));\n }\n\n renderArray() {\n const arrayWrapperSpan = createElement('span');\n arrayWrapperSpan.appendChild(createElement('span', 'bracket', '['));\n\n // some pretty handling of number arrays\n if (this.isNumberArray()) {\n this.json.forEach((val: any, index: number) => {\n if (index > 0) {\n arrayWrapperSpan.appendChild(createElement('span', 'array-comma', ','));\n }\n arrayWrapperSpan.appendChild(createElement('span', 'number', val));\n });\n this.skipChildren = true;\n } else {\n arrayWrapperSpan.appendChild(createElement('span', 'number', this.json.length));\n }\n\n arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']'));\n return arrayWrapperSpan;\n }\n\n /**\n * Renders an HTML element and installs event listeners\n *\n * @returns {HTMLDivElement}\n */\n render(skipRoot = false): HTMLDivElement {\n // construct the root element and assign it to this.element\n this.element = createElement('div', 'row');\n\n // construct the toggler link\n const togglerLink = createElement('a', 'toggler-link');\n const togglerIcon = createElement('span', 'toggler');\n\n // if this is an object we need a wrapper span (toggler)\n if (this.isObject) {\n togglerLink.appendChild(togglerIcon);\n }\n\n // if this is child of a parent formatter we need to append the key\n if (this.hasKey) {\n togglerLink.appendChild(createElement('span', 'key', `${this.key}:`));\n }\n\n // Value for objects and arrays\n if (this.isObject) {\n // construct the value holder element\n const value = createElement('span', 'value');\n\n // we need a wrapper span for objects\n const objectWrapperSpan = createElement('span');\n\n // get constructor name and append it to wrapper span\n const constructorName = createElement('span', 'constructor-name', this.constructorName);\n objectWrapperSpan.appendChild(constructorName);\n\n // if it's an array append the array specific elements like brackets and length\n if (this.isArray) {\n const arrayWrapperSpan = this.renderArray();\n objectWrapperSpan.appendChild(arrayWrapperSpan);\n }\n\n // append object wrapper span to toggler link\n value.appendChild(objectWrapperSpan);\n togglerLink.appendChild(value);\n // Primitive values\n } else {\n // make a value holder element\n const value = this.isUrl ? createElement('a') : createElement('span');\n\n // add type and other type related CSS classes\n value.classList.add(cssClass(this.type));\n if (this.isDate) {\n value.classList.add(cssClass('date'));\n }\n if (this.isUrl) {\n value.classList.add(cssClass('url'));\n value.setAttribute('href', this.json);\n }\n\n // Append value content to value element\n const valuePreview = getValuePreview(this.json, this.json);\n value.appendChild(document.createTextNode(valuePreview));\n\n // append the value element to toggler link\n togglerLink.appendChild(value);\n }\n\n // construct a children element\n const children = createElement('div', 'children');\n\n // set CSS classes for children\n if (this.isObject) {\n children.classList.add(cssClass('object'));\n }\n if (this.isArray) {\n children.classList.add(cssClass('array'));\n }\n if (this.isEmpty) {\n children.classList.add(cssClass('empty'));\n }\n\n // set CSS classes for root element\n if (this.config && this.config.theme) {\n this.element.classList.add(cssClass(this.config.theme));\n }\n if (this.isOpen) {\n this.element.classList.add(cssClass('open'));\n }\n\n // append toggler and children elements to root element\n if (!skipRoot) {\n this.element.appendChild(togglerLink);\n }\n\n if (!this.skipChildren) {\n this.element.appendChild(children);\n } else {\n // remove togglerIcon\n togglerLink.removeChild(togglerIcon);\n }\n\n // if formatter is set to be open call appendChildren\n if (this.isObject && this.isOpen) {\n this.appendChildren();\n }\n\n // add event listener for toggling\n if (this.isObject) {\n togglerLink.addEventListener('click', this.toggleOpen.bind(this));\n }\n\n return this.element;\n }\n\n /**\n * Appends all the children to children element\n * Animated option is used when user triggers this via a click\n */\n appendChildren(animated = false) {\n const children = this.element && this.element.querySelector(`div.${cssClass('children')}`);\n\n if (!children || this.isEmpty) {\n return;\n }\n\n if (animated) {\n let index = 0;\n const addAChild = () => {\n const key = this.keys[index];\n const formatter = new JsonExplorer(this.json[key], this.open - 1, this.config, key);\n children.appendChild(formatter.render());\n\n index += 1;\n\n if (index < this.keys.length) {\n if (index > MAX_ANIMATED_TOGGLE_ITEMS) {\n addAChild();\n } else {\n requestAnimationFrame(addAChild);\n }\n }\n };\n\n requestAnimationFrame(addAChild);\n } else {\n this.keys.forEach((key) => {\n const formatter = new JsonExplorer(this.json[key], this.open - 1, this.config, key);\n children.appendChild(formatter.render());\n });\n }\n }\n\n /**\n * Removes all the children from children element\n * Animated option is used when user triggers this via a click\n */\n removeChildren(animated = false) {\n const childrenElement = this.element && this.element.querySelector<HTMLDivElement>(`div.${cssClass('children')}`);\n\n if (animated) {\n let childrenRemoved = 0;\n const removeAChild = () => {\n if (childrenElement && childrenElement.children.length) {\n childrenElement.removeChild(childrenElement.children[0]);\n childrenRemoved += 1;\n if (childrenRemoved > MAX_ANIMATED_TOGGLE_ITEMS) {\n removeAChild();\n } else {\n requestAnimationFrame(removeAChild);\n }\n }\n };\n requestAnimationFrame(removeAChild);\n } else {\n if (childrenElement) {\n childrenElement.innerHTML = '';\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}