diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index eeddd4ec30..5bb8792dfc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,8 +1,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbContextDebugRequest, UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; - +import { + UmbContextDebugRequest, + UmbContextRequestEventImplementation, + umbContextRequestEventType, +} from '@umbraco-cms/context-api'; @customElement('umb-debug') export class UmbDebug extends LitElement { @@ -13,63 +16,64 @@ export class UmbDebug extends LitElement { display: block; font-family: monospace; - z-index:10000; + z-index: 10000; - width:100%; - padding:10px 0; + width: 100%; + padding: 10px 0; } .events { - background-color:var(--uui-color-danger); - color:var(--uui-color-selected-contrast); - height:0; + background-color: var(--uui-color-danger); + color: var(--uui-color-selected-contrast); + height: 0; transition: height 0.3s ease-out; } .events.open { - height:auto; + height: auto; } .events > div { - padding:10px; + padding: 10px; } h4 { - margin:0; + margin: 0; } `, ]; - @property({reflect: true, type: Boolean}) - enabled = false; + @property({ reflect: true, type: Boolean }) + enabled = false; @property() contextAliases = new Map(); - @state() + @state() private _debugPaneOpen = false; - private _toggleDebugPane() { - this._debugPaneOpen = !this._debugPaneOpen; - } + private _toggleDebugPane() { + this._debugPaneOpen = !this._debugPaneOpen; + } connectedCallback(): void { super.connectedCallback(); - - // Dispatch it - this.dispatchEvent(new UmbContextDebugRequest((instances)=> { - console.log('I have contexts now', instances); - this.contextAliases = instances; - })); + // Dispatch it + this.dispatchEvent( + new UmbContextDebugRequest((instances) => { + console.log('I have contexts now', instances); + + this.contextAliases = instances; + }) + ); } render() { - - if(this.enabled){ - return html` -
- + if (this.enabled) { + return html` +
+ Debug @@ -80,13 +84,13 @@ export class UmbDebug extends LitElement {
    ${this._renderContextAliases()}
-
+
- + `; - } + } - return nothing; + return nothing; } private _renderContextAliases() { @@ -94,14 +98,13 @@ export class UmbDebug extends LitElement { for (const [alias, instance] of this.contextAliases) { aliases.push( - html` -
  • - Context: ${alias} - -
  • ` - ); + html`
  • + Context: ${alias} + +
  • ` + ); } return aliases; @@ -110,23 +113,48 @@ export class UmbDebug extends LitElement { private _renderInstance(instance: any) { const instanceKeys = []; - for(const key in instance) { + if (typeof instance === 'object') { + const methodNames = this.getClassMethodNames(instance); + instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); + // instanceKeys.push(html`
  • Method -
  • `); + } + + for (const key in instance) { + if (key.startsWith('_')) { + continue; + } // Goes KABOOM - if try to loop over the class/object // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); const value = instance[key]; - if(typeof value === 'string'){ - instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - } - else { + if (typeof value === 'string') { + instanceKeys.push(html`
  • ${key} = ${value}
  • `); + } else { instanceKeys.push(html`
  • ${key}
  • `); } } return instanceKeys; } + + private getClassMethodNames(klass: any) { + const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; + const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; + const deepFunctions = (x: any): any => + x !== Object.prototype && + Object.getOwnPropertyNames(x) + .filter((name) => isGetter(x, name) || isFunction(x, name)) + .concat(deepFunctions(Object.getPrototypeOf(x)) || []); + const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); + + const allMethods = + typeof klass.prototype === 'undefined' + ? distinctDeepFunctions(klass) + : Object.getOwnPropertyNames(klass.prototype); + return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); + } } declare global {