mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 优化选择面板、查找面板交互,添加查找忽略大小写开关(#231)
This commit is contained in:
parent
6aa6acaafa
commit
3450843878
@ -18,6 +18,8 @@ interface SearchTableResult {
|
||||
|
||||
type SearchResult = SearchTextResult | SearchTableResult
|
||||
|
||||
type Modifiers = 'g' | 'gi'
|
||||
|
||||
export default () => {
|
||||
const mainStore = useMainStore()
|
||||
const slidesStore = useSlidesStore()
|
||||
@ -28,10 +30,12 @@ export default () => {
|
||||
const replaceWord = ref('')
|
||||
const searchResults = ref<SearchResult[]>([])
|
||||
const searchIndex = ref(-1)
|
||||
|
||||
const modifiers = ref<Modifiers>('g')
|
||||
|
||||
const search = () => {
|
||||
const textList: SearchResult[] = []
|
||||
const matchRegex = new RegExp(searchWord.value, 'g')
|
||||
const matchRegex = new RegExp(searchWord.value, modifiers.value)
|
||||
const textRegex = /(<([^>]+)>)/g
|
||||
|
||||
for (const slide of slides.value) {
|
||||
@ -116,7 +120,7 @@ export default () => {
|
||||
type TextInfoList = ReturnType<typeof getTextInfoList>
|
||||
|
||||
const getMatchList = (content: string, keyword: string) => {
|
||||
const reg = new RegExp(keyword, 'g')
|
||||
const reg = new RegExp(keyword, modifiers.value)
|
||||
const matchList = []
|
||||
let match = reg.exec(content)
|
||||
while (match) {
|
||||
@ -154,7 +158,7 @@ export default () => {
|
||||
|
||||
const highlightTableText = (nodes: NodeListOf<Element>, index: number) => {
|
||||
for (const node of nodes) {
|
||||
node.innerHTML = node.innerHTML.replace(new RegExp(searchWord.value, 'g'), () => {
|
||||
node.innerHTML = node.innerHTML.replace(new RegExp(searchWord.value, modifiers.value), () => {
|
||||
return `<mark data-index=${index++}>${searchWord.value}</mark>`
|
||||
})
|
||||
}
|
||||
@ -393,13 +397,15 @@ export default () => {
|
||||
searchResults.value = []
|
||||
searchIndex.value = -1
|
||||
}
|
||||
|
||||
watch(searchWord, () => {
|
||||
|
||||
const reset = () => {
|
||||
searchIndex.value = -1
|
||||
searchResults.value = []
|
||||
|
||||
if (!searchWord.value) clearMarks()
|
||||
})
|
||||
}
|
||||
|
||||
watch(searchWord, reset)
|
||||
|
||||
watch(slideIndex, () => {
|
||||
nextTick(() => {
|
||||
@ -417,15 +423,22 @@ export default () => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(clearMarks)
|
||||
|
||||
const toggleModifiers = () => {
|
||||
modifiers.value = modifiers.value === 'g' ? 'gi' : 'g'
|
||||
reset()
|
||||
}
|
||||
|
||||
return {
|
||||
searchWord,
|
||||
replaceWord,
|
||||
searchResults,
|
||||
searchIndex,
|
||||
modifiers,
|
||||
searchNext,
|
||||
searchPrev,
|
||||
replace,
|
||||
replaceAll,
|
||||
toggleModifiers,
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
<IconBack class="handler-item" :class="{ 'disable': !canUndo }" v-tooltip="'撤销'" @click="undo()" />
|
||||
<IconNext class="handler-item" :class="{ 'disable': !canRedo }" v-tooltip="'重做'" @click="redo()" />
|
||||
<Divider type="vertical" style="height: 20px;" />
|
||||
<IconMoveOne class="handler-item" v-tooltip="'选择窗格'" @click="openSelectPanel()" />
|
||||
<IconSearch class="handler-item" v-tooltip="'查找/替换'" @click="openSraechPanel()" />
|
||||
<IconMoveOne class="handler-item" :class="{ 'active': showSelectPanel }" v-tooltip="'选择窗格'" @click="toggleSelectPanel()" />
|
||||
<IconSearch class="handler-item" :class="{ 'active': showSearchPanel }" v-tooltip="'查找/替换'" @click="toggleSraechPanel()" />
|
||||
</div>
|
||||
|
||||
<div class="add-element-handler">
|
||||
@ -116,7 +116,7 @@ import Popover from '@/components/Popover.vue'
|
||||
import PopoverMenuItem from '@/components/PopoverMenuItem.vue'
|
||||
|
||||
const mainStore = useMainStore()
|
||||
const { creatingElement, creatingCustomShape } = storeToRefs(mainStore)
|
||||
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel } = storeToRefs(mainStore)
|
||||
const { canUndo, canRedo } = storeToRefs(useSnapshotStore())
|
||||
|
||||
const { redo, undo } = useHistorySnapshot()
|
||||
@ -191,13 +191,13 @@ const drawLine = (line: LinePoolItem) => {
|
||||
}
|
||||
|
||||
// 打开选择面板
|
||||
const openSelectPanel = () => {
|
||||
mainStore.setSelectPanelState(true)
|
||||
const toggleSelectPanel = () => {
|
||||
mainStore.setSelectPanelState(!showSelectPanel.value)
|
||||
}
|
||||
|
||||
// 打开搜索替换面板
|
||||
const openSraechPanel = () => {
|
||||
mainStore.setSearchPanelState(true)
|
||||
const toggleSraechPanel = () => {
|
||||
mainStore.setSearchPanelState(!showSearchPanel.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -289,6 +289,7 @@ const openSraechPanel = () => {
|
||||
.handler-item {
|
||||
padding: 0 8px;
|
||||
|
||||
&.active,
|
||||
&:not(.disable):hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<MoveablePanel
|
||||
class="search-panel"
|
||||
:width="300"
|
||||
:width="330"
|
||||
:height="0"
|
||||
:left="-270"
|
||||
:top="90"
|
||||
@ -17,8 +17,14 @@
|
||||
<template #suffix>
|
||||
<span class="count">{{searchIndex + 1}}/{{searchResults.length}}</span>
|
||||
<Divider type="vertical" />
|
||||
<IconLeft class="next-btn left" @click="searchPrev()" />
|
||||
<IconRight class="next-btn right" @click="searchNext()" />
|
||||
<span class="ignore-case"
|
||||
:class="{ 'active': modifiers === 'g' }"
|
||||
v-tooltip="'忽略大小写'"
|
||||
@click="toggleModifiers()"
|
||||
>Aa</span>
|
||||
<Divider type="vertical" />
|
||||
<IconLeft class="next-btn left" @click="searchPrev()" v-tooltip="'上一个'" />
|
||||
<IconRight class="next-btn right" @click="searchNext()" v-tooltip="'下一个'" />
|
||||
</template>
|
||||
</Input>
|
||||
<Input class="input" v-model:value="replaceWord" placeholder="输入替换内容" @enter="replace()" v-if="type === 'replace'"></Input>
|
||||
@ -53,10 +59,12 @@ const {
|
||||
replaceWord,
|
||||
searchResults,
|
||||
searchIndex,
|
||||
modifiers,
|
||||
searchNext,
|
||||
searchPrev,
|
||||
replace,
|
||||
replaceAll,
|
||||
toggleModifiers,
|
||||
} = useSearch()
|
||||
|
||||
const type = ref<TypeKey>('search')
|
||||
@ -98,6 +106,15 @@ watch(type, () => {
|
||||
margin-right: 8px;
|
||||
user-select: none;
|
||||
}
|
||||
.ignore-case {
|
||||
font-size: 12px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: $themeColor;
|
||||
}
|
||||
}
|
||||
.next-btn {
|
||||
width: 22px;
|
||||
height: 100%;
|
||||
|
Loading…
x
Reference in New Issue
Block a user