Skip to content

Commit

Permalink
feat: copy select text
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge authored Nov 20, 2024
2 parents 6390c97 + fa5ee3d commit fbed08c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 1 deletion.
62 changes: 62 additions & 0 deletions src/utils/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,68 @@ import type {
Snapshot,
} from './types';

// 获取元素id最后一个.后面的内容
const getShortName = (fullName: string): string => {
let lstIndex = fullName.lastIndexOf('.');
if (lstIndex === -1) {
return fullName;
}
return fullName.slice(lstIndex + 1);
};

export const getNodeSelectorText = (
curNode: RawNode /* 当前节点 */,
isFirst: boolean = true /* 调用时须省略 */,
lastIndex: number = 1 /* 调用时须省略 */,
): string => {
// 先处理递归基
if (!curNode.parent) {
// 当前节点为根节点
if (isFirst) {
return '[parent=null]';
} else {
return ' <' + lastIndex + ' [parent=null]';
}
}
if (curNode.idQf) {
// 可以快速查询
// (依赖页面结构而不是文本内容,只处理idQf的情况)
const key = curNode.attr.vid ? 'vid' : 'id';
const value = curNode.attr.vid || curNode.attr.id;
if (isFirst) {
return `[${key}="${value}"]`;
} else {
return ' <' + lastIndex + ` [${key}="${value}"]`;
}
}
// 处理一般的递归情况
if (isFirst) {
// 第一次调用,当前节点即为目标节点
// 返回完整的选择器,假设getSelector会返回后面应该拼接的文本
// (递归基在前面已经处理掉了,所以说这里一定会有后缀)
return (
'@' +
getShortName(curNode.attr.name) +
getNodeSelectorText(curNode.parent, false, curNode.attr.index + 1)
/* 当前节点的index转序号后传递给下一层函数调用
* 否则下一层函数不知道现在的节点是父节点的第几个儿子 */
);
}
// 不是第一次调用,所以说函数的目标是拼接返回选择器的后缀部分
return (
' <' +
lastIndex /* 当前处理的是目标节点的(间接)父节点
* 所以说这里取子节点(也就是上一层函数的节点)的index */ +
' ' +
getShortName(curNode.attr.name) +
getNodeSelectorText(
curNode.parent,
false,
curNode.attr.index + 1,
) /* 递归构造后缀 */
);
};

export const listToTree = (nodes: RawNode[]) => {
nodes.forEach((node) => {
node.attr ??= { name: `NULL` } as any;
Expand Down
36 changes: 35 additions & 1 deletion src/views/snapshot/AttrCard.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import DraggableCard from '@/components/DraggableCard.vue';
import { getNodeSelectorText } from '@/utils/node';
import { buildEmptyFn, copy } from '@/utils/others';
withDefaults(
Expand Down Expand Up @@ -33,6 +34,11 @@ const attrTip = computed<AttrTipMap>(() => {
type: 'info',
show: true,
},
_selector: {
desc: `自动生成的选择器, 点击“_selector”可直接复制内容, 用于定位`,
type: 'info',
show: true,
},
depth: {
desc: `使用此属性在某些应用上可能造成无限节点错误`,
type: 'info',
Expand Down Expand Up @@ -82,6 +88,11 @@ const attrs = computed(() => {
})
.flat();
});
const selectText = computed(() => {
if (!focusNode.value) return '';
return getNodeSelectorText(focusNode.value);
});
</script>

<template>
Expand Down Expand Up @@ -110,7 +121,7 @@ const attrs = computed(() => {
class="gkd_code"
:themeOverrides="{
thPaddingSmall: '1px 3px',
tdPaddingSmall: '1px 3px',
tdPaddingSmall: '0px 3px',
}"
><thead>
<tr :ref="onRef" cursor-move>
Expand Down Expand Up @@ -164,6 +175,29 @@ const attrs = computed(() => {
</NEllipsis>
</NTd>
</NTr>
<NTr>
<NTd colspan="2">
<div flex items-center h-24px px-2px>
<NTooltip>
<template #trigger>
<NButton text @click="copy(selectText)">
<template #icon>
<NIcon size="20">
<svg viewBox="0 0 24 24">
<path
fill="currentColor"
d="M5 21V8.825Q4.125 8.5 3.563 7.738T3 6q0-1.25.875-2.125T6 3q1.25 0 2.125.875T9 6q0 .975-.562 1.738T7 8.825V19h4V3h8v12.175q.875.325 1.438 1.088T21 18q0 1.25-.875 2.125T18 21q-1.25 0-2.125-.875T15 18q0-.975.563-1.75T17 15.175V5h-4v16zM6 7q.425 0 .713-.288T7 6q0-.425-.288-.712T6 5q-.425 0-.712.288T5 6q0 .425.288.713T6 7m12 12q.425 0 .713-.288T19 18q0-.425-.288-.712T18 17q-.425 0-.712.288T17 18q0 .425.288.713T18 19m0-1"
/>
</svg>
</NIcon>
</template>
</NButton>
</template>
{{ selectText }}
</NTooltip>
</div>
</NTd>
</NTr>
</NTbody>
</NTable>
</DraggableCard>
Expand Down

0 comments on commit fbed08c

Please sign in to comment.