fix(data-viewer): correct text line break in presence of <span>

This commit is contained in:
kerms 2024-05-25 09:38:54 +08:00
parent a2b7026f54
commit f0f11c0646
2 changed files with 52 additions and 26 deletions

View File

@ -137,7 +137,7 @@ function u8toHexdump(buffer: Uint8Array) {
function strToHTML(str: string) {
return str.replace(/\n/g, '<br>') // Replace newline with <br> tag
.replace(/\t/g, '&emsp;') // Replace tab with spaces (or you could use '&nbsp;' for single spaces)
.replace(/ /g, '&nbsp;');
.replace(/ /g, ' ');
}
function isArrayContained(subArray: Uint8Array, mainArray: Uint8Array,
@ -376,11 +376,15 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
} else {
RxSegment = new Uint8Array();
}
RxRemainHexdump.value = u8toHexdump(RxSegment);
for (let i = 0; i < frames.length; i++) {
addItem(frames[i], isRX, doSend);
}
if (RxSegment.length > 8192) {
addItem(RxSegment, isRX, doSend);
RxSegment = new Uint8Array();
}
}
const frameBreakRet = {
@ -409,6 +413,11 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
const TxTotalByteCount = ref(0);
const TxByteCount = ref(0);
let TxByteCountLocal = 0;
let TxTotalByteCountLocal = 0;
let RxByteCountLocal = 0;
let RxTotalByteCountLocal = 0;
const enableFilter = ref(true);
const forceToBottom = ref(true);
const filterChanged = ref(false);
@ -511,9 +520,19 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
}
}, {immediate: true});
/* delayed value update, prevent quick unnecessary update */
setInterval(() => {
dataBufLength.value = dataBuf.length;
}, 500);
TxByteCount.value = TxByteCountLocal;
TxTotalByteCount.value = TxTotalByteCountLocal;
RxByteCount.value = RxByteCountLocal;
RxTotalByteCount.value = RxTotalByteCountLocal;
if (RxSegment.length) {
RxRemainHexdump.value = u8toHexdump(RxSegment);
} else {
RxRemainHexdump.value = "";
}
}, 200);
function addString(item: string, isRX: boolean = false, doSend: boolean = false, type: number = 0) {
const encoder = new TextEncoder();
@ -594,8 +613,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
// });
if (isRX) {
RxTotalByteCount.value += item.length;
RxByteCount.value = item.length;
RxTotalByteCountLocal += item.length;
RxByteCountLocal = item.length;
} else {
/* append prefix and suffix */
if (computedPrefixValue.value.length || computedSuffixValue.value.length) {
@ -614,8 +633,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
} else {
type = 1;
}
TxTotalByteCount.value += item.length;
TxByteCount.value = item.length;
TxTotalByteCountLocal += item.length;
TxByteCountLocal = item.length;
}
let str = ""
@ -722,9 +741,9 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
function clearByteCount(isRX: boolean) {
if (isRX) {
RxTotalByteCount.value = 0;
RxTotalByteCountLocal = 0;
} else {
TxTotalByteCount.value = 0;
TxTotalByteCountLocal = 0;
}
}
@ -734,11 +753,13 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
dataBufLength.value = 0;
batchStartIndex = 0;
RxByteCount.value = 0;
RxTotalByteCount.value = 0;
RxByteCountLocal = 0;
RxTotalByteCountLocal = 0;
TxByteCountLocal = 0;
TxTotalByteCountLocal = 0;
TxByteCount.value = 0;
TxTotalByteCount.value = 0;
RxSegment = new Uint8Array();
RxRemainHexdump.value = "";
}
function clearFilteredBuff() {

View File

@ -103,8 +103,8 @@
:class="[store.enableLineWrap ? 'break-all' : 'text-nowrap']"
>
<template v-slot:default="{ item, }">
<div>
<div class="flex">
<div class="">
<div class="flex" :class="[store.enableLineWrap ? 'whitespace-pre-wrap' : 'whitespace-pre']">
<p class="text-nowrap text-sm text-lime-500" v-if="item.isRX" type="success" v-show="store.showTimestamp">
<span>{{ item.time }}</span>-RX|</p>
<p class="text-nowrap text-sm text-sky-500" v-else-if="item.type === 0" type="primary" v-show="store.showTimestamp">
@ -115,10 +115,10 @@
<p v-show="store.showText"
v-html="item.str"></p>
</div>
<div class="flex text-wrap">
<div class="flex">
<p v-show="store.showHex" class="">{{ item.hex }}</p>
</div>
<div class="flex">
<div class="flex whitespace-pre">
<p v-show="store.showHexdump"
class="text-nowrap"
:style="{ 'background-color': item.isRX ? store.RxHexdumpColor : store.TxHexdumpColor }"
@ -138,7 +138,7 @@
>
<template v-slot:default="{ item, }">
<div>
<div class="flex">
<div class="flex" :class="[store.enableLineWrap ? 'whitespace-pre-wrap' : 'whitespace-pre']">
<p class="text-nowrap text-sm text-lime-500" v-if="item.isRX" type="success" v-show="store.showTimestamp">
<span>{{ item.time }}</span>-RX|</p>
<p class="text-nowrap text-sm text-sky-500" v-else-if="item.type === 0" type="primary" v-show="store.showTimestamp">
@ -148,10 +148,10 @@
<p v-show="store.showText"
v-html="item.str"></p>
</div>
<div class="flex text-wrap">
<div class="flex">
<p v-show="store.showHex" class="">{{ item.hex }}</p>
</div>
<div class="flex">
<div class="flex whitespace-pre">
<p v-show="store.showHexdump"
class="text-nowrap"
:style="{ 'background-color': item.isRX ? store.RxHexdumpColor : store.TxHexdumpColor }"
@ -165,7 +165,7 @@
<div class="shrink-0 flex max-h-14 mt-0.5 text-xs">
<div class="flex shrink-0">
<el-tooltip content="未满足断帧规则的数据(如:未超时),暂时实时显示在此区域。" effect="light">
<el-tooltip content="未满足断帧规则的数据(如:未超时),暂时实时显示在此区域。超过8192字节自动断帧" effect="light">
<InlineSvg name="help" class="w-3.5 h-3.5 text-gray-500 cursor-help"></InlineSvg>
</el-tooltip>
<p></p>
@ -209,12 +209,12 @@
<div class="flex gap-2">
<el-link>
<el-tag class="font-mono font-bold" size="small">
{{ `TX:${store.TxByteCount}B/${store.TxTotalByteCount}B` }}
{{ `TX(B):${store.TxByteCount}/ ${store.TxTotalByteCount}` }}
</el-tag>
</el-link>
<el-link type="success">
<el-tag class="font-mono font-bold" size="small" type="success">
{{ `RX:${store.RxByteCount}B/${store.RxTotalByteCount}B` }}
{{ `RX(B):${store.RxByteCount}/ ${store.RxTotalByteCount}` }}
</el-tag>
</el-link>
<div class="flex align-center">
@ -222,7 +222,7 @@
<el-link class="flex" @click="store.clearDataBuff" type="warning">
<InlineSvg class="h-5" name="trash"></InlineSvg>
</el-link>
<span class="align-text-bottom">缓存帧数: {{ store.dataBufLength }}/20000</span>
<span class="align-text-bottom">缓存帧数: {{ store.dataBufLength }}/30000</span>
</el-tag>
</div>
</div>
@ -336,8 +336,7 @@ function addItem(nr: number) {
function scrollToBottom() {
nextTick(() => {
const scrollerElement = vuetifyVirtualScrollBarRef.value; // Adjust according to your setup
// scrollerElement.scrollTop = scrollerElement.scrollHeight;
scrollerElement.scrollTo(scrollerElement.scrollLeft, scrollerElement.scrollHeight);
scrollerElement.scrollTop = scrollerElement.scrollHeight;
});
}
@ -428,6 +427,12 @@ watch(() => store.filterChanged, (value) => {
}
})
watch(() => store.showVirtualScroll, () => {
if (store.forceToBottom) {
scrollToBottom();
}
});
const handleScroll = (ev: Event) => {
if (store.forceToBottom) {
if (vuetifyVirtualScrollBarRef.value.scrollTop - lastScrollHeight < 0) {