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, '&lt;').replace(/>/g, '&gt;')
+
+  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