From 3aedad63dd01f1fc5154cb520af32edab967d6e0 Mon Sep 17 00:00:00 2001
From: schangxiang@126.com <schangxiang@126.com>
Date: 周一, 12 5月 2025 09:15:26 +0800
Subject: [PATCH] Merge branch 'master' of http://222.71.245.114:9086/r/HIA24016N_PipeLineDemo
---
PipeLineLems/pipelinelems_web/src/widgets/Http/components/InputCode.vue | 242 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 242 insertions(+), 0 deletions(-)
diff --git a/PipeLineLems/pipelinelems_web/src/widgets/Http/components/InputCode.vue b/PipeLineLems/pipelinelems_web/src/widgets/Http/components/InputCode.vue
new file mode 100644
index 0000000..39fb085
--- /dev/null
+++ b/PipeLineLems/pipelinelems_web/src/widgets/Http/components/InputCode.vue
@@ -0,0 +1,242 @@
+<!--
+
+v-model="鍙屽悜缁戝畾"
+
+:modelValue="琛ㄨ揪寮�"
+@update:modelValue="(淇敼鍚庣殑琛ㄨ揪寮�)=>{}"
+
+inputCodeRef.insertCode('鍦ㄧ劍鐐瑰鎻掑叆浠g爜')
+
+@update:focusWord="(鍏夋爣澶勭殑鍗曡瘝)=>{}"
+
+ -->
+<template>
+ <div class="inputCode">
+ <div
+ ref="inputEl"
+ class="input"
+ :contenteditable="(contentEditable as any)"
+ spellcheck="false"
+ @input="input"
+ @click="click"
+ .onblur="saveRange"
+ ></div>
+ <div class="highlight" v-html="codeHighlighted"></div>
+ </div>
+</template>
+<script setup lang="ts">
+import { computed, defineEmits, ref, watch } from 'vue'
+
+const props = defineProps(['modelValue'])
+const emit = defineEmits(['update:modelValue', 'update:focusWord'])
+
+// code ----------------------------------------
+
+let code = ref('')
+watch(
+ () => props.modelValue,
+ () => {
+ code.value = props.modelValue || ''
+ },
+ { immediate: true }
+)
+
+// inputEl ----------------------------------------
+
+let inputEl = ref()
+const contentEditable = 'plaintext-only'
+
+function updateInputInnerText() {
+ if (!inputEl) {
+ return
+ }
+
+ // 閬垮厤褰卞搷鍏夋爣
+ if (getInnerText() === code.value) return
+
+ inputEl.value.innerText = code.value
+}
+
+function getInnerText() {
+ const innerText = inputEl.value?.innerText || ''
+ return fixInnerTextLn(innerText)
+}
+
+// 闈� 'plaintext-only' innerText \n 浼氭瘮椤甸潰涓婄殑澶�
+// 1 1
+// 2 3
+// 3 5
+function fixInnerTextLn(innerText: string) {
+ if (inputEl.value?.contentEditable === contentEditable) {
+ return innerText
+ }
+
+ return innerText.replace(/\n+/g, function ($and) {
+ const length = $and.split('').length
+ const lengthFixed = Math.floor((length + 1) / 2)
+
+ return Array(lengthFixed).fill('\n').join('')
+ })
+}
+
+// highlight ----------------------------------------
+
+let codeHighlighted = computed(() => {
+ updateInputInnerText()
+ return highlight(code.value)
+})
+
+function highlight(value: string) {
+ let html = value
+
+ html = html
+ .replace(/\b(true|false)\b/g, '馃懢b $& b馃懢')
+ .replace(/\b[\d.]+/gi, '馃懢n $& n馃懢') // number
+ .replace(/"(\\.|.)*?"/gi, '馃懢s $& s馃懢') // string
+ .replace(/[!%^&*\-+=|<>/]+/gi, '馃懢p $& p馃懢') // +
+ .replace(/\b(\w+)\s*(?=\()/gi, '馃懢f $& f馃懢') // function()
+ .replace(/\[.*?\]/gi, '馃懢k $& k馃懢') // [field]
+
+ html = html.replace(/</g, '<').replace(/>/g, '>')
+
+ html = html
+ .replace(/馃懢b (.*?) b馃懢/g, '<span style="color:#fe72f3">$1</span>')
+ .replace(/馃懢n (.*?) n馃懢/g, '<span style="color:#57b6ff">$1</span>')
+ .replace(/馃懢s (.*?) s馃懢/g, '<span style="color:#ffff66">$1</span>')
+ .replace(/馃懢p (.*?) p馃懢/g, '<span style="color:#9B9B9B">$1</span>')
+ .replace(/馃懢f (.*?) f馃懢/g, '<span style="color:#23DBBB">$1</span>')
+ .replace(/馃懢k (.*?) k馃懢/g, '<span style="color:#febf72">$1</span>')
+
+ html = html.replace(/\n/g, '<br />')
+
+ return html
+}
+
+// emit ----------------------------------------
+
+function input() {
+ code.value = getInnerText()
+ emit('update:modelValue', code.value)
+ emit('update:focusWord', getFocusWord())
+}
+
+function click() {
+ emit('update:focusWord', getFocusWord())
+}
+
+// insertCode ----------------------------------------
+
+let range: Range | undefined
+function saveRange() {
+ const selection = document.getSelection()
+ range = selection?.getRangeAt(0)
+}
+
+function insertCode(text: string) {
+ if (!inputEl) {
+ console.warn('!inputEl')
+ return
+ }
+
+ const selection = document.getSelection()
+ if (!selection) return
+
+ if (!range) {
+ range = new Range()
+ range.selectNodeContents(inputEl.value)
+ range.collapse()
+ }
+
+ selection.removeAllRanges()
+ selection.addRange(range)
+
+ // range.deleteContents()
+ // range.insertNode(document.createTextNode(text))
+ // range.collapse()
+
+ document.execCommand('insertText', false, text)
+
+ // fun( | )
+ if (/\)$/.test(text)) {
+ const rangeCurrent = selection.getRangeAt(0)
+ rangeCurrent.setEnd(rangeCurrent.endContainer, rangeCurrent.endOffset - 2)
+
+ selection.removeAllRanges()
+ selection.addRange(rangeCurrent)
+ }
+
+ input()
+}
+
+// focusWord ----------------------------------------
+
+function getFocusWord() {
+ const range = document.getSelection()?.getRangeAt(0)
+ if (!range) return
+
+ const node = range.endContainer
+ const text = node.nodeValue || ''
+ const left = text.slice(0, range.endOffset)
+ const right = text.slice(range.endOffset)
+ const l = left.match(/\w+$/)?.[0] || ''
+ const r = right.match(/^\w+/)?.[0] || ''
+
+ return l + r
+}
+
+defineExpose({
+ insertCode,
+ getFocusWord,
+})
+</script>
+
+<style lang="scss" scoped>
+.inputCode {
+ position: relative;
+ width: 100%;
+ height: 220px;
+ min-height: 42px;
+ background: #262c33;
+ border-radius: 6px 6px 6px 6px;
+ color: #f00;
+ color: transparent;
+ resize: none;
+ white-space: pre;
+ caret-color: #fff;
+ overflow: auto;
+ &:hover,
+ &:active {
+ resize: vertical;
+ }
+
+ outline: solid 1px transparent;
+ outline-offset: -1px;
+ transition: 0.5s outline;
+ &:focus-within {
+ outline-color: #707070;
+ }
+
+ .input {
+ outline: none;
+ min-height: 100%;
+ padding: 10px;
+ &[contenteditable='plaintext-only'] {
+ -webkit-user-modify: read-write-plaintext-only;
+ }
+ &::selection {
+ background-color: rgba(255, 255, 255, 0.25);
+ }
+ }
+ .highlight {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ padding: 10px;
+ pointer-events: none;
+ color: #febf72;
+ color: #fff;
+ // margin-top: 50px;
+ }
+}
+</style>
--
Gitblit v1.9.3