chore(frontend): add debugger for #6864 (#10270)

This commit is contained in:
Acid Chicken (硫酸鶏) 2023-03-09 14:35:38 +09:00 committed by GitHub
parent c75afad64a
commit 93ea9c2033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 1 deletions

View File

@ -1,7 +1,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, h, PropType, TransitionGroup, useCssModule } from 'vue'; import { defineComponent, h, PropType, TransitionGroup, useCssModule } from 'vue';
import MkAd from '@/components/global/MkAd.vue'; import MkAd from '@/components/global/MkAd.vue';
import { isDebuggerEnabled, stackTraceInstances } from '@/debug';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import * as os from '@/os';
import { defaultStore } from '@/store'; import { defaultStore } from '@/store';
import { MisskeyEntity } from '@/types/date-separated-list'; import { MisskeyEntity } from '@/types/date-separated-list';
@ -46,7 +48,7 @@ export default defineComponent({
if (props.items.length === 0) return; if (props.items.length === 0) return;
const renderChildren = () => props.items.map((item, i) => { const renderChildrenImpl = () => props.items.map((item, i) => {
if (!slots || !slots.default) return; if (!slots || !slots.default) return;
const el = slots.default({ const el = slots.default({
@ -95,6 +97,21 @@ export default defineComponent({
} }
}); });
const renderChildren = () => {
const children = renderChildrenImpl();
if (isDebuggerEnabled(6864)) {
const nodes = children.flatMap((node) => node ?? []);
const keys = new Set(nodes.map((node) => node.key));
if (keys.size !== nodes.length) {
const id = crypto.randomUUID();
const instances = stackTraceInstances();
os.toast(instances.reduce((a, c) => `${a} at ${c.type.name}`, `[DEBUG_6864 (${id})]: ${nodes.length - keys.size} duplicated keys found`));
console.warn({ id, debugId: 6864, stack: instances });
}
}
return children;
};
function onBeforeLeave(el: HTMLElement) { function onBeforeLeave(el: HTMLElement) {
el.style.top = `${el.offsetTop}px`; el.style.top = `${el.offsetTop}px`;
el.style.left = `${el.offsetLeft}px`; el.style.left = `${el.offsetLeft}px`;

View File

@ -0,0 +1,27 @@
import { type ComponentInternalInstance, getCurrentInstance } from 'vue';
export function isDebuggerEnabled(id: number): boolean {
try {
return localStorage.getItem(`DEBUG_${id}`) !== null;
} catch {
return false;
}
}
export function switchDebuggerEnabled(id: number, enabled: boolean): void {
if (enabled) {
localStorage.setItem(`DEBUG_${id}`, '');
} else {
localStorage.removeItem(`DEBUG_${id}`);
}
}
export function stackTraceInstances(): ComponentInternalInstance[] {
let instance = getCurrentInstance();
const stack: ComponentInternalInstance[] = [];
while (instance) {
stack.push(instance);
instance = instance.parent;
}
return stack;
}