diff --git a/dev_log/2.1.362/daoqgong_202112211913.yaml b/dev_log/2.1.362/daoqgong_202112211913.yaml new file mode 100644 index 000000000..b263d9844 --- /dev/null +++ b/dev_log/2.1.362/daoqgong_202112211913.yaml @@ -0,0 +1,3 @@ +--- +bugfix: + - "Firefox 浏览器粘贴 IP 解析错误 (close #378)" diff --git a/frontend/src/views/agent/agent-list.vue b/frontend/src/views/agent/agent-list.vue index 3894b2713..86d74f02b 100644 --- a/frontend/src/views/agent/agent-list.vue +++ b/frontend/src/views/agent/agent-list.vue @@ -1622,64 +1622,71 @@ export default class AgentList extends Mixins(pollMixin, TableHeaderMixins, auth /** * search select复制逻辑 */ - private handlePaste(e: { target: EventTarget, clipboardData: any }) { - const [data] = e.clipboardData.items; - data.getAsString((value: string) => { - // 已选择特定类型的情况下 - 保持原有的粘贴行为(排除IP类型的粘贴) - if (this.searchSelect.input) { - let selectionText = (window.getSelection() as Dictionary).toString(); // 鼠标选中的文本 - const regExpChar = /[\\^$.*+?()[\]{}|]/g; - const hasRegExpChar = new RegExp(regExpChar.source); - selectionText = selectionText.replace(hasRegExpChar, ''); - const inputValue = selectionText && !isEmpty(this.searchSelect.input.value) - ? this.searchSelect.input.value.replace(new RegExp(selectionText), '') - : this.searchSelect.input.value || ''; + private handlePaste(e: { target: EventTarget, clipboardData: any, originalEvent?: any }) { + let value = ''; + try { + const clp = (e.originalEvent || e).clipboardData; + if (clp === undefined || clp === null) { // 兼容针对于opera ie等浏览器 + value = window.clipboardData.getData('text') || ''; + } else { + value = clp.getData('text/plain') || ''; // 兼容Chrome Firefox + } + } catch (err) {} - const str = value.replace(/;+|;+|_+|\\+|,+|,+|、+|\s+/g, ',').replace(/,+/g, ' ') - .trim(); - const tmpStr = str.trim().split(' '); - const isIp = tmpStr.every(item => this.ipRegx.test(item)); - let backfillValue = inputValue + value; - if (isIp || !!inputValue) { - if (isIp) { - backfillValue = ''; - this.handlePushValue('inner_ip', tmpStr.map(ip => ({ id: ip, name: ip, checked: false }))); - this.handleValueChange(); - } - Object.assign(e.target, { innerText: backfillValue }); // 数据清空或合并 - this.searchSelect.handleInputChange(e); // 回填并响应数据 - this.searchSelect.handleInputFocus(e); // contenteditable类型 - 光标移动到最后 - } else { - let directFilling = true; - const pairArr = backfillValue.replace(/:+|:+/g, ' ').trim() - .split(' '); - if (pairArr.length > 1) { - const [name, ...valueText] = pairArr; - const category = this.filterData.find(item => item.name === name); - if (category) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { children, ...other } = category; - directFilling = false; - this.searchSelectValue.push({ - ...other, - values: [{ id: valueText.join(''), name: valueText.join(''), checked: false }], - }); - Object.assign(e.target, { innerText: '' }); // 数据清空或合并 - this.searchSelect.handleInputChange(e); // 回填并响应数据 - this.searchSelect.handleInputOutSide(e); - } - } - this.searchSelect.handleInputChange(e); // 回填并响应数据 - if (directFilling) { + // 已选择特定类型的情况下 - 保持原有的粘贴行为(排除IP类型的粘贴) + if (value.trim() && this.searchSelect.input) { + let selectionText = (window.getSelection() as Dictionary).toString(); // 鼠标选中的文本 + const regExpChar = /[\\^$.*+?()[\]{}|]/g; + const hasRegExpChar = new RegExp(regExpChar.source); + selectionText = selectionText.replace(hasRegExpChar, ''); + const inputValue = selectionText && !isEmpty(this.searchSelect.input.value) + ? this.searchSelect.input.value.replace(new RegExp(selectionText), '') + : this.searchSelect.input.value || ''; + + const str = value.replace(/;+|;+|_+|\\+|,+|,+|、+|\s+/g, ',').replace(/,+/g, ' ') + .trim(); + const tmpStr = str.trim().split(' '); + const isIp = tmpStr.every(item => this.ipRegx.test(item)); + let backfillValue = inputValue + value; + if (isIp || !!inputValue) { + if (isIp) { + backfillValue = ''; + this.handlePushValue('inner_ip', tmpStr.map(ip => ({ id: ip, name: ip, checked: false }))); + this.handleValueChange(); + } + Object.assign(e.target, { innerText: backfillValue }); // 数据清空或合并 + this.searchSelect.handleInputChange(e); // 回填并响应数据 + this.searchSelect.handleInputFocus(e); // contenteditable类型 - 光标移动到最后 + } else { + let directFilling = true; + const pairArr = backfillValue.replace(/:+|:+/g, ' ').trim() + .split(' '); + if (pairArr.length > 1) { + const [name, ...valueText] = pairArr; + const category = this.filterData.find(item => item.name === name); + if (category) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { children, ...other } = category; + directFilling = false; this.searchSelectValue.push({ - id: str.trim().replace('\n', ''), - name: str.trim().replace('\n', ''), + ...other, + values: [{ id: valueText.join(''), name: valueText.join(''), checked: false }], }); + Object.assign(e.target, { innerText: '' }); // 数据清空或合并 + this.searchSelect.handleInputChange(e); // 回填并响应数据 + this.searchSelect.handleInputOutSide(e); } - this.handleValueChange(); } + this.searchSelect.handleInputChange(e); // 回填并响应数据 + if (directFilling) { + this.searchSelectValue.push({ + id: str.trim().replace('\n', ''), + name: str.trim().replace('\n', ''), + }); + } + this.handleValueChange(); } - }); + } } /** * agent 版本排序 diff --git a/frontend/src/views/plugin/plugin-list/plugin-list-operate.vue b/frontend/src/views/plugin/plugin-list/plugin-list-operate.vue index 72d8c15a5..ac07b610a 100644 --- a/frontend/src/views/plugin/plugin-list/plugin-list-operate.vue +++ b/frontend/src/views/plugin/plugin-list/plugin-list-operate.vue @@ -188,63 +188,70 @@ export default class PluginListOperate extends Mixins(HeaderFilterMixins) { } public handlePaste(e: any): void { - const [data]: any = e.clipboardData.items; - data.getAsString((value: string) => { - // 已选择特定类型的情况下 - 保持原有的粘贴行为(排除IP类型的粘贴) - if (this.searchSelect.input) { - let selectionText = (window.getSelection() as Dictionary).toString(); // 鼠标选中的文本 - const regExpChar = /[\\^$.*+?()[\]{}|]/g; - const hasRegExpChar = new RegExp(regExpChar.source); - selectionText = selectionText.replace(hasRegExpChar, ''); - const inputValue = selectionText && !isEmpty(this.searchSelect.input.value) - ? this.searchSelect.input.value.replace(new RegExp(selectionText), '') - : this.searchSelect.input.value || ''; + let value = ''; + try { + const clp = (e.originalEvent || e).clipboardData; + if (clp === undefined || clp === null) { // 兼容针对于opera ie等浏览器 + value = window.clipboardData.getData('text') || ''; + } else { + value = clp.getData('text/plain') || ''; // 兼容Chrome Firefox + } + } catch (err) {} - const str = value.replace(/;+|;+|_+|\\+|,+|,+|、+|\s+/g, ',').replace(/,+/g, ' ') - .trim(); - const tmpStr = str.trim().split(' '); - const isIp = tmpStr.every(item => this.ipRegx.test(item)); - let backfillValue = inputValue + value; - if (isIp || !!inputValue) { - if (isIp) { - backfillValue = ''; - this.handlePushValue('inner_ip', tmpStr.map(ip => ({ id: ip, name: ip, checked: false }))); - this.handleValueChange(); - } - Object.assign(e.target, { innerText: backfillValue }); // 数据清空或合并 - this.searchSelect.handleInputChange(e); // 回填并响应数据 - this.searchSelect.handleInputFocus(e); // contenteditable类型 - 光标移动到最后 - } else { - let directFilling = true; - const pairArr = backfillValue.replace(/:+|:+/g, ' ').trim() - .split(' '); - if (pairArr.length > 1) { - const [name, ...valueText] = pairArr; - const category = this.filterData.find(item => item.name === name); - if (category) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { children, ...other } = category; - directFilling = false; - this.searchSelectValue.push({ - ...other, - values: [{ id: valueText.join(''), name: valueText.join(''), checked: false }], - }); - Object.assign(e.target, { innerText: '' }); // 数据清空或合并 - this.searchSelect.handleInputChange(e); // 回填并响应数据 - this.searchSelect.handleInputOutSide(e); - } - } - this.searchSelect.handleInputChange(e); // 回填并响应数据 - if (directFilling) { + // 已选择特定类型的情况下 - 保持原有的粘贴行为(排除IP类型的粘贴) + if (value.trim() && this.searchSelect.input) { + let selectionText = (window.getSelection() as Dictionary).toString(); // 鼠标选中的文本 + const regExpChar = /[\\^$.*+?()[\]{}|]/g; + const hasRegExpChar = new RegExp(regExpChar.source); + selectionText = selectionText.replace(hasRegExpChar, ''); + const inputValue = selectionText && !isEmpty(this.searchSelect.input.value) + ? this.searchSelect.input.value.replace(new RegExp(selectionText), '') + : this.searchSelect.input.value || ''; + + const str = value.replace(/;+|;+|_+|\\+|,+|,+|、+|\s+/g, ',').replace(/,+/g, ' ') + .trim(); + const tmpStr = str.trim().split(' '); + const isIp = tmpStr.every(item => this.ipRegx.test(item)); + let backfillValue = inputValue + value; + if (isIp || !!inputValue) { + if (isIp) { + backfillValue = ''; + this.handlePushValue('inner_ip', tmpStr.map(ip => ({ id: ip, name: ip, checked: false }))); + this.handleValueChange(); + } + Object.assign(e.target, { innerText: backfillValue }); // 数据清空或合并 + this.searchSelect.handleInputChange(e); // 回填并响应数据 + this.searchSelect.handleInputFocus(e); // contenteditable类型 - 光标移动到最后 + } else { + let directFilling = true; + const pairArr = backfillValue.replace(/:+|:+/g, ' ').trim() + .split(' '); + if (pairArr.length > 1) { + const [name, ...valueText] = pairArr; + const category = this.filterData.find(item => item.name === name); + if (category) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { children, ...other } = category; + directFilling = false; this.searchSelectValue.push({ - id: str.trim().replace('\n', ''), - name: str.trim().replace('\n', ''), + ...other, + values: [{ id: valueText.join(''), name: valueText.join(''), checked: false }], }); + Object.assign(e.target, { innerText: '' }); // 数据清空或合并 + this.searchSelect.handleInputChange(e); // 回填并响应数据 + this.searchSelect.handleInputOutSide(e); } - this.handleValueChange(); } + this.searchSelect.handleInputChange(e); // 回填并响应数据 + if (directFilling) { + this.searchSelectValue.push({ + id: str.trim().replace('\n', ''), + name: str.trim().replace('\n', ''), + }); + } + this.handleValueChange(); } - }); + } } @Emit('plugin-operate')