Files
FixIt/assets/lib/json-viewer-element/json-viewer-element.umd.js
T

2 lines
8.9 KiB
JavaScript
Vendored

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).JsonViewerElement={})}(this,function(e){"use strict";const t=document.createElement("template");t.innerHTML='\n<style>\n/* Light Theme (default) */\n:host {\n --jv-bg-color: #ffffff;\n --jv-border-color: #ddd;\n --jv-text-color: #111;\n --jv-key-color: #111;\n --jv-string-color: #42b983;\n --jv-number-color: #fc1e70;\n --jv-boolean-color: #fc1e70;\n --jv-null-color: #e08331;\n --jv-undefined-color: #b0b0b0;\n --jv-function-color: #067bca;\n --jv-regexp-color: #fc1e70;\n --jv-copy-bg: #eee;\n --jv-copy-text: #333;\n --jv-ellipsis-color: #999999;\n --jv-ellipsis-bg: #eeeeee;\n --jv-hover-shadow: rgba(0,0,0,0.1);\n}\n\n/* Dark Theme */\n:host([theme="dark"]) {\n --jv-bg-color: #23272f;\n --jv-border-color: #2c313a;\n --jv-text-color: #d4d4d4;\n --jv-key-color: #79c0ff;\n --jv-string-color: #a5d6a7;\n --jv-number-color: #e2b86b;\n --jv-boolean-color: #ff7b72;\n --jv-null-color: #ffab70;\n --jv-undefined-color: #d2a8ff;\n --jv-function-color: #c678dd;\n --jv-regexp-color: #56b6c2;\n --jv-copy-bg: #3a3f4b;\n --jv-copy-text: #fff;\n --jv-ellipsis-color: #6e7681;\n --jv-ellipsis-bg: #2c313a;\n --jv-hover-shadow: rgba(0,0,0,0.4);\n}\n\n:host {\n display: block;\n width: 100%;\n max-width: 100%;\n font-family: Consolas, Menlo, Courier, monospace;\n font-size: 14px;\n padding: 8px;\n overflow-x: auto;\n box-sizing: border-box;\n position: relative;\n background-color: var(--jv-bg-color);\n color: var(--jv-text-color);\n}\n\n:host([boxed]) {\n border: 1px solid var(--jv-border-color);\n border-radius: 4px;\n padding: 16px;\n transition: box-shadow 0.2s ease;\n}\n:host([boxed]:hover) {\n box-shadow: 0 2px 8px var(--jv-hover-shadow);\n}\n#root:has(+.align-left) {\n margin-top: 16px;\n}\n.jv-copy {\n cursor: pointer;\n font-size: 12px;\n background: var(--jv-copy-bg);\n color: var(--jv-copy-text);\n padding: 4px 8px;\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n:host(:hover) .jv-copy {\n opacity: 1;\n}\nslot[name="copy-button"] {\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 10;\n opacity: 0;\n transition: opacity 0.2s ease;\n display: block !important;\n}\nslot[name="copy-button"][hidden] {\n display: none !important;\n}\nslot[name="copy-button"].align-left {\n left: 8px;\n right: auto;\n}\nslot[name="copy-button"].align-right {\n right: 8px;\n left: auto;\n}\n:host(:hover) slot[name="copy-button"] {\n opacity: 1;\n}\n.jv-toggle {\n background-image: url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMCAwIDggOC04IDh6IiBmaWxsPSIjNjY2Ii8+PC9zdmc+");\n background-repeat: no-repeat;\n background-size: contain;\n background-position: center center;\n cursor: pointer;\n width: 10px;\n height: 10px;\n margin-right: 2px;\n display: inline-block;\n transition: rotate .1s;\n}\n.jv-toggle.open {\n rotate: 90deg;\n}\n.jv-key {\n color: var(--jv-key-color);\n}\n.jv-string {\n color: var(--jv-string-color);\n}\n.jv-number {\n color: var(--jv-number-color);\n}\n.jv-boolean {\n color: var(--jv-boolean-color);\n}\n.jv-null {\n color: var(--jv-null-color);\n}\n.jv-undefined {\n color: var(--jv-undefined-color);\n}\n.jv-function {\n color: var(--jv-function-color);\n}\n.jv-regexp {\n color: var(--jv-regexp-color);\n}\n.jv-list {\n margin-left: 16px;\n}\n.jv-item:not(:has(.jv-toggle)) .jv-key {\n margin-left: 12px;\n}\n.jv-item:not(:last-child):after {\n content: \',\';\n}\n.jv-node > .jv-ellipsis {\n display: none;\n}\n.jv-node.empty > .jv-list {\n display: inline-block;\n margin-inline: 4px;\n}\n.jv-node.collapsed > .jv-list,\n.jv-node.collapsed.empty > .jv-ellipsis {\n display: none;\n}\n.jv-node.collapsed > .jv-ellipsis {\n color: var(--jv-ellipsis-color);\n background-color: var(--jv-ellipsis-bg);\n display: inline-block;\n line-height: 0.9;\n font-size: 0.85em;\n vertical-align: 2px;\n cursor: pointer;\n user-select: none;\n padding: 2px 4px;\n margin: 0px 4px;\n border-radius: 3px;\n}\n</style>\n<div id="root" part="root"></div>\n<slot name="copy-button" part="copy-button" hidden>\n <span class="jv-copy"></span>\n</slot>\n';class n extends HTMLElement{constructor(){super(),this._value=null,this.root=this.attachShadow({mode:"open"}),this.root.appendChild(t.content.cloneNode(!0)),this.container=this.root.getElementById("root")}static get observedAttributes(){return["value","expand-depth","copyable","sort","boxed","theme","parse"]}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}set value(e){e!==this._value&&(this._value=e,this.render())}get value(){return this._value??this.getAttribute("value")}set sort(e){this.setAttribute("sort",e?"true":"false")}get sort(){return this.hasAttribute("sort")}set parse(e){this.setAttribute("parse",e?"true":"false")}get parse(){return"false"!==this.getAttribute("parse")}set copyable(e){!1===e?this.removeAttribute("copyable"):this.setAttribute("copyable",JSON.stringify(e))}get copyable(){if(!this.hasAttribute("copyable"))return!1;const e=this.getAttribute("copyable"),t={copyText:"Copy",copiedText:"Copied",timeout:2e3,align:"right"};if(""===e||null===e)return t;try{return{...t,...JSON.parse(e)}}catch{return t}}get expandDepth(){return Number(this.getAttribute("expand-depth")??1)}copyText(e){return navigator.clipboard?(this.copyText=e=>navigator.clipboard.writeText(e),this.copyText(e)):(this.copyText=e=>new Promise((t,n)=>{const o=document.createElement("input");o.value=e,document.body.appendChild(o),o.select(),document.execCommand("copy")?(document.body.removeChild(o),t()):(document.body.removeChild(o),n(new Error("Copy failed")))}),this.copyText(e))}render(){if("string"==typeof this.value&&this.parse)try{this._value=JSON.parse(this.value)}catch{}this.container.innerHTML="",this.container.appendChild(this.build(this._value,0));const e=this.copyable;if(e){const t=e.align||"right",n=this.root.querySelector('slot[name="copy-button"]'),o=n.assignedElements()[0],r=this.root.querySelector(".jv-copy");if(n.hidden=!1,n.className=`align-${t}`,!o){let t;r.textContent=e.copyText;const n=r.cloneNode(!0);r.replaceWith(n),n.textContent=e.copyText,n.addEventListener("click",()=>{const o=JSON.stringify(this._value,null,2);this.copyText(o).then(()=>{n.textContent=e.copiedText,t=window.setTimeout(()=>{n.textContent=e.copyText,clearTimeout(t)},e.timeout),this.dispatchEvent(new CustomEvent("copy-success",{detail:{text:o,options:e}}))}).catch(()=>{console.warn("Failed to copy text to clipboard"),this.dispatchEvent(new CustomEvent("copy-error",{detail:{text:o,options:e}}))})})}}}build(e,t){if(null===e)return this.leaf("null","jv-null");if(void 0===e)return this.leaf("undefined","jv-undefined");if("boolean"==typeof e)return this.leaf(String(e),"jv-boolean");if("number"==typeof e)return this.leaf(String(e),"jv-number");if("string"==typeof e)return this.leaf(`"${e}"`,"jv-string");if("function"==typeof e)return this.leaf("<function>","jv-function");if(e instanceof RegExp)return this.leaf("<regexp>","jv-regexp");if(e instanceof Date)return this.leaf(`"${e.toLocaleString()}"`,"jv-string");const n=Array.isArray(e),o=document.createElement("span");o.className="jv-node",o.setAttribute("part","node");const r=document.createElement("div");r.className="jv-list",r.setAttribute("part","list");const s=n?this.sort?[...e.keys()].sort((e,t)=>e-t):[...e.keys()]:this.sort?Object.keys(e).sort():Object.keys(e);for(const l of s){const o=document.createElement("div"),s=this.build(e[l],t+1);if(o.className="jv-item",s instanceof Element&&s.classList.contains("jv-node")){const e=s.querySelector(".jv-toggle");e&&(e.remove(),o.append(e))}if(!n){const e=document.createElement("span");e.className="jv-key",e.setAttribute("part","key"),e.textContent=`"${l}": `,o.append(e)}o.append(s),r.append(o)}const i=document.createElement("span");i.className="jv-toggle",i.setAttribute("part","toggle"),o.classList.contains("collapsed")||i.classList.add("open"),i.addEventListener("click",()=>{o.classList.toggle("collapsed"),i.classList.toggle("open"),this.dispatchEvent(new CustomEvent("toggle",{detail:{node:o,data:e,isCollapsed:o.classList.contains("collapsed")}}))});const a=document.createElement("span");return a.className="jv-ellipsis",a.setAttribute("part","ellipsis"),a.textContent=`...${s.length}`,a.addEventListener("click",()=>{o.classList.remove("collapsed"),i.classList.add("open")}),t>=this.expandDepth&&(o.classList.add("collapsed"),i.classList.remove("open")),s.length||o.classList.add("empty"),o.append(i,n?"[":"{",a,r,n?"]":"}"),o}leaf(e,t){const n=document.createElement("span");return n.className=`jv-value ${t}`,n.setAttribute("part",`value ${t.replace("jv-","")}`),n.textContent=e,n}}customElements.define("json-viewer",n),e.JsonViewerElement=n,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});