fix: 执行lint,调整书写格式
This commit is contained in:
@@ -92,7 +92,7 @@ export default {
|
|||||||
username: '',
|
username: '',
|
||||||
pin: '',
|
pin: '',
|
||||||
language: '',
|
language: '',
|
||||||
licenseStatus: -1,//-1 未获取后台数据状态;0 获取后台数据且验证成功;1 获取后台数据且验证失败;
|
licenseStatus: -1, // -1 未获取后台数据状态;0 获取后台数据且验证成功;1 获取后台数据且验证失败;
|
||||||
licenseStatusErrMsg: '',
|
licenseStatusErrMsg: '',
|
||||||
downloadC2vUrl: api.downloadLicenseC2v,
|
downloadC2vUrl: api.downloadLicenseC2v,
|
||||||
supportID: ''
|
supportID: ''
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -12,11 +12,13 @@ export default function createHint (hitType = 'default', CodeMirror, {
|
|||||||
keyboardDown,
|
keyboardDown,
|
||||||
keyboardEnter
|
keyboardEnter
|
||||||
}) {
|
}) {
|
||||||
hitType === 'default' ? showHint(CodeMirror) : manualShowHint(CodeMirror, {
|
hitType === 'default'
|
||||||
cb: callback,
|
? showHint(CodeMirror)
|
||||||
keyboardUp,
|
: manualShowHint(CodeMirror, {
|
||||||
keyboardDown,
|
cb: callback,
|
||||||
keyboardEnter
|
keyboardUp,
|
||||||
})
|
keyboardDown,
|
||||||
|
keyboardEnter
|
||||||
|
})
|
||||||
sqlHint(CodeMirror, { dataset, hinthook, keywordshook })
|
sqlHint(CodeMirror, { dataset, hinthook, keywordshook })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
export default function (CodeMirror,{
|
export default function (CodeMirror, {
|
||||||
cb,
|
cb,
|
||||||
keyboardUp,
|
keyboardUp,
|
||||||
keyboardDown,
|
keyboardDown,
|
||||||
keyboardEnter
|
keyboardEnter
|
||||||
}) {
|
}) {
|
||||||
var HINT_ELEMENT_CLASS = 'CodeMirror-hint'
|
const HINT_ELEMENT_CLASS = 'CodeMirror-hint'
|
||||||
var ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
|
const ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
|
||||||
|
|
||||||
// This is the old interface, kept around for now to stay
|
// This is the old interface, kept around for now to stay
|
||||||
// backwards-compatible.
|
// backwards-compatible.
|
||||||
CodeMirror.showHint = function (cm, getHints, options) {
|
CodeMirror.showHint = function (cm, getHints, options) {
|
||||||
if (!getHints) return cm.showHint(options)
|
if (!getHints) return cm.showHint(options)
|
||||||
if (options && options.async) getHints.async = true
|
if (options && options.async) getHints.async = true
|
||||||
var newOpts = { hint: getHints }
|
const newOpts = { hint: getHints }
|
||||||
if (options) for (var prop in options) newOpts[prop] = options[prop]
|
if (options) for (const prop in options) newOpts[prop] = options[prop]
|
||||||
return cm.showHint(newOpts)
|
return cm.showHint(newOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.defineExtension('showHint', function (options) {
|
CodeMirror.defineExtension('showHint', function (options) {
|
||||||
options = parseOptions(this, this.getCursor('start'), options)
|
options = parseOptions(this, this.getCursor('start'), options)
|
||||||
var selections = this.listSelections()
|
const selections = this.listSelections()
|
||||||
if (selections.length > 1) return
|
if (selections.length > 1) return
|
||||||
// By default, don't allow completion when something is selected.
|
// By default, don't allow completion when something is selected.
|
||||||
// A hint function can have a `supportsSelection` property to
|
// A hint function can have a `supportsSelection` property to
|
||||||
@@ -27,7 +27,7 @@ export default function (CodeMirror,{
|
|||||||
if (this.somethingSelected()) {
|
if (this.somethingSelected()) {
|
||||||
if (!options.hint.supportsSelection) return
|
if (!options.hint.supportsSelection) return
|
||||||
// Don't try with cross-line selections
|
// Don't try with cross-line selections
|
||||||
for (var i = 0; i < selections.length; i++) {
|
for (let i = 0; i < selections.length; i++) {
|
||||||
if (selections[i].head.line != selections[i].anchor.line) return
|
if (selections[i].head.line != selections[i].anchor.line) return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,17 +55,17 @@ export default function (CodeMirror,{
|
|||||||
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length
|
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length
|
||||||
|
|
||||||
if (this.options.updateOnCursorActivity) {
|
if (this.options.updateOnCursorActivity) {
|
||||||
var self = this
|
const self = this
|
||||||
cm.on('cursorActivity', this.activityFunc = function () {
|
cm.on('cursorActivity', this.activityFunc = function () {
|
||||||
self.cursorActivity()
|
self.cursorActivity()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestAnimationFrame = window.requestAnimationFrame || function (fn) {
|
const requestAnimationFrame = window.requestAnimationFrame || function (fn) {
|
||||||
return setTimeout(fn, 1000 / 60)
|
return setTimeout(fn, 1000 / 60)
|
||||||
}
|
}
|
||||||
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
|
const cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
|
||||||
|
|
||||||
Completion.prototype = {
|
Completion.prototype = {
|
||||||
close: function () {
|
close: function () {
|
||||||
@@ -116,7 +116,7 @@ export default function (CodeMirror,{
|
|||||||
this.debounce = 0
|
this.debounce = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var identStart = this.startPos
|
let identStart = this.startPos
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
identStart = this.data.from
|
identStart = this.data.from
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ export default function (CodeMirror,{
|
|||||||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
||||||
this.close()
|
this.close()
|
||||||
} else {
|
} else {
|
||||||
var self = this
|
const self = this
|
||||||
this.debounce = requestAnimationFrame(function () {
|
this.debounce = requestAnimationFrame(function () {
|
||||||
self.update()
|
self.update()
|
||||||
})
|
})
|
||||||
@@ -137,7 +137,7 @@ export default function (CodeMirror,{
|
|||||||
|
|
||||||
update: function (first) {
|
update: function (first) {
|
||||||
if (this.tick == null) return
|
if (this.tick == null) return
|
||||||
var self = this, myTick = ++this.tick
|
const self = this; const myTick = ++this.tick
|
||||||
fetchHints(this.options.hint, this.cm, this.options, function (data) {
|
fetchHints(this.options.hint, this.cm, this.options, function (data) {
|
||||||
if (self.tick == myTick) self.finishUpdate(data, first)
|
if (self.tick == myTick) self.finishUpdate(data, first)
|
||||||
})
|
})
|
||||||
@@ -189,7 +189,7 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildKeyMap (completion, handle) {
|
function buildKeyMap (completion, handle) {
|
||||||
var baseMap = {
|
const baseMap = {
|
||||||
Up: function () {
|
Up: function () {
|
||||||
handle.moveFocus(-1)
|
handle.moveFocus(-1)
|
||||||
},
|
},
|
||||||
@@ -215,7 +215,7 @@ export default function (CodeMirror,{
|
|||||||
Esc: handle.close
|
Esc: handle.close
|
||||||
}
|
}
|
||||||
|
|
||||||
var mac = /Mac/.test(navigator.platform)
|
const mac = /Mac/.test(navigator.platform)
|
||||||
|
|
||||||
if (mac) {
|
if (mac) {
|
||||||
baseMap['Ctrl-P'] = function () {
|
baseMap['Ctrl-P'] = function () {
|
||||||
@@ -226,11 +226,11 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var custom = completion.options.customKeys
|
const custom = completion.options.customKeys
|
||||||
var ourMap = custom ? {} : baseMap
|
const ourMap = custom ? {} : baseMap
|
||||||
|
|
||||||
function addBinding (key, val) {
|
function addBinding (key, val) {
|
||||||
var bound
|
let bound
|
||||||
if (typeof val != 'string') {
|
if (typeof val != 'string') {
|
||||||
bound = function (cm) {
|
bound = function (cm) {
|
||||||
return val(cm, handle)
|
return val(cm, handle)
|
||||||
@@ -251,7 +251,7 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var extra = completion.options.extraKeys
|
const extra = completion.options.extraKeys
|
||||||
if (extra) {
|
if (extra) {
|
||||||
for (var key in extra) {
|
for (var key in extra) {
|
||||||
if (extra.hasOwnProperty(key)) {
|
if (extra.hasOwnProperty(key)) {
|
||||||
@@ -274,25 +274,25 @@ export default function (CodeMirror,{
|
|||||||
this.completion = completion
|
this.completion = completion
|
||||||
this.data = data
|
this.data = data
|
||||||
this.picked = false
|
this.picked = false
|
||||||
var widget = this, cm = completion.cm
|
const widget = this; const cm = completion.cm
|
||||||
var ownerDocument = cm.getInputField().ownerDocument
|
const ownerDocument = cm.getInputField().ownerDocument
|
||||||
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
|
const parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
|
||||||
|
|
||||||
var hints = this.hints = ownerDocument.createElement('ul')
|
const hints = this.hints = ownerDocument.createElement('ul')
|
||||||
// $(hints).append(`
|
// $(hints).append(`
|
||||||
// <h1>lalallalla</h1>
|
// <h1>lalallalla</h1>
|
||||||
// `)
|
// `)
|
||||||
hints.setAttribute('role', 'listbox')
|
hints.setAttribute('role', 'listbox')
|
||||||
hints.setAttribute('aria-expanded', 'true')
|
hints.setAttribute('aria-expanded', 'true')
|
||||||
hints.id = this.id
|
hints.id = this.id
|
||||||
var theme = completion.cm.options.theme
|
const theme = completion.cm.options.theme
|
||||||
hints.className = 'CodeMirror-hints ' + theme
|
hints.className = 'CodeMirror-hints ' + theme
|
||||||
this.selectedHint = data.selectedHint || 0
|
this.selectedHint = data.selectedHint || 0
|
||||||
|
|
||||||
var completions = data.list
|
const completions = data.list
|
||||||
for (var i = 0; i < completions.length; ++i) {
|
for (let i = 0; i < completions.length; ++i) {
|
||||||
var elt = hints.appendChild(ownerDocument.createElement('li')), cur = completions[i]
|
const elt = hints.appendChild(ownerDocument.createElement('li')); const cur = completions[i]
|
||||||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
|
let className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
|
||||||
if (cur.className != null) className = cur.className + ' ' + className
|
if (cur.className != null) className = cur.className + ' ' + className
|
||||||
elt.className = className
|
elt.className = className
|
||||||
if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true')
|
if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true')
|
||||||
@@ -306,16 +306,16 @@ export default function (CodeMirror,{
|
|||||||
elt.hintId = i
|
elt.hintId = i
|
||||||
}
|
}
|
||||||
|
|
||||||
var container = completion.options.container || ownerDocument.body
|
const container = completion.options.container || ownerDocument.body
|
||||||
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
|
let pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
|
||||||
var left = pos.left, top = pos.bottom, below = true
|
let left = pos.left; let top = pos.bottom; let below = true
|
||||||
var offsetLeft = 0, offsetTop = 0
|
let offsetLeft = 0; let offsetTop = 0
|
||||||
if (container !== ownerDocument.body) {
|
if (container !== ownerDocument.body) {
|
||||||
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
|
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
|
||||||
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1
|
const isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1
|
||||||
var offsetParent = isContainerPositioned ? container : container.offsetParent
|
const offsetParent = isContainerPositioned ? container : container.offsetParent
|
||||||
var offsetParentPosition = offsetParent.getBoundingClientRect()
|
const offsetParentPosition = offsetParent.getBoundingClientRect()
|
||||||
var bodyPosition = ownerDocument.body.getBoundingClientRect()
|
const bodyPosition = ownerDocument.body.getBoundingClientRect()
|
||||||
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft)
|
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft)
|
||||||
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop)
|
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop)
|
||||||
}
|
}
|
||||||
@@ -325,10 +325,10 @@ export default function (CodeMirror,{
|
|||||||
hints.style.display = 'none'
|
hints.style.display = 'none'
|
||||||
|
|
||||||
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
||||||
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
|
const winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
|
||||||
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
|
const winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
|
||||||
|
|
||||||
//不用默认的DOM 下拉提示
|
// 不用默认的DOM 下拉提示
|
||||||
// container.appendChild(hints);
|
// container.appendChild(hints);
|
||||||
hints.remove()
|
hints.remove()
|
||||||
|
|
||||||
@@ -336,25 +336,25 @@ export default function (CodeMirror,{
|
|||||||
cm.getInputField().setAttribute('aria-owns', this.id)
|
cm.getInputField().setAttribute('aria-owns', this.id)
|
||||||
cm.getInputField().setAttribute('aria-activedescendant', this.id + '-' + this.selectedHint)
|
cm.getInputField().setAttribute('aria-activedescendant', this.id + '-' + this.selectedHint)
|
||||||
|
|
||||||
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
|
let box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
|
||||||
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
|
const scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
|
||||||
|
|
||||||
// Compute in the timeout to avoid reflow on init
|
// Compute in the timeout to avoid reflow on init
|
||||||
var startScroll
|
let startScroll
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
startScroll = cm.getScrollInfo()
|
startScroll = cm.getScrollInfo()
|
||||||
})
|
})
|
||||||
|
|
||||||
var overlapY = box.bottom - winH
|
const overlapY = box.bottom - winH
|
||||||
if (overlapY > 0) {
|
if (overlapY > 0) {
|
||||||
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top)
|
const height = box.bottom - box.top; const curTop = pos.top - (pos.bottom - box.top)
|
||||||
if (curTop - height > 0) { // Fits above cursor
|
if (curTop - height > 0) { // Fits above cursor
|
||||||
hints.style.top = (top = pos.top - height - offsetTop) + 'px'
|
hints.style.top = (top = pos.top - height - offsetTop) + 'px'
|
||||||
below = false
|
below = false
|
||||||
} else if (height > winH) {
|
} else if (height > winH) {
|
||||||
hints.style.height = (winH - 5) + 'px'
|
hints.style.height = (winH - 5) + 'px'
|
||||||
hints.style.top = (top = pos.bottom - box.top - offsetTop) + 'px'
|
hints.style.top = (top = pos.bottom - box.top - offsetTop) + 'px'
|
||||||
var cursor = cm.getCursor()
|
const cursor = cm.getCursor()
|
||||||
if (data.from.ch != cursor.ch) {
|
if (data.from.ch != cursor.ch) {
|
||||||
pos = cm.cursorCoords(cursor)
|
pos = cm.cursorCoords(cursor)
|
||||||
hints.style.left = (left = pos.left - offsetLeft) + 'px'
|
hints.style.left = (left = pos.left - offsetLeft) + 'px'
|
||||||
@@ -362,7 +362,7 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var overlapX = box.right - winW
|
let overlapX = box.right - winW
|
||||||
if (scrolls) overlapX += cm.display.nativeBarWidth
|
if (scrolls) overlapX += cm.display.nativeBarWidth
|
||||||
if (overlapX > 0) {
|
if (overlapX > 0) {
|
||||||
if (box.right - box.left > winW) {
|
if (box.right - box.left > winW) {
|
||||||
@@ -372,7 +372,7 @@ export default function (CodeMirror,{
|
|||||||
hints.style.left = (left = Math.max(pos.left - overlapX - offsetLeft, 0)) + 'px'
|
hints.style.left = (left = Math.max(pos.left - overlapX - offsetLeft, 0)) + 'px'
|
||||||
}
|
}
|
||||||
if (scrolls) {
|
if (scrolls) {
|
||||||
for (var node = hints.firstChild; node; node = node.nextSibling) {
|
for (let node = hints.firstChild; node; node = node.nextSibling) {
|
||||||
node.style.paddingRight = cm.display.nativeBarWidth + 'px'
|
node.style.paddingRight = cm.display.nativeBarWidth + 'px'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,7 +400,7 @@ export default function (CodeMirror,{
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
if (completion.options.closeOnUnfocus) {
|
if (completion.options.closeOnUnfocus) {
|
||||||
var closingOnBlur
|
let closingOnBlur
|
||||||
cm.on('blur', this.onBlur = function () {
|
cm.on('blur', this.onBlur = function () {
|
||||||
closingOnBlur = setTimeout(function () {
|
closingOnBlur = setTimeout(function () {
|
||||||
completion.close()
|
completion.close()
|
||||||
@@ -412,10 +412,10 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
|
|
||||||
cm.on('scroll', this.onScroll = function () {
|
cm.on('scroll', this.onScroll = function () {
|
||||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect()
|
const curScroll = cm.getScrollInfo(); const editor = cm.getWrapperElement().getBoundingClientRect()
|
||||||
if (!startScroll) startScroll = cm.getScrollInfo()
|
if (!startScroll) startScroll = cm.getScrollInfo()
|
||||||
var newTop = top + startScroll.top - curScroll.top
|
const newTop = top + startScroll.top - curScroll.top
|
||||||
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
|
let point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
|
||||||
if (!below) point += hints.offsetHeight
|
if (!below) point += hints.offsetHeight
|
||||||
if (point <= editor.top || point >= editor.bottom) return completion.close()
|
if (point <= editor.top || point >= editor.bottom) return completion.close()
|
||||||
hints.style.top = newTop + 'px'
|
hints.style.top = newTop + 'px'
|
||||||
@@ -423,7 +423,7 @@ export default function (CodeMirror,{
|
|||||||
})
|
})
|
||||||
|
|
||||||
CodeMirror.on(hints, 'dblclick', function (e) {
|
CodeMirror.on(hints, 'dblclick', function (e) {
|
||||||
var t = getHintElement(hints, e.target || e.srcElement)
|
const t = getHintElement(hints, e.target || e.srcElement)
|
||||||
if (t && t.hintId != null) {
|
if (t && t.hintId != null) {
|
||||||
widget.changeActive(t.hintId)
|
widget.changeActive(t.hintId)
|
||||||
widget.pick()
|
widget.pick()
|
||||||
@@ -431,7 +431,7 @@ export default function (CodeMirror,{
|
|||||||
})
|
})
|
||||||
|
|
||||||
CodeMirror.on(hints, 'click', function (e) {
|
CodeMirror.on(hints, 'click', function (e) {
|
||||||
var t = getHintElement(hints, e.target || e.srcElement)
|
const t = getHintElement(hints, e.target || e.srcElement)
|
||||||
if (t && t.hintId != null) {
|
if (t && t.hintId != null) {
|
||||||
widget.changeActive(t.hintId)
|
widget.changeActive(t.hintId)
|
||||||
if (completion.options.completeOnSingleClick) widget.pick()
|
if (completion.options.completeOnSingleClick) widget.pick()
|
||||||
@@ -445,7 +445,7 @@ export default function (CodeMirror,{
|
|||||||
})
|
})
|
||||||
|
|
||||||
// The first hint doesn't need to be scrolled to on init
|
// The first hint doesn't need to be scrolled to on init
|
||||||
var selectedHintRange = this.getSelectedHintRange()
|
const selectedHintRange = this.getSelectedHintRange()
|
||||||
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
|
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
|
||||||
this.scrollToActive()
|
this.scrollToActive()
|
||||||
}
|
}
|
||||||
@@ -460,11 +460,11 @@ export default function (CodeMirror,{
|
|||||||
this.completion.widget = null
|
this.completion.widget = null
|
||||||
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints)
|
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints)
|
||||||
this.completion.cm.removeKeyMap(this.keyMap)
|
this.completion.cm.removeKeyMap(this.keyMap)
|
||||||
var input = this.completion.cm.getInputField()
|
const input = this.completion.cm.getInputField()
|
||||||
input.removeAttribute('aria-activedescendant')
|
input.removeAttribute('aria-activedescendant')
|
||||||
input.removeAttribute('aria-owns')
|
input.removeAttribute('aria-owns')
|
||||||
|
|
||||||
var cm = this.completion.cm
|
const cm = this.completion.cm
|
||||||
if (this.completion.options.closeOnUnfocus) {
|
if (this.completion.options.closeOnUnfocus) {
|
||||||
cm.off('blur', this.onBlur)
|
cm.off('blur', this.onBlur)
|
||||||
cm.off('focus', this.onFocus)
|
cm.off('focus', this.onFocus)
|
||||||
@@ -474,7 +474,7 @@ export default function (CodeMirror,{
|
|||||||
|
|
||||||
disable: function () {
|
disable: function () {
|
||||||
this.completion.cm.removeKeyMap(this.keyMap)
|
this.completion.cm.removeKeyMap(this.keyMap)
|
||||||
var widget = this
|
const widget = this
|
||||||
this.keyMap = {
|
this.keyMap = {
|
||||||
Enter: function () {
|
Enter: function () {
|
||||||
widget.picked = true
|
widget.picked = true
|
||||||
@@ -494,7 +494,7 @@ export default function (CodeMirror,{
|
|||||||
i = avoidWrap ? 0 : this.data.list.length - 1
|
i = avoidWrap ? 0 : this.data.list.length - 1
|
||||||
}
|
}
|
||||||
if (this.selectedHint == i) return
|
if (this.selectedHint == i) return
|
||||||
var node = this.hints.childNodes[this.selectedHint]
|
let node = this.hints.childNodes[this.selectedHint]
|
||||||
if (node) {
|
if (node) {
|
||||||
node.className = node.className.replace(' ' + ACTIVE_HINT_ELEMENT_CLASS, '')
|
node.className = node.className.replace(' ' + ACTIVE_HINT_ELEMENT_CLASS, '')
|
||||||
node.removeAttribute('aria-selected')
|
node.removeAttribute('aria-selected')
|
||||||
@@ -508,10 +508,10 @@ export default function (CodeMirror,{
|
|||||||
},
|
},
|
||||||
|
|
||||||
scrollToActive: function () {
|
scrollToActive: function () {
|
||||||
var selectedHintRange = this.getSelectedHintRange()
|
const selectedHintRange = this.getSelectedHintRange()
|
||||||
var node1 = this.hints.childNodes[selectedHintRange.from]
|
const node1 = this.hints.childNodes[selectedHintRange.from]
|
||||||
var node2 = this.hints.childNodes[selectedHintRange.to]
|
const node2 = this.hints.childNodes[selectedHintRange.to]
|
||||||
var firstNode = this.hints.firstChild
|
const firstNode = this.hints.firstChild
|
||||||
if (node1.offsetTop < this.hints.scrollTop) {
|
if (node1.offsetTop < this.hints.scrollTop) {
|
||||||
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop
|
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop
|
||||||
} else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) {
|
} else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) {
|
||||||
@@ -524,18 +524,18 @@ export default function (CodeMirror,{
|
|||||||
},
|
},
|
||||||
|
|
||||||
getSelectedHintRange: function () {
|
getSelectedHintRange: function () {
|
||||||
var margin = this.completion.options.scrollMargin || 0
|
const margin = this.completion.options.scrollMargin || 0
|
||||||
return {
|
return {
|
||||||
from: Math.max(0, this.selectedHint - margin),
|
from: Math.max(0, this.selectedHint - margin),
|
||||||
to: Math.min(this.data.list.length - 1, this.selectedHint + margin),
|
to: Math.min(this.data.list.length - 1, this.selectedHint + margin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applicableHelpers (cm, helpers) {
|
function applicableHelpers (cm, helpers) {
|
||||||
if (!cm.somethingSelected()) return helpers
|
if (!cm.somethingSelected()) return helpers
|
||||||
var result = []
|
const result = []
|
||||||
for (var i = 0; i < helpers.length; i++) {
|
for (let i = 0; i < helpers.length; i++) {
|
||||||
if (helpers[i].supportsSelection) result.push(helpers[i])
|
if (helpers[i].supportsSelection) result.push(helpers[i])
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -545,7 +545,7 @@ export default function (CodeMirror,{
|
|||||||
if (hint.async) {
|
if (hint.async) {
|
||||||
hint(cm, callback, options)
|
hint(cm, callback, options)
|
||||||
} else {
|
} else {
|
||||||
var result = hint(cm, options)
|
const result = hint(cm, options)
|
||||||
if (result && result.then) {
|
if (result && result.then) {
|
||||||
result.then(callback)
|
result.then(callback)
|
||||||
} else {
|
} else {
|
||||||
@@ -555,10 +555,10 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveAutoHints (cm, pos) {
|
function resolveAutoHints (cm, pos) {
|
||||||
var helpers = cm.getHelpers(pos, 'hint'), words
|
const helpers = cm.getHelpers(pos, 'hint'); let words
|
||||||
if (helpers.length) {
|
if (helpers.length) {
|
||||||
var resolved = function (cm, callback, options) {
|
const resolved = function (cm, callback, options) {
|
||||||
var app = applicableHelpers(cm, helpers)
|
const app = applicableHelpers(cm, helpers)
|
||||||
|
|
||||||
function run (i) {
|
function run (i) {
|
||||||
if (i == app.length) return callback(null)
|
if (i == app.length) return callback(null)
|
||||||
@@ -595,17 +595,17 @@ export default function (CodeMirror,{
|
|||||||
})
|
})
|
||||||
|
|
||||||
CodeMirror.registerHelper('hint', 'fromList', function (cm, options) {
|
CodeMirror.registerHelper('hint', 'fromList', function (cm, options) {
|
||||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
|
const cur = cm.getCursor(); const token = cm.getTokenAt(cur)
|
||||||
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
|
let term; let from = CodeMirror.Pos(cur.line, token.start); const to = cur
|
||||||
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
|
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
|
||||||
term = token.string.substr(0, cur.ch - token.start)
|
term = token.string.substr(0, cur.ch - token.start)
|
||||||
} else {
|
} else {
|
||||||
term = ''
|
term = ''
|
||||||
from = cur
|
from = cur
|
||||||
}
|
}
|
||||||
var found = []
|
const found = []
|
||||||
for (var i = 0; i < options.words.length; i++) {
|
for (let i = 0; i < options.words.length; i++) {
|
||||||
var word = options.words[i]
|
const word = options.words[i]
|
||||||
if (word.slice(0, term.length) == term) {
|
if (word.slice(0, term.length) == term) {
|
||||||
found.push(word)
|
found.push(word)
|
||||||
}
|
}
|
||||||
@@ -620,7 +620,7 @@ export default function (CodeMirror,{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
CodeMirror.commands.autocomplete = CodeMirror.showHint
|
||||||
|
|
||||||
var defaultOptions = {
|
var defaultOptions = {
|
||||||
hint: CodeMirror.hint.auto,
|
hint: CodeMirror.hint.auto,
|
||||||
@@ -629,7 +629,7 @@ export default function (CodeMirror,{
|
|||||||
closeCharacters: /[\s()\[\]{};:>,]/,
|
closeCharacters: /[\s()\[\]{};:>,]/,
|
||||||
|
|
||||||
closeOnPick: false,
|
closeOnPick: false,
|
||||||
closeOnUnfocus: false, //阻止提示信息 失焦关闭
|
closeOnUnfocus: false, // 阻止提示信息 失焦关闭
|
||||||
// closeOnUnfocus: false,
|
// closeOnUnfocus: false,
|
||||||
|
|
||||||
updateOnCursorActivity: true,
|
updateOnCursorActivity: true,
|
||||||
@@ -638,8 +638,7 @@ export default function (CodeMirror,{
|
|||||||
customKeys: null,
|
customKeys: null,
|
||||||
extraKeys: null,
|
extraKeys: null,
|
||||||
paddingForScrollbar: true,
|
paddingForScrollbar: true,
|
||||||
moveOnOverlap: true,
|
moveOnOverlap: true
|
||||||
};
|
}
|
||||||
CodeMirror.defineOption("hintOptions", null);
|
CodeMirror.defineOption('hintOptions', null)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,222 +1,216 @@
|
|||||||
//正则 向前去找关键字
|
// 正则 向前去找关键字
|
||||||
/* 用于匹配关系数据 */
|
/* 用于匹配关系数据 */
|
||||||
function matchOperator(CodeMirror, hintParams = {}) {
|
function matchOperator (CodeMirror, hintParams = {}) {
|
||||||
var editor = hintParams.editor;
|
const editor = hintParams.editor
|
||||||
var Pos = CodeMirror.Pos
|
const Pos = CodeMirror.Pos
|
||||||
var cur = hintParams.cur;
|
const cur = hintParams.cur
|
||||||
var token = hintParams.token;
|
let token = hintParams.token
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = token.start
|
||||||
var start = token.start;
|
let cont = true
|
||||||
var cont = true;
|
const leftTokenGroup = []
|
||||||
var leftTokenGroup = [];
|
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(token.string.match(/^[ ]*$/) || start === 0); //只用空格做终止条件
|
cont = !(token.string.match(/^[ ]*$/) || start === 0) // 只用空格做终止条件
|
||||||
}
|
}
|
||||||
|
|
||||||
var cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
const cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
||||||
|
|
||||||
//判断是不是满足 运算符 表达式的正则
|
// 判断是不是满足 运算符 表达式的正则
|
||||||
//test 如果是ig 会改变正则指针: https://my.oschina.net/jamesview/blog/5460753
|
// test 如果是ig 会改变正则指针: https://my.oschina.net/jamesview/blog/5460753
|
||||||
var reg = /^(.*?)(=|!=|>|<|>=|<=)([^ ]*?)$/;
|
const reg = /^(.*?)(=|!=|>|<|>=|<=)([^ ]*?)$/
|
||||||
if (reg.test(cursorLeftString)) {
|
if (reg.test(cursorLeftString)) {
|
||||||
var execArr = reg.exec(cursorLeftString) || []
|
const execArr = reg.exec(cursorLeftString) || []
|
||||||
return {
|
return {
|
||||||
leftTokenGroup,
|
leftTokenGroup,
|
||||||
cursorLeftString,
|
cursorLeftString,
|
||||||
label: execArr[1],
|
label: execArr[1],
|
||||||
sign: execArr[2],
|
sign: execArr[2],
|
||||||
value: execArr[3],
|
value: execArr[3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchCommon(CodeMirror, hintParams = {}) {
|
function matchCommon (CodeMirror, hintParams = {}) {
|
||||||
//通用情况 QUANTILE(expr,level) 左括号右侧第一个就是 关键字
|
// 通用情况 QUANTILE(expr,level) 左括号右侧第一个就是 关键字
|
||||||
var editor = hintParams.editor;
|
const editor = hintParams.editor
|
||||||
var Pos = CodeMirror.Pos
|
const Pos = CodeMirror.Pos
|
||||||
var cur = hintParams.cur;
|
const cur = hintParams.cur
|
||||||
var token = hintParams.token;
|
let token = hintParams.token
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = token.start
|
||||||
var start = token.start;
|
let cont = true
|
||||||
var cont = true;
|
const leftTokenGroup = []
|
||||||
var leftTokenGroup = [];
|
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(token.string.match(/^[ (]*$/) || start === 0); //括号或者空格为终止条件
|
cont = !(token.string.match(/^[ (]*$/) || start === 0) // 括号或者空格为终止条件
|
||||||
|
|
||||||
//括号补上
|
// 括号补上
|
||||||
if (token.string === '(') {
|
if (token.string === '(') {
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
const cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
||||||
|
|
||||||
//判断是不是满足 运算符 表达式的正则
|
// 判断是不是满足 运算符 表达式的正则
|
||||||
var reg = /^\((.*?),([^ ]*)$/;
|
const reg = /^\((.*?),([^ ]*)$/
|
||||||
if (reg.test(cursorLeftString)) {
|
if (reg.test(cursorLeftString)) {
|
||||||
var execArr = reg.exec(cursorLeftString) || []
|
const execArr = reg.exec(cursorLeftString) || []
|
||||||
return {
|
return {
|
||||||
leftTokenGroup,
|
leftTokenGroup,
|
||||||
cursorLeftString,
|
cursorLeftString,
|
||||||
label: execArr[1],
|
label: execArr[1],
|
||||||
sign: 'unknown', //没必要判断
|
sign: 'unknown', // 没必要判断
|
||||||
value: execArr[2],
|
value: execArr[2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchIn(CodeMirror, hintParams = {}) {
|
function matchIn (CodeMirror, hintParams = {}) {
|
||||||
//in 的情况比较特殊
|
// in 的情况比较特殊
|
||||||
//通用情况 expr not in (values) expr in (values)
|
// 通用情况 expr not in (values) expr in (values)
|
||||||
var editor = hintParams.editor;
|
const editor = hintParams.editor
|
||||||
var Pos = CodeMirror.Pos
|
const Pos = CodeMirror.Pos
|
||||||
var cur = hintParams.cur;
|
const cur = hintParams.cur
|
||||||
var token = hintParams.token;
|
let token = hintParams.token
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = token.start
|
||||||
|
let cont = true
|
||||||
|
const leftTokenGroup = []
|
||||||
|
|
||||||
var start = token.start;
|
// 找到左括号
|
||||||
var cont = true;
|
|
||||||
var leftTokenGroup = [];
|
|
||||||
|
|
||||||
//找到左括号
|
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(token.string.match(/^[ (]*$/) || start === 0); //括号或者空格为终止条件
|
cont = !(token.string.match(/^[ (]*$/) || start === 0) // 括号或者空格为终止条件
|
||||||
//左括号补上
|
// 左括号补上
|
||||||
if (token.string === '(') {
|
if (token.string === '(') {
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//左括号继续向右找
|
// 左括号继续向右找
|
||||||
cont = true
|
cont = true
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(!token.string.match(/^(in|not| )/g) || start === 0); //括号或者空格为终止条件
|
cont = !(!token.string.match(/^(in|not| )/g) || start === 0) // 括号或者空格为终止条件
|
||||||
|
|
||||||
//string-2
|
// string-2
|
||||||
if (token.type === 'string-2') {
|
if (token.type === 'string-2') {
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
const cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
||||||
|
|
||||||
//判断是不是满足 运算符 表达式的正则
|
// 判断是不是满足 运算符 表达式的正则
|
||||||
var reg = /^(.*?)[ ]+((?:not[ ]+)?in)[ ]*\(([^ ]*?)$/i;
|
const reg = /^(.*?)[ ]+((?:not[ ]+)?in)[ ]*\(([^ ]*?)$/i
|
||||||
if (reg.test(cursorLeftString)) {
|
if (reg.test(cursorLeftString)) {
|
||||||
var execArr = reg.exec(cursorLeftString) || []
|
const execArr = reg.exec(cursorLeftString) || []
|
||||||
return {
|
return {
|
||||||
leftTokenGroup,
|
leftTokenGroup,
|
||||||
cursorLeftString,
|
cursorLeftString,
|
||||||
label: execArr[1],
|
label: execArr[1],
|
||||||
sign: execArr[2],
|
sign: execArr[2],
|
||||||
value: execArr[3],
|
value: execArr[3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchLike(CodeMirror, hintParams = {}) {
|
function matchLike (CodeMirror, hintParams = {}) {
|
||||||
//like 的情况比较特殊 expr like value , expr not like value
|
// like 的情况比较特殊 expr like value , expr not like value
|
||||||
var editor = hintParams.editor;
|
const editor = hintParams.editor
|
||||||
var Pos = CodeMirror.Pos
|
const Pos = CodeMirror.Pos
|
||||||
var cur = hintParams.cur;
|
const cur = hintParams.cur
|
||||||
var token = hintParams.token;
|
let token = hintParams.token
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = token.start
|
||||||
|
let cont = true
|
||||||
|
const leftTokenGroup = []
|
||||||
|
|
||||||
var start = token.start;
|
// 找到左括号
|
||||||
var cont = true;
|
|
||||||
var leftTokenGroup = [];
|
|
||||||
|
|
||||||
//找到左括号
|
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(token.string.match(/^[ ]*$/) || start === 0); //括号或者空格为终止条件
|
cont = !(token.string.match(/^[ ]*$/) || start === 0) // 括号或者空格为终止条件
|
||||||
}
|
}
|
||||||
|
|
||||||
//左括号继续向右找
|
// 左括号继续向右找
|
||||||
cont = true
|
cont = true
|
||||||
while (cont) {
|
while (cont) {
|
||||||
start = token.start;
|
start = token.start
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
cont = !(!token.string.match(/^(like|not| )/g) || start === 0); //括号或者空格为终止条件
|
cont = !(!token.string.match(/^(like|not| )/g) || start === 0) // 括号或者空格为终止条件
|
||||||
|
|
||||||
//string-2
|
// string-2
|
||||||
if (token.type === 'string-2') {
|
if (token.type === 'string-2') {
|
||||||
leftTokenGroup.unshift(token);
|
leftTokenGroup.unshift(token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
const cursorLeftString = editor.getRange(Pos(cur.line, leftTokenGroup[0].start), Pos(cur.line, leftTokenGroup[leftTokenGroup.length - 1].end))
|
||||||
|
|
||||||
//判断是不是满足 运算符 表达式的正则
|
// 判断是不是满足 运算符 表达式的正则
|
||||||
var reg = /^(.*?)[ ]+((?:not[ ]+)?like)[ ]*([^ ]*?)$/i;
|
const reg = /^(.*?)[ ]+((?:not[ ]+)?like)[ ]*([^ ]*?)$/i
|
||||||
if (reg.test(cursorLeftString)) {
|
if (reg.test(cursorLeftString)) {
|
||||||
var execArr = reg.exec(cursorLeftString) || []
|
const execArr = reg.exec(cursorLeftString) || []
|
||||||
return {
|
return {
|
||||||
leftTokenGroup,
|
leftTokenGroup,
|
||||||
cursorLeftString,
|
cursorLeftString,
|
||||||
label: execArr[1],
|
label: execArr[1],
|
||||||
sign: execArr[2],
|
sign: execArr[2],
|
||||||
value: execArr[3],
|
value: execArr[3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const matchMain = (CodeMirror, params, manualParams = {}) => {
|
export const matchMain = (CodeMirror, params, manualParams = {}) => {
|
||||||
var matchRes = null
|
let matchRes = null
|
||||||
//匹配 运算符表达式
|
// 匹配 运算符表达式
|
||||||
matchRes = matchOperator(CodeMirror, manualParams)
|
matchRes = matchOperator(CodeMirror, manualParams)
|
||||||
if (matchRes) {
|
if (matchRes) {
|
||||||
return matchRes
|
return matchRes
|
||||||
}
|
}
|
||||||
|
|
||||||
//匹配 in表达式
|
// 匹配 in表达式
|
||||||
matchRes = matchIn(CodeMirror, manualParams)
|
matchRes = matchIn(CodeMirror, manualParams)
|
||||||
if (matchRes) {
|
if (matchRes) {
|
||||||
return matchRes
|
return matchRes
|
||||||
}
|
}
|
||||||
|
|
||||||
//匹配 like表达式
|
// 匹配 like表达式
|
||||||
matchRes = matchLike(CodeMirror, manualParams)
|
matchRes = matchLike(CodeMirror, manualParams)
|
||||||
if (matchRes) {
|
if (matchRes) {
|
||||||
return matchRes
|
return matchRes
|
||||||
}
|
}
|
||||||
|
|
||||||
//这里缺少一个对 count(distinct expr) 模式的匹配, 感觉大数据涉及存在缺陷, 先暂时不写
|
// 这里缺少一个对 count(distinct expr) 模式的匹配, 感觉大数据涉及存在缺陷, 先暂时不写
|
||||||
|
|
||||||
|
// 匹配 其他表达式 (expr,value1,value2....) 模式的匹配
|
||||||
//匹配 其他表达式 (expr,value1,value2....) 模式的匹配
|
|
||||||
matchRes = matchCommon(CodeMirror, manualParams)
|
matchRes = matchCommon(CodeMirror, manualParams)
|
||||||
if (matchRes) {
|
if (matchRes) {
|
||||||
// 说明这是一个 运算符表达式
|
// 说明这是一个 运算符表达式
|
||||||
|
|||||||
@@ -1,525 +1,521 @@
|
|||||||
export default function showHint(CodeMirror) {
|
export default function showHint (CodeMirror) {
|
||||||
"use strict";
|
'use strict'
|
||||||
|
|
||||||
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
|
const HINT_ELEMENT_CLASS = 'CodeMirror-hint'
|
||||||
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
|
const ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
|
||||||
|
|
||||||
// This is the old interface, kept around for now to stay
|
// This is the old interface, kept around for now to stay
|
||||||
// backwards-compatible.
|
// backwards-compatible.
|
||||||
CodeMirror.showHint = function (cm, getHints, options) {
|
CodeMirror.showHint = function (cm, getHints, options) {
|
||||||
if (!getHints) return cm.showHint(options);
|
if (!getHints) return cm.showHint(options)
|
||||||
if (options && options.async) getHints.async = true;
|
if (options && options.async) getHints.async = true
|
||||||
var newOpts = {hint: getHints};
|
const newOpts = { hint: getHints }
|
||||||
if (options) for (var prop in options) newOpts[prop] = options[prop];
|
if (options) for (const prop in options) newOpts[prop] = options[prop]
|
||||||
return cm.showHint(newOpts);
|
return cm.showHint(newOpts)
|
||||||
};
|
}
|
||||||
|
|
||||||
CodeMirror.defineExtension("showHint", function (options) {
|
CodeMirror.defineExtension('showHint', function (options) {
|
||||||
options = parseOptions(this, this.getCursor("start"), options);
|
options = parseOptions(this, this.getCursor('start'), options)
|
||||||
var selections = this.listSelections()
|
const selections = this.listSelections()
|
||||||
if (selections.length > 1) return;
|
if (selections.length > 1) return
|
||||||
// By default, don't allow completion when something is selected.
|
// By default, don't allow completion when something is selected.
|
||||||
// A hint function can have a `supportsSelection` property to
|
// A hint function can have a `supportsSelection` property to
|
||||||
// indicate that it can handle selections.
|
// indicate that it can handle selections.
|
||||||
if (this.somethingSelected()) {
|
if (this.somethingSelected()) {
|
||||||
if (!options.hint.supportsSelection) return;
|
if (!options.hint.supportsSelection) return
|
||||||
// Don't try with cross-line selections
|
// Don't try with cross-line selections
|
||||||
for (var i = 0; i < selections.length; i++)
|
for (let i = 0; i < selections.length; i++) { if (selections[i].head.line != selections[i].anchor.line) return }
|
||||||
if (selections[i].head.line != selections[i].anchor.line) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.completionActive) this.state.completionActive.close();
|
if (this.state.completionActive) this.state.completionActive.close()
|
||||||
var completion = this.state.completionActive = new Completion(this, options);
|
const completion = this.state.completionActive = new Completion(this, options)
|
||||||
if (!completion.options.hint) return;
|
if (!completion.options.hint) return
|
||||||
|
|
||||||
CodeMirror.signal(this, "startCompletion", this);
|
CodeMirror.signal(this, 'startCompletion', this)
|
||||||
completion.update(true);
|
completion.update(true)
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.defineExtension("closeHint", function () {
|
CodeMirror.defineExtension('closeHint', function () {
|
||||||
if (this.state.completionActive) this.state.completionActive.close()
|
if (this.state.completionActive) this.state.completionActive.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
function Completion(cm, options) {
|
function Completion (cm, options) {
|
||||||
this.cm = cm;
|
this.cm = cm
|
||||||
this.options = options;
|
this.options = options
|
||||||
this.widget = null;
|
this.widget = null
|
||||||
this.debounce = 0;
|
this.debounce = 0
|
||||||
this.tick = 0;
|
this.tick = 0
|
||||||
this.startPos = this.cm.getCursor("start");
|
this.startPos = this.cm.getCursor('start')
|
||||||
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
|
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length
|
||||||
|
|
||||||
if (this.options.updateOnCursorActivity) {
|
if (this.options.updateOnCursorActivity) {
|
||||||
var self = this;
|
const self = this
|
||||||
cm.on("cursorActivity", this.activityFunc = function () {
|
cm.on('cursorActivity', this.activityFunc = function () {
|
||||||
self.cursorActivity();
|
self.cursorActivity()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestAnimationFrame = window.requestAnimationFrame || function (fn) {
|
const requestAnimationFrame = window.requestAnimationFrame || function (fn) {
|
||||||
return setTimeout(fn, 1000 / 60);
|
return setTimeout(fn, 1000 / 60)
|
||||||
};
|
}
|
||||||
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
|
const cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
|
||||||
|
|
||||||
Completion.prototype = {
|
Completion.prototype = {
|
||||||
close: function () {
|
close: function () {
|
||||||
if (!this.active()) return;
|
if (!this.active()) return
|
||||||
this.cm.state.completionActive = null;
|
this.cm.state.completionActive = null
|
||||||
this.tick = null;
|
this.tick = null
|
||||||
if (this.options.updateOnCursorActivity) {
|
if (this.options.updateOnCursorActivity) {
|
||||||
this.cm.off("cursorActivity", this.activityFunc);
|
this.cm.off('cursorActivity', this.activityFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
|
if (this.widget && this.data) CodeMirror.signal(this.data, 'close')
|
||||||
if (this.widget) this.widget.close();
|
if (this.widget) this.widget.close()
|
||||||
CodeMirror.signal(this.cm, "endCompletion", this.cm);
|
CodeMirror.signal(this.cm, 'endCompletion', this.cm)
|
||||||
},
|
},
|
||||||
|
|
||||||
active: function () {
|
active: function () {
|
||||||
return this.cm.state.completionActive == this;
|
return this.cm.state.completionActive == this
|
||||||
},
|
},
|
||||||
|
|
||||||
pick: function (data, i) {
|
pick: function (data, i) {
|
||||||
var completion = data.list[i], self = this;
|
const completion = data.list[i]; const self = this
|
||||||
this.cm.operation(function () {
|
this.cm.operation(function () {
|
||||||
if (completion.hint)
|
if (completion.hint) { completion.hint(self.cm, data, completion) } else {
|
||||||
completion.hint(self.cm, data, completion);
|
|
||||||
else
|
|
||||||
self.cm.replaceRange(getText(completion), completion.from || data.from,
|
self.cm.replaceRange(getText(completion), completion.from || data.from,
|
||||||
completion.to || data.to, "complete");
|
completion.to || data.to, 'complete')
|
||||||
CodeMirror.signal(data, "pick", completion);
|
}
|
||||||
self.cm.scrollIntoView();
|
CodeMirror.signal(data, 'pick', completion)
|
||||||
});
|
self.cm.scrollIntoView()
|
||||||
|
})
|
||||||
if (this.options.closeOnPick) {
|
if (this.options.closeOnPick) {
|
||||||
this.close();
|
this.close()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
cursorActivity: function () {
|
cursorActivity: function () {
|
||||||
if (this.debounce) {
|
if (this.debounce) {
|
||||||
cancelAnimationFrame(this.debounce);
|
cancelAnimationFrame(this.debounce)
|
||||||
this.debounce = 0;
|
this.debounce = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var identStart = this.startPos;
|
let identStart = this.startPos
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
identStart = this.data.from;
|
identStart = this.data.from
|
||||||
}
|
}
|
||||||
|
|
||||||
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
|
const pos = this.cm.getCursor(); const line = this.cm.getLine(pos.line)
|
||||||
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
|
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
|
||||||
pos.ch < identStart.ch || this.cm.somethingSelected() ||
|
pos.ch < identStart.ch || this.cm.somethingSelected() ||
|
||||||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
||||||
this.close();
|
this.close()
|
||||||
} else {
|
} else {
|
||||||
var self = this;
|
const self = this
|
||||||
this.debounce = requestAnimationFrame(function () {
|
this.debounce = requestAnimationFrame(function () {
|
||||||
self.update();
|
self.update()
|
||||||
});
|
})
|
||||||
if (this.widget) this.widget.disable();
|
if (this.widget) this.widget.disable()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function (first) {
|
update: function (first) {
|
||||||
if (this.tick == null) return
|
if (this.tick == null) return
|
||||||
var self = this, myTick = ++this.tick
|
const self = this; const myTick = ++this.tick
|
||||||
fetchHints(this.options.hint, this.cm, this.options, function (data) {
|
fetchHints(this.options.hint, this.cm, this.options, function (data) {
|
||||||
if (self.tick == myTick) self.finishUpdate(data, first)
|
if (self.tick == myTick) self.finishUpdate(data, first)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
finishUpdate: function (data, first) {
|
finishUpdate: function (data, first) {
|
||||||
if (this.data) CodeMirror.signal(this.data, "update");
|
if (this.data) CodeMirror.signal(this.data, 'update')
|
||||||
|
|
||||||
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
|
const picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle)
|
||||||
if (this.widget) this.widget.close();
|
if (this.widget) this.widget.close()
|
||||||
|
|
||||||
this.data = data;
|
this.data = data
|
||||||
|
|
||||||
if (data && data.list.length) {
|
if (data && data.list.length) {
|
||||||
if (picked && data.list.length == 1) {
|
if (picked && data.list.length == 1) {
|
||||||
this.pick(data, 0);
|
this.pick(data, 0)
|
||||||
} else {
|
} else {
|
||||||
this.widget = new Widget(this, data);
|
this.widget = new Widget(this, data)
|
||||||
CodeMirror.signal(data, "shown");
|
CodeMirror.signal(data, 'shown')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function parseOptions(cm, pos, options) {
|
function parseOptions (cm, pos, options) {
|
||||||
var editor = cm.options.hintOptions;
|
const editor = cm.options.hintOptions
|
||||||
var out = {};
|
const out = {}
|
||||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
for (var prop in defaultOptions) out[prop] = defaultOptions[prop]
|
||||||
if (editor) for (var prop in editor)
|
if (editor) {
|
||||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
for (var prop in editor) { if (editor[prop] !== undefined) out[prop] = editor[prop] }
|
||||||
if (options) for (var prop in options)
|
}
|
||||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
if (options) {
|
||||||
|
for (var prop in options) { if (options[prop] !== undefined) out[prop] = options[prop] }
|
||||||
|
}
|
||||||
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
|
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
|
||||||
return out;
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(completion) {
|
function getText (completion) {
|
||||||
if (typeof completion == "string") return completion;
|
if (typeof completion == 'string') return completion
|
||||||
else return completion.text;
|
else return completion.text
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildKeyMap(completion, handle) {
|
function buildKeyMap (completion, handle) {
|
||||||
var baseMap = {
|
const baseMap = {
|
||||||
Up: function () {
|
Up: function () {
|
||||||
handle.moveFocus(-1);
|
handle.moveFocus(-1)
|
||||||
},
|
},
|
||||||
Down: function () {
|
Down: function () {
|
||||||
handle.moveFocus(1);
|
handle.moveFocus(1)
|
||||||
},
|
},
|
||||||
PageUp: function () {
|
PageUp: function () {
|
||||||
handle.moveFocus(-handle.menuSize() + 1, true);
|
handle.moveFocus(-handle.menuSize() + 1, true)
|
||||||
},
|
},
|
||||||
PageDown: function () {
|
PageDown: function () {
|
||||||
handle.moveFocus(handle.menuSize() - 1, true);
|
handle.moveFocus(handle.menuSize() - 1, true)
|
||||||
},
|
},
|
||||||
Home: function () {
|
Home: function () {
|
||||||
handle.setFocus(0);
|
handle.setFocus(0)
|
||||||
},
|
},
|
||||||
End: function () {
|
End: function () {
|
||||||
handle.setFocus(handle.length - 1);
|
handle.setFocus(handle.length - 1)
|
||||||
},
|
},
|
||||||
Enter: handle.pick,
|
Enter: handle.pick,
|
||||||
Tab: handle.pick,
|
Tab: handle.pick,
|
||||||
Esc: handle.close
|
Esc: handle.close
|
||||||
};
|
}
|
||||||
|
|
||||||
var mac = /Mac/.test(navigator.platform);
|
const mac = /Mac/.test(navigator.platform)
|
||||||
|
|
||||||
if (mac) {
|
if (mac) {
|
||||||
baseMap["Ctrl-P"] = function () {
|
baseMap['Ctrl-P'] = function () {
|
||||||
handle.moveFocus(-1);
|
handle.moveFocus(-1)
|
||||||
};
|
}
|
||||||
baseMap["Ctrl-N"] = function () {
|
baseMap['Ctrl-N'] = function () {
|
||||||
handle.moveFocus(1);
|
handle.moveFocus(1)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var custom = completion.options.customKeys;
|
const custom = completion.options.customKeys
|
||||||
var ourMap = custom ? {} : baseMap;
|
const ourMap = custom ? {} : baseMap
|
||||||
|
|
||||||
function addBinding(key, val) {
|
function addBinding (key, val) {
|
||||||
var bound;
|
let bound
|
||||||
if (typeof val != "string")
|
if (typeof val != 'string') {
|
||||||
bound = function (cm) {
|
bound = function (cm) {
|
||||||
return val(cm, handle);
|
return val(cm, handle)
|
||||||
};
|
}
|
||||||
|
}
|
||||||
// This mechanism is deprecated
|
// This mechanism is deprecated
|
||||||
else if (baseMap.hasOwnProperty(val))
|
else if (baseMap.hasOwnProperty(val)) { bound = baseMap[val] } else { bound = val }
|
||||||
bound = baseMap[val];
|
ourMap[key] = bound
|
||||||
else
|
|
||||||
bound = val;
|
|
||||||
ourMap[key] = bound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (custom)
|
if (custom) {
|
||||||
for (var key in custom) if (custom.hasOwnProperty(key))
|
for (var key in custom) {
|
||||||
addBinding(key, custom[key]);
|
if (custom.hasOwnProperty(key)) { addBinding(key, custom[key]) }
|
||||||
var extra = completion.options.extraKeys;
|
}
|
||||||
if (extra)
|
}
|
||||||
for (var key in extra) if (extra.hasOwnProperty(key))
|
const extra = completion.options.extraKeys
|
||||||
addBinding(key, extra[key]);
|
if (extra) {
|
||||||
return ourMap;
|
for (var key in extra) {
|
||||||
|
if (extra.hasOwnProperty(key)) { addBinding(key, extra[key]) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ourMap
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHintElement(hintsElement, el) {
|
function getHintElement (hintsElement, el) {
|
||||||
while (el && el != hintsElement) {
|
while (el && el != hintsElement) {
|
||||||
if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
|
if (el.nodeName.toUpperCase() === 'LI' && el.parentNode == hintsElement) return el
|
||||||
el = el.parentNode;
|
el = el.parentNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Widget(completion, data) {
|
function Widget (completion, data) {
|
||||||
this.id = "cm-complete-" + Math.floor(Math.random(1e6))
|
this.id = 'cm-complete-' + Math.floor(Math.random(1e6))
|
||||||
this.completion = completion;
|
this.completion = completion
|
||||||
this.data = data;
|
this.data = data
|
||||||
this.picked = false;
|
this.picked = false
|
||||||
var widget = this, cm = completion.cm;
|
const widget = this; const cm = completion.cm
|
||||||
var ownerDocument = cm.getInputField().ownerDocument;
|
const ownerDocument = cm.getInputField().ownerDocument
|
||||||
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
|
const parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
|
||||||
|
|
||||||
var hints = this.hints = ownerDocument.createElement("ul");
|
const hints = this.hints = ownerDocument.createElement('ul')
|
||||||
// $(hints).append(`
|
// $(hints).append(`
|
||||||
// <h1>lalallalla</h1>
|
// <h1>lalallalla</h1>
|
||||||
// `)
|
// `)
|
||||||
hints.setAttribute("role", "listbox")
|
hints.setAttribute('role', 'listbox')
|
||||||
hints.setAttribute("aria-expanded", "true")
|
hints.setAttribute('aria-expanded', 'true')
|
||||||
hints.id = this.id
|
hints.id = this.id
|
||||||
var theme = completion.cm.options.theme;
|
const theme = completion.cm.options.theme
|
||||||
hints.className = "CodeMirror-hints " + theme;
|
hints.className = 'CodeMirror-hints ' + theme
|
||||||
this.selectedHint = data.selectedHint || 0;
|
this.selectedHint = data.selectedHint || 0
|
||||||
|
|
||||||
var completions = data.list;
|
const completions = data.list
|
||||||
for (var i = 0; i < completions.length; ++i) {
|
for (let i = 0; i < completions.length; ++i) {
|
||||||
var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i];
|
const elt = hints.appendChild(ownerDocument.createElement('li')); const cur = completions[i]
|
||||||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
|
let className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
|
||||||
if (cur.className != null) className = cur.className + " " + className;
|
if (cur.className != null) className = cur.className + ' ' + className
|
||||||
elt.className = className;
|
elt.className = className
|
||||||
if (i == this.selectedHint) elt.setAttribute("aria-selected", "true")
|
if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true')
|
||||||
elt.id = this.id + "-" + i
|
elt.id = this.id + '-' + i
|
||||||
elt.setAttribute("role", "option")
|
elt.setAttribute('role', 'option')
|
||||||
if (cur.render) cur.render(elt, data, cur);
|
if (cur.render) cur.render(elt, data, cur)
|
||||||
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
|
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)))
|
||||||
elt.hintId = i;
|
elt.hintId = i
|
||||||
}
|
}
|
||||||
|
|
||||||
var container = completion.options.container || ownerDocument.body;
|
const container = completion.options.container || ownerDocument.body
|
||||||
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
|
let pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
|
||||||
var left = pos.left, top = pos.bottom, below = true;
|
let left = pos.left; let top = pos.bottom; let below = true
|
||||||
var offsetLeft = 0, offsetTop = 0;
|
let offsetLeft = 0; let offsetTop = 0
|
||||||
if (container !== ownerDocument.body) {
|
if (container !== ownerDocument.body) {
|
||||||
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
|
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
|
||||||
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
|
const isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1
|
||||||
var offsetParent = isContainerPositioned ? container : container.offsetParent;
|
const offsetParent = isContainerPositioned ? container : container.offsetParent
|
||||||
var offsetParentPosition = offsetParent.getBoundingClientRect();
|
const offsetParentPosition = offsetParent.getBoundingClientRect()
|
||||||
var bodyPosition = ownerDocument.body.getBoundingClientRect();
|
const bodyPosition = ownerDocument.body.getBoundingClientRect()
|
||||||
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
|
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft)
|
||||||
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
|
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop)
|
||||||
}
|
}
|
||||||
hints.style.left = (left - offsetLeft) + "px";
|
hints.style.left = (left - offsetLeft) + 'px'
|
||||||
hints.style.top = (top - offsetTop) + "px";
|
hints.style.top = (top - offsetTop) + 'px'
|
||||||
// todo 隐藏codemirror自带的提示
|
// todo 隐藏codemirror自带的提示
|
||||||
hints.style.display = 'none'
|
hints.style.display = 'none'
|
||||||
|
|
||||||
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
||||||
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
|
const winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
|
||||||
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
|
const winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
|
||||||
//在这里 添加的DOM 元素 -- 该方案 实现复杂算了吧
|
// 在这里 添加的DOM 元素 -- 该方案 实现复杂算了吧
|
||||||
container.appendChild(hints);
|
container.appendChild(hints)
|
||||||
// debugger
|
// debugger
|
||||||
// $(container).append(
|
// $(container).append(
|
||||||
// `
|
// `
|
||||||
// <div>
|
// <div>
|
||||||
// <h1>hahah</h1>
|
// <h1>hahah</h1>
|
||||||
// ${ hints }
|
// ${ hints }
|
||||||
// </div>
|
// </div>
|
||||||
// `
|
// `
|
||||||
// )
|
// )
|
||||||
cm.getInputField().setAttribute("aria-autocomplete", "list")
|
cm.getInputField().setAttribute('aria-autocomplete', 'list')
|
||||||
cm.getInputField().setAttribute("aria-owns", this.id)
|
cm.getInputField().setAttribute('aria-owns', this.id)
|
||||||
cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint)
|
cm.getInputField().setAttribute('aria-activedescendant', this.id + '-' + this.selectedHint)
|
||||||
|
|
||||||
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
|
let box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
|
||||||
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
|
const scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
|
||||||
|
|
||||||
// Compute in the timeout to avoid reflow on init
|
// Compute in the timeout to avoid reflow on init
|
||||||
var startScroll;
|
let startScroll
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
startScroll = cm.getScrollInfo();
|
startScroll = cm.getScrollInfo()
|
||||||
});
|
})
|
||||||
|
|
||||||
var overlapY = box.bottom - winH;
|
const overlapY = box.bottom - winH
|
||||||
if (overlapY > 0) {
|
if (overlapY > 0) {
|
||||||
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
|
const height = box.bottom - box.top; const curTop = pos.top - (pos.bottom - box.top)
|
||||||
if (curTop - height > 0) { // Fits above cursor
|
if (curTop - height > 0) { // Fits above cursor
|
||||||
hints.style.top = (top = pos.top - height - offsetTop) + "px";
|
hints.style.top = (top = pos.top - height - offsetTop) + 'px'
|
||||||
below = false;
|
below = false
|
||||||
} else if (height > winH) {
|
} else if (height > winH) {
|
||||||
hints.style.height = (winH - 5) + "px";
|
hints.style.height = (winH - 5) + 'px'
|
||||||
hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
|
hints.style.top = (top = pos.bottom - box.top - offsetTop) + 'px'
|
||||||
var cursor = cm.getCursor();
|
const cursor = cm.getCursor()
|
||||||
if (data.from.ch != cursor.ch) {
|
if (data.from.ch != cursor.ch) {
|
||||||
pos = cm.cursorCoords(cursor);
|
pos = cm.cursorCoords(cursor)
|
||||||
hints.style.left = (left = pos.left - offsetLeft) + "px";
|
hints.style.left = (left = pos.left - offsetLeft) + 'px'
|
||||||
box = hints.getBoundingClientRect();
|
box = hints.getBoundingClientRect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var overlapX = box.right - winW;
|
let overlapX = box.right - winW
|
||||||
if (scrolls) overlapX += cm.display.nativeBarWidth;
|
if (scrolls) overlapX += cm.display.nativeBarWidth
|
||||||
if (overlapX > 0) {
|
if (overlapX > 0) {
|
||||||
if (box.right - box.left > winW) {
|
if (box.right - box.left > winW) {
|
||||||
hints.style.width = (winW - 5) + "px";
|
hints.style.width = (winW - 5) + 'px'
|
||||||
overlapX -= (box.right - box.left) - winW;
|
overlapX -= (box.right - box.left) - winW
|
||||||
}
|
}
|
||||||
hints.style.left = (left = Math.max(pos.left - overlapX - offsetLeft, 0)) + "px";
|
hints.style.left = (left = Math.max(pos.left - overlapX - offsetLeft, 0)) + 'px'
|
||||||
|
}
|
||||||
|
if (scrolls) {
|
||||||
|
for (let node = hints.firstChild; node; node = node.nextSibling) { node.style.paddingRight = cm.display.nativeBarWidth + 'px' }
|
||||||
}
|
}
|
||||||
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
|
|
||||||
node.style.paddingRight = cm.display.nativeBarWidth + "px"
|
|
||||||
|
|
||||||
// debugger
|
// debugger
|
||||||
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
|
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
|
||||||
moveFocus: function (n, avoidWrap) {
|
moveFocus: function (n, avoidWrap) {
|
||||||
widget.changeActive(widget.selectedHint + n, avoidWrap);
|
widget.changeActive(widget.selectedHint + n, avoidWrap)
|
||||||
},
|
},
|
||||||
setFocus: function (n) {
|
setFocus: function (n) {
|
||||||
widget.changeActive(n);
|
widget.changeActive(n)
|
||||||
},
|
},
|
||||||
menuSize: function () {
|
menuSize: function () {
|
||||||
return widget.screenAmount();
|
return widget.screenAmount()
|
||||||
},
|
},
|
||||||
length: completions.length,
|
length: completions.length,
|
||||||
close: function () {
|
close: function () {
|
||||||
completion.close();
|
completion.close()
|
||||||
},
|
},
|
||||||
pick: function () {
|
pick: function () {
|
||||||
widget.pick();
|
widget.pick()
|
||||||
},
|
},
|
||||||
data: data
|
data: data
|
||||||
}));
|
}))
|
||||||
|
|
||||||
if (completion.options.closeOnUnfocus) {
|
if (completion.options.closeOnUnfocus) {
|
||||||
var closingOnBlur;
|
let closingOnBlur
|
||||||
cm.on("blur", this.onBlur = function () {
|
cm.on('blur', this.onBlur = function () {
|
||||||
closingOnBlur = setTimeout(function () {
|
closingOnBlur = setTimeout(function () {
|
||||||
completion.close();
|
completion.close()
|
||||||
}, 100);
|
}, 100)
|
||||||
});
|
})
|
||||||
cm.on("focus", this.onFocus = function () {
|
cm.on('focus', this.onFocus = function () {
|
||||||
clearTimeout(closingOnBlur);
|
clearTimeout(closingOnBlur)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
cm.on("scroll", this.onScroll = function () {
|
cm.on('scroll', this.onScroll = function () {
|
||||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
|
const curScroll = cm.getScrollInfo(); const editor = cm.getWrapperElement().getBoundingClientRect()
|
||||||
if (!startScroll) startScroll = cm.getScrollInfo();
|
if (!startScroll) startScroll = cm.getScrollInfo()
|
||||||
var newTop = top + startScroll.top - curScroll.top;
|
const newTop = top + startScroll.top - curScroll.top
|
||||||
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
|
let point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
|
||||||
if (!below) point += hints.offsetHeight;
|
if (!below) point += hints.offsetHeight
|
||||||
if (point <= editor.top || point >= editor.bottom) return completion.close();
|
if (point <= editor.top || point >= editor.bottom) return completion.close()
|
||||||
hints.style.top = newTop + "px";
|
hints.style.top = newTop + 'px'
|
||||||
hints.style.left = (left + startScroll.left - curScroll.left) + "px";
|
hints.style.left = (left + startScroll.left - curScroll.left) + 'px'
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.on(hints, "dblclick", function (e) {
|
CodeMirror.on(hints, 'dblclick', function (e) {
|
||||||
var t = getHintElement(hints, e.target || e.srcElement);
|
const t = getHintElement(hints, e.target || e.srcElement)
|
||||||
if (t && t.hintId != null) {
|
if (t && t.hintId != null) {
|
||||||
widget.changeActive(t.hintId);
|
widget.changeActive(t.hintId)
|
||||||
widget.pick();
|
widget.pick()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.on(hints, "click", function (e) {
|
CodeMirror.on(hints, 'click', function (e) {
|
||||||
var t = getHintElement(hints, e.target || e.srcElement);
|
const t = getHintElement(hints, e.target || e.srcElement)
|
||||||
if (t && t.hintId != null) {
|
if (t && t.hintId != null) {
|
||||||
widget.changeActive(t.hintId);
|
widget.changeActive(t.hintId)
|
||||||
if (completion.options.completeOnSingleClick) widget.pick();
|
if (completion.options.completeOnSingleClick) widget.pick()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.on(hints, "mousedown", function () {
|
CodeMirror.on(hints, 'mousedown', function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
cm.focus();
|
cm.focus()
|
||||||
}, 20);
|
}, 20)
|
||||||
});
|
})
|
||||||
|
|
||||||
// The first hint doesn't need to be scrolled to on init
|
// The first hint doesn't need to be scrolled to on init
|
||||||
var selectedHintRange = this.getSelectedHintRange();
|
const selectedHintRange = this.getSelectedHintRange()
|
||||||
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
|
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
|
||||||
this.scrollToActive();
|
this.scrollToActive()
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
|
CodeMirror.signal(data, 'select', completions[this.selectedHint], hints.childNodes[this.selectedHint])
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget.prototype = {
|
Widget.prototype = {
|
||||||
close: function () {
|
close: function () {
|
||||||
if (this.completion.widget != this) return;
|
if (this.completion.widget != this) return
|
||||||
this.completion.widget = null;
|
this.completion.widget = null
|
||||||
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
|
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints)
|
||||||
this.completion.cm.removeKeyMap(this.keyMap);
|
this.completion.cm.removeKeyMap(this.keyMap)
|
||||||
var input = this.completion.cm.getInputField()
|
const input = this.completion.cm.getInputField()
|
||||||
input.removeAttribute("aria-activedescendant")
|
input.removeAttribute('aria-activedescendant')
|
||||||
input.removeAttribute("aria-owns")
|
input.removeAttribute('aria-owns')
|
||||||
|
|
||||||
var cm = this.completion.cm;
|
const cm = this.completion.cm
|
||||||
if (this.completion.options.closeOnUnfocus) {
|
if (this.completion.options.closeOnUnfocus) {
|
||||||
cm.off("blur", this.onBlur);
|
cm.off('blur', this.onBlur)
|
||||||
cm.off("focus", this.onFocus);
|
cm.off('focus', this.onFocus)
|
||||||
}
|
}
|
||||||
cm.off("scroll", this.onScroll);
|
cm.off('scroll', this.onScroll)
|
||||||
},
|
},
|
||||||
|
|
||||||
disable: function () {
|
disable: function () {
|
||||||
this.completion.cm.removeKeyMap(this.keyMap);
|
this.completion.cm.removeKeyMap(this.keyMap)
|
||||||
var widget = this;
|
const widget = this
|
||||||
this.keyMap = {
|
this.keyMap = {
|
||||||
Enter: function () {
|
Enter: function () {
|
||||||
widget.picked = true;
|
widget.picked = true
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
this.completion.cm.addKeyMap(this.keyMap);
|
this.completion.cm.addKeyMap(this.keyMap)
|
||||||
},
|
},
|
||||||
|
|
||||||
pick: function () {
|
pick: function () {
|
||||||
this.completion.pick(this.data, this.selectedHint);
|
this.completion.pick(this.data, this.selectedHint)
|
||||||
},
|
},
|
||||||
|
|
||||||
changeActive: function (i, avoidWrap) {
|
changeActive: function (i, avoidWrap) {
|
||||||
if (i >= this.data.list.length)
|
if (i >= this.data.list.length) { i = avoidWrap ? this.data.list.length - 1 : 0 } else if (i < 0) { i = avoidWrap ? 0 : this.data.list.length - 1 }
|
||||||
i = avoidWrap ? this.data.list.length - 1 : 0;
|
if (this.selectedHint == i) return
|
||||||
else if (i < 0)
|
let node = this.hints.childNodes[this.selectedHint]
|
||||||
i = avoidWrap ? 0 : this.data.list.length - 1;
|
|
||||||
if (this.selectedHint == i) return;
|
|
||||||
var node = this.hints.childNodes[this.selectedHint];
|
|
||||||
if (node) {
|
if (node) {
|
||||||
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
|
node.className = node.className.replace(' ' + ACTIVE_HINT_ELEMENT_CLASS, '')
|
||||||
node.removeAttribute("aria-selected")
|
node.removeAttribute('aria-selected')
|
||||||
}
|
}
|
||||||
node = this.hints.childNodes[this.selectedHint = i];
|
node = this.hints.childNodes[this.selectedHint = i]
|
||||||
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
|
node.className += ' ' + ACTIVE_HINT_ELEMENT_CLASS
|
||||||
node.setAttribute("aria-selected", "true")
|
node.setAttribute('aria-selected', 'true')
|
||||||
this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id)
|
this.completion.cm.getInputField().setAttribute('aria-activedescendant', node.id)
|
||||||
this.scrollToActive()
|
this.scrollToActive()
|
||||||
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
|
CodeMirror.signal(this.data, 'select', this.data.list[this.selectedHint], node)
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToActive: function () {
|
scrollToActive: function () {
|
||||||
var selectedHintRange = this.getSelectedHintRange();
|
const selectedHintRange = this.getSelectedHintRange()
|
||||||
var node1 = this.hints.childNodes[selectedHintRange.from];
|
const node1 = this.hints.childNodes[selectedHintRange.from]
|
||||||
var node2 = this.hints.childNodes[selectedHintRange.to];
|
const node2 = this.hints.childNodes[selectedHintRange.to]
|
||||||
var firstNode = this.hints.firstChild;
|
const firstNode = this.hints.firstChild
|
||||||
if (node1.offsetTop < this.hints.scrollTop)
|
if (node1.offsetTop < this.hints.scrollTop) { this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop } else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) { this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop }
|
||||||
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
|
|
||||||
else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
|
||||||
this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
screenAmount: function () {
|
screenAmount: function () {
|
||||||
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
|
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1
|
||||||
},
|
},
|
||||||
|
|
||||||
getSelectedHintRange: function () {
|
getSelectedHintRange: function () {
|
||||||
var margin = this.completion.options.scrollMargin || 0;
|
const margin = this.completion.options.scrollMargin || 0
|
||||||
return {
|
return {
|
||||||
from: Math.max(0, this.selectedHint - margin),
|
from: Math.max(0, this.selectedHint - margin),
|
||||||
to: Math.min(this.data.list.length - 1, this.selectedHint + margin),
|
to: Math.min(this.data.list.length - 1, this.selectedHint + margin)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function applicableHelpers(cm, helpers) {
|
function applicableHelpers (cm, helpers) {
|
||||||
if (!cm.somethingSelected()) return helpers
|
if (!cm.somethingSelected()) return helpers
|
||||||
var result = []
|
const result = []
|
||||||
for (var i = 0; i < helpers.length; i++)
|
for (let i = 0; i < helpers.length; i++) { if (helpers[i].supportsSelection) result.push(helpers[i]) }
|
||||||
if (helpers[i].supportsSelection) result.push(helpers[i])
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHints(hint, cm, options, callback) {
|
function fetchHints (hint, cm, options, callback) {
|
||||||
if (hint.async) {
|
if (hint.async) {
|
||||||
hint(cm, callback, options)
|
hint(cm, callback, options)
|
||||||
} else {
|
} else {
|
||||||
var result = hint(cm, options)
|
const result = hint(cm, options)
|
||||||
if (result && result.then) result.then(callback)
|
if (result && result.then) result.then(callback)
|
||||||
else callback(result)
|
else callback(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveAutoHints(cm, pos) {
|
function resolveAutoHints (cm, pos) {
|
||||||
var helpers = cm.getHelpers(pos, "hint"), words
|
const helpers = cm.getHelpers(pos, 'hint'); let words
|
||||||
if (helpers.length) {
|
if (helpers.length) {
|
||||||
var resolved = function (cm, callback, options) {
|
const resolved = function (cm, callback, options) {
|
||||||
var app = applicableHelpers(cm, helpers);
|
const app = applicableHelpers(cm, helpers)
|
||||||
|
|
||||||
function run(i) {
|
function run (i) {
|
||||||
if (i == app.length) return callback(null)
|
if (i == app.length) return callback(null)
|
||||||
fetchHints(app[i], cm, options, function (result) {
|
fetchHints(app[i], cm, options, function (result) {
|
||||||
if (result && result.list.length > 0) callback(result)
|
if (result && result.list.length > 0) callback(result)
|
||||||
@@ -532,9 +528,9 @@ export default function showHint(CodeMirror) {
|
|||||||
resolved.async = true
|
resolved.async = true
|
||||||
resolved.supportsSelection = true
|
resolved.supportsSelection = true
|
||||||
return resolved
|
return resolved
|
||||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
} else if (words = cm.getHelper(cm.getCursor(), 'hintWords')) {
|
||||||
return function (cm) {
|
return function (cm) {
|
||||||
return CodeMirror.hint.fromList(cm, {words: words})
|
return CodeMirror.hint.fromList(cm, { words: words })
|
||||||
}
|
}
|
||||||
} else if (CodeMirror.hint.anyword) {
|
} else if (CodeMirror.hint.anyword) {
|
||||||
return function (cm, options) {
|
return function (cm, options) {
|
||||||
@@ -546,30 +542,29 @@ export default function showHint(CodeMirror) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "auto", {
|
CodeMirror.registerHelper('hint', 'auto', {
|
||||||
resolve: resolveAutoHints
|
resolve: resolveAutoHints
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "fromList", function (cm, options) {
|
CodeMirror.registerHelper('hint', 'fromList', function (cm, options) {
|
||||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
|
const cur = cm.getCursor(); const token = cm.getTokenAt(cur)
|
||||||
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
|
let term; let from = CodeMirror.Pos(cur.line, token.start); const to = cur
|
||||||
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
|
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
|
||||||
term = token.string.substr(0, cur.ch - token.start)
|
term = token.string.substr(0, cur.ch - token.start)
|
||||||
} else {
|
} else {
|
||||||
term = ""
|
term = ''
|
||||||
from = cur
|
from = cur
|
||||||
}
|
}
|
||||||
var found = [];
|
const found = []
|
||||||
for (var i = 0; i < options.words.length; i++) {
|
for (let i = 0; i < options.words.length; i++) {
|
||||||
var word = options.words[i];
|
const word = options.words[i]
|
||||||
if (word.slice(0, term.length) == term)
|
if (word.slice(0, term.length) == term) { found.push(word) }
|
||||||
found.push(word);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found.length) return {list: found, from: from, to: to};
|
if (found.length) return { list: found, from: from, to: to }
|
||||||
});
|
})
|
||||||
|
|
||||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
CodeMirror.commands.autocomplete = CodeMirror.showHint
|
||||||
|
|
||||||
var defaultOptions = {
|
var defaultOptions = {
|
||||||
hint: CodeMirror.hint.auto,
|
hint: CodeMirror.hint.auto,
|
||||||
@@ -584,8 +579,8 @@ export default function showHint(CodeMirror) {
|
|||||||
customKeys: null,
|
customKeys: null,
|
||||||
extraKeys: null,
|
extraKeys: null,
|
||||||
paddingForScrollbar: true,
|
paddingForScrollbar: true,
|
||||||
moveOnOverlap: true,
|
moveOnOverlap: true
|
||||||
};
|
}
|
||||||
|
|
||||||
CodeMirror.defineOption("hintOptions", null);
|
CodeMirror.defineOption('hintOptions', null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,343 +1,336 @@
|
|||||||
import {cloneDeep} from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import {matchMain} from './matchRelatedInfo'
|
import { matchMain } from './matchRelatedInfo'
|
||||||
|
|
||||||
export default function (CodeMirror,
|
export default function (CodeMirror,
|
||||||
{
|
{
|
||||||
dataset,
|
dataset,
|
||||||
hinthook, //生成提示的hook 拦截
|
hinthook, // 生成提示的hook 拦截
|
||||||
keywordshook //关键字hook 在关键字里面
|
keywordshook // 关键字hook 在关键字里面
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
// "use strict";
|
// "use strict";
|
||||||
|
|
||||||
var tables;
|
let tables
|
||||||
var defaultTable;
|
let defaultTable
|
||||||
var keywords;
|
let keywords
|
||||||
var identifierQuote;
|
let identifierQuote
|
||||||
var CONS = {
|
const CONS = {
|
||||||
QUERY_DIV: ";",
|
QUERY_DIV: ';',
|
||||||
ALIAS_KEYWORD: "AS"
|
ALIAS_KEYWORD: 'AS'
|
||||||
};
|
}
|
||||||
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
|
const Pos = CodeMirror.Pos; const cmpPos = CodeMirror.cmpPos
|
||||||
|
|
||||||
function isArray(val) {
|
function isArray (val) {
|
||||||
return Object.prototype.toString.call(val) == "[object Array]"
|
return Object.prototype.toString.call(val) == '[object Array]'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeywords(editor) {
|
function getKeywords (editor) {
|
||||||
var mode = editor.doc.modeOption;
|
let mode = editor.doc.modeOption
|
||||||
if (mode === "sql") mode = "text/x-sql";
|
if (mode === 'sql') mode = 'text/x-sql'
|
||||||
keywords = CodeMirror.resolveMode(mode).keywords;
|
keywords = CodeMirror.resolveMode(mode).keywords
|
||||||
if (keywordshook) {
|
if (keywordshook) {
|
||||||
keywords = keywordshook(keywords, CodeMirror.resolveMode(mode)) || keywords
|
keywords = keywordshook(keywords, CodeMirror.resolveMode(mode)) || keywords
|
||||||
}
|
}
|
||||||
return keywords
|
return keywords
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIdentifierQuote(editor) {
|
function getIdentifierQuote (editor) {
|
||||||
var mode = editor.doc.modeOption;
|
let mode = editor.doc.modeOption
|
||||||
if (mode === "sql") mode = "text/x-sql";
|
if (mode === 'sql') mode = 'text/x-sql'
|
||||||
return CodeMirror.resolveMode(mode).identifierQuote || "`";
|
return CodeMirror.resolveMode(mode).identifierQuote || '`'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(item) {
|
function getText (item) {
|
||||||
return typeof item == "string" ? item : item.text;
|
return typeof item == 'string' ? item : item.text
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapTable(name, value) {
|
function wrapTable (name, value) {
|
||||||
if (isArray(value)) value = {columns: value}
|
if (isArray(value)) value = { columns: value }
|
||||||
if (!value.text) value.text = name
|
if (!value.text) value.text = name
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTables(input) {
|
function parseTables (input) {
|
||||||
//table 名称变大写 统一变成对象格式 columns text
|
// table 名称变大写 统一变成对象格式 columns text
|
||||||
var result = {}
|
const result = {}
|
||||||
if (isArray(input)) {
|
if (isArray(input)) {
|
||||||
for (var i = input.length - 1; i >= 0; i--) {
|
for (let i = input.length - 1; i >= 0; i--) {
|
||||||
var item = input[i]
|
const item = input[i]
|
||||||
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
||||||
}
|
}
|
||||||
} else if (input) {
|
} else if (input) {
|
||||||
for (var name in input)
|
for (const name in input) { result[name.toUpperCase()] = wrapTable(name, input[name]) }
|
||||||
result[name.toUpperCase()] = wrapTable(name, input[name])
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTable(name) {
|
function getTable (name) {
|
||||||
return tables[name.toUpperCase()]
|
return tables[name.toUpperCase()]
|
||||||
}
|
}
|
||||||
|
|
||||||
function shallowClone(object) {
|
function shallowClone (object) {
|
||||||
var result = {};
|
const result = {}
|
||||||
for (var key in object) if (object.hasOwnProperty(key))
|
for (const key in object) {
|
||||||
result[key] = object[key];
|
if (object.hasOwnProperty(key)) { result[key] = object[key] }
|
||||||
return result;
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function match(string, word) {
|
function match (string, word) {
|
||||||
var len = string.length;
|
const len = string.length
|
||||||
var sub = getText(word).substr(0, len);
|
const sub = getText(word).substr(0, len)
|
||||||
return string.toUpperCase() === sub.toUpperCase();
|
return string.toUpperCase() === sub.toUpperCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMatches(result, search, wordlist, formatter) {
|
function addMatches (result, search, wordlist, formatter) {
|
||||||
if (isArray(wordlist)) {
|
if (isArray(wordlist)) {
|
||||||
for (var i = 0; i < wordlist.length; i++)
|
for (let i = 0; i < wordlist.length; i++) { if (match(search, wordlist[i])) result.push(formatter(wordlist[i])) }
|
||||||
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
|
|
||||||
} else {
|
} else {
|
||||||
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
|
for (const word in wordlist) {
|
||||||
var val = wordlist[word]
|
if (wordlist.hasOwnProperty(word)) {
|
||||||
if (!val || val === true)
|
let val = wordlist[word]
|
||||||
val = word
|
if (!val || val === true) { val = word } else { val = val.displayText ? { text: val.text, displayText: val.displayText } : val.text }
|
||||||
else
|
if (match(search, val)) result.push(formatter(val))
|
||||||
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
|
}
|
||||||
if (match(search, val)) result.push(formatter(val))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanName(name) {
|
function cleanName (name) {
|
||||||
// Get rid name from identifierQuote and preceding dot(.)
|
// Get rid name from identifierQuote and preceding dot(.)
|
||||||
if (name.charAt(0) == ".") {
|
if (name.charAt(0) == '.') {
|
||||||
name = name.substr(1);
|
name = name.substr(1)
|
||||||
}
|
}
|
||||||
// replace duplicated identifierQuotes with single identifierQuotes
|
// replace duplicated identifierQuotes with single identifierQuotes
|
||||||
// and remove single identifierQuotes
|
// and remove single identifierQuotes
|
||||||
var nameParts = name.split(identifierQuote + identifierQuote);
|
const nameParts = name.split(identifierQuote + identifierQuote)
|
||||||
for (var i = 0; i < nameParts.length; i++)
|
for (let i = 0; i < nameParts.length; i++) { nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote, 'g'), '') }
|
||||||
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote, "g"), "");
|
return nameParts.join(identifierQuote)
|
||||||
return nameParts.join(identifierQuote);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertIdentifierQuotes(name) {
|
function insertIdentifierQuotes (name) {
|
||||||
var nameParts = getText(name).split(".");
|
const nameParts = getText(name).split('.')
|
||||||
for (var i = 0; i < nameParts.length; i++)
|
for (let i = 0; i < nameParts.length; i++) {
|
||||||
nameParts[i] = identifierQuote +
|
nameParts[i] = identifierQuote +
|
||||||
// duplicate identifierQuotes
|
// duplicate identifierQuotes
|
||||||
nameParts[i].replace(new RegExp(identifierQuote, "g"), identifierQuote + identifierQuote) +
|
nameParts[i].replace(new RegExp(identifierQuote, 'g'), identifierQuote + identifierQuote) +
|
||||||
identifierQuote;
|
identifierQuote
|
||||||
var escaped = nameParts.join(".");
|
}
|
||||||
if (typeof name == "string") return escaped;
|
const escaped = nameParts.join('.')
|
||||||
name = shallowClone(name);
|
if (typeof name == 'string') return escaped
|
||||||
name.text = escaped;
|
name = shallowClone(name)
|
||||||
return name;
|
name.text = escaped
|
||||||
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLeftpart(cur, token, result, editor) {
|
function getLeftpart (cur, token, result, editor) {
|
||||||
var nameParts = [];
|
const nameParts = []
|
||||||
var start = token.start;
|
let start = token.start
|
||||||
var cont = true;
|
let cont = true
|
||||||
while (cont) {
|
while (cont) {
|
||||||
//全是空格 或者 是操作符 就接着往前找
|
// 全是空格 或者 是操作符 就接着往前找
|
||||||
cont = ((token.type === 'operator' || token.string.match(/^[ ]*$/)) && start !== 0);
|
cont = ((token.type === 'operator' || token.string.match(/^[ ]*$/)) && start !== 0)
|
||||||
start = token.start;
|
start = token.start
|
||||||
nameParts.unshift(token.string);
|
nameParts.unshift(token.string)
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
if (token.type === 'operator') {
|
if (token.type === 'operator') {
|
||||||
cont = true;
|
cont = true
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nameParts[0]
|
return nameParts[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRightpart(cur, token, result, editor) {
|
function isRightpart (cur, token, result, editor) {
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
return token.type === 'operator'
|
return token.type === 'operator'
|
||||||
}
|
}
|
||||||
|
|
||||||
function nameCompletion(cur, token, result, editor) {
|
function nameCompletion (cur, token, result, editor) {
|
||||||
// Try to complete table, column names and return start position of completion
|
// Try to complete table, column names and return start position of completion
|
||||||
var useIdentifierQuotes = false;
|
let useIdentifierQuotes = false
|
||||||
var nameParts = [];
|
const nameParts = []
|
||||||
var start = token.start;
|
let start = token.start
|
||||||
var cont = true;
|
let cont = true
|
||||||
while (cont) {
|
while (cont) {
|
||||||
cont = (token.string.charAt(0) == ".");
|
cont = (token.string.charAt(0) == '.')
|
||||||
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
|
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote)
|
||||||
|
|
||||||
start = token.start;
|
start = token.start
|
||||||
nameParts.unshift(cleanName(token.string));
|
nameParts.unshift(cleanName(token.string))
|
||||||
|
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
if (token.string == ".") {
|
if (token.string == '.') {
|
||||||
cont = true;
|
cont = true
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
token = editor.getTokenAt(Pos(cur.line, token.start))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to complete table names
|
// Try to complete table names
|
||||||
var string = nameParts.join(".");
|
let string = nameParts.join('.')
|
||||||
addMatches(result, string, tables, function (w) {
|
addMatches(result, string, tables, function (w) {
|
||||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
|
||||||
});
|
})
|
||||||
|
|
||||||
// Try to complete columns from defaultTable
|
// Try to complete columns from defaultTable
|
||||||
addMatches(result, string, defaultTable, function (w) {
|
addMatches(result, string, defaultTable, function (w) {
|
||||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
|
||||||
});
|
})
|
||||||
|
|
||||||
// Try to complete columns
|
// Try to complete columns
|
||||||
string = nameParts.pop();
|
string = nameParts.pop()
|
||||||
var table = nameParts.join(".");
|
let table = nameParts.join('.')
|
||||||
|
|
||||||
var alias = false;
|
let alias = false
|
||||||
var aliasTable = table;
|
const aliasTable = table
|
||||||
// Check if table is available. If not, find table by Alias
|
// Check if table is available. If not, find table by Alias
|
||||||
if (!getTable(table)) {
|
if (!getTable(table)) {
|
||||||
var oldTable = table;
|
const oldTable = table
|
||||||
table = findTableByAlias(table, editor);
|
table = findTableByAlias(table, editor)
|
||||||
if (table !== oldTable) alias = true;
|
if (table !== oldTable) alias = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var columns = getTable(table);
|
let columns = getTable(table)
|
||||||
if (columns && columns.columns)
|
if (columns && columns.columns) { columns = columns.columns }
|
||||||
columns = columns.columns;
|
|
||||||
|
|
||||||
if (columns) {
|
if (columns) {
|
||||||
addMatches(result, string, columns, function (w) {
|
addMatches(result, string, columns, function (w) {
|
||||||
var tableInsert = table;
|
let tableInsert = table
|
||||||
if (alias == true) tableInsert = aliasTable;
|
if (alias == true) tableInsert = aliasTable
|
||||||
if (typeof w == "string") {
|
if (typeof w == 'string') {
|
||||||
w = tableInsert + "." + w;
|
w = tableInsert + '.' + w
|
||||||
} else {
|
} else {
|
||||||
w = shallowClone(w);
|
w = shallowClone(w)
|
||||||
w.text = tableInsert + "." + w.text;
|
w.text = tableInsert + '.' + w.text
|
||||||
}
|
}
|
||||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
return start;
|
return start
|
||||||
}
|
}
|
||||||
|
|
||||||
function eachWord(lineText, f) {
|
function eachWord (lineText, f) {
|
||||||
var words = lineText.split(/\s+/)
|
const words = lineText.split(/\s+/)
|
||||||
for (var i = 0; i < words.length; i++)
|
for (let i = 0; i < words.length; i++) { if (words[i]) f(words[i].replace(/[`,;]/g, '')) }
|
||||||
if (words[i]) f(words[i].replace(/[`,;]/g, ''))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function findTableByAlias(alias, editor) {
|
function findTableByAlias (alias, editor) {
|
||||||
var doc = editor.doc;
|
const doc = editor.doc
|
||||||
var fullQuery = doc.getValue();
|
const fullQuery = doc.getValue()
|
||||||
var aliasUpperCase = alias.toUpperCase();
|
const aliasUpperCase = alias.toUpperCase()
|
||||||
var previousWord = "";
|
let previousWord = ''
|
||||||
var table = "";
|
let table = ''
|
||||||
var separator = [];
|
const separator = []
|
||||||
var validRange = {
|
let validRange = {
|
||||||
start: Pos(0, 0),
|
start: Pos(0, 0),
|
||||||
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
|
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
|
||||||
};
|
|
||||||
|
|
||||||
//add separator
|
|
||||||
var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
|
|
||||||
while (indexOfSeparator != -1) {
|
|
||||||
separator.push(doc.posFromIndex(indexOfSeparator));
|
|
||||||
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator + 1);
|
|
||||||
}
|
}
|
||||||
separator.unshift(Pos(0, 0));
|
|
||||||
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
|
|
||||||
|
|
||||||
//find valid range
|
// add separator
|
||||||
var prevItem = null;
|
let indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV)
|
||||||
var current = editor.getCursor()
|
while (indexOfSeparator != -1) {
|
||||||
|
separator.push(doc.posFromIndex(indexOfSeparator))
|
||||||
|
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator + 1)
|
||||||
|
}
|
||||||
|
separator.unshift(Pos(0, 0))
|
||||||
|
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length))
|
||||||
|
|
||||||
|
// find valid range
|
||||||
|
let prevItem = null
|
||||||
|
const current = editor.getCursor()
|
||||||
for (var i = 0; i < separator.length; i++) {
|
for (var i = 0; i < separator.length; i++) {
|
||||||
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
||||||
validRange = {start: prevItem, end: separator[i]};
|
validRange = { start: prevItem, end: separator[i] }
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
prevItem = separator[i];
|
prevItem = separator[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validRange.start) {
|
if (validRange.start) {
|
||||||
var query = doc.getRange(validRange.start, validRange.end, false);
|
const query = doc.getRange(validRange.start, validRange.end, false)
|
||||||
|
|
||||||
for (var i = 0; i < query.length; i++) {
|
for (var i = 0; i < query.length; i++) {
|
||||||
var lineText = query[i];
|
const lineText = query[i]
|
||||||
eachWord(lineText, function (word) {
|
eachWord(lineText, function (word) {
|
||||||
var wordUpperCase = word.toUpperCase();
|
const wordUpperCase = word.toUpperCase()
|
||||||
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
|
if (wordUpperCase === aliasUpperCase && getTable(previousWord)) { table = previousWord }
|
||||||
table = previousWord;
|
if (wordUpperCase !== CONS.ALIAS_KEYWORD) { previousWord = word }
|
||||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
})
|
||||||
previousWord = word;
|
if (table) break
|
||||||
});
|
|
||||||
if (table) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return table;
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "sql", function (editor, options) {
|
CodeMirror.registerHelper('hint', 'sql', function (editor, options) {
|
||||||
tables = parseTables(options && options.tables);
|
tables = parseTables(options && options.tables)
|
||||||
var defaultTableName = options && options.defaultTable; //默认table 名称
|
const defaultTableName = options && options.defaultTable // 默认table 名称
|
||||||
var disableKeywords = options && options.disableKeywords; //禁用的keyword
|
const disableKeywords = options && options.disableKeywords // 禁用的keyword
|
||||||
defaultTable = defaultTableName && getTable(defaultTableName);
|
defaultTable = defaultTableName && getTable(defaultTableName)
|
||||||
keywords = getKeywords(editor); //获取 定义defineMIME 时候的关键字参数
|
keywords = getKeywords(editor) // 获取 定义defineMIME 时候的关键字参数
|
||||||
identifierQuote = getIdentifierQuote(editor); //获取 引用标识符
|
identifierQuote = getIdentifierQuote(editor) // 获取 引用标识符
|
||||||
|
|
||||||
if (defaultTableName && !defaultTable)
|
if (defaultTableName && !defaultTable) { defaultTable = findTableByAlias(defaultTableName, editor) }
|
||||||
defaultTable = findTableByAlias(defaultTableName, editor);
|
|
||||||
|
|
||||||
defaultTable = defaultTable || [];
|
defaultTable = defaultTable || []
|
||||||
|
|
||||||
if (defaultTable.columns)
|
if (defaultTable.columns) { defaultTable = defaultTable.columns }
|
||||||
defaultTable = defaultTable.columns;
|
|
||||||
|
|
||||||
var cur = editor.getCursor(); //line 当前行 ch 索引 sticky ??
|
const cur = editor.getCursor() // line 当前行 ch 索引 sticky ??
|
||||||
var result = [];
|
let result = []
|
||||||
var token = editor.getTokenAt(cur), start, end, search;
|
const token = editor.getTokenAt(cur); let start; let end; let search
|
||||||
if (token.end > cur.ch) {
|
if (token.end > cur.ch) {
|
||||||
token.end = cur.ch;
|
token.end = cur.ch
|
||||||
token.string = token.string.slice(0, cur.ch - token.start);
|
token.string = token.string.slice(0, cur.ch - token.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
//start end search 赋值
|
// start end search 赋值
|
||||||
// todo 此处允许字符串包含 .
|
// todo 此处允许字符串包含 .
|
||||||
// if (token.string.match(/^[.`"'\w@][\w$#]*/g)) {
|
// if (token.string.match(/^[.`"'\w@][\w$#]*/g)) {
|
||||||
if (token.string.match(/^[.`"'\w@][\w#]*/g)) {
|
if (token.string.match(/^[.`"'\w@][\w#]*/g)) {
|
||||||
search = token.string;
|
search = token.string
|
||||||
start = token.start;
|
start = token.start
|
||||||
end = token.end;
|
end = token.end
|
||||||
} else {
|
} else {
|
||||||
start = end = cur.ch;
|
start = end = cur.ch
|
||||||
search = "";
|
search = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
//对引用标识符 . 的使用,关联table 列
|
// 对引用标识符 . 的使用,关联table 列
|
||||||
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
|
if (search.charAt(0) == '.' || search.charAt(0) == identifierQuote) {
|
||||||
start = nameCompletion(cur, token, result, editor);
|
start = nameCompletion(cur, token, result, editor)
|
||||||
} else {
|
} else {
|
||||||
var objectOrClass = function (w, className) {
|
const objectOrClass = function (w, className) {
|
||||||
if (typeof w === "object") {
|
if (typeof w === 'object') {
|
||||||
w.className = className;
|
w.className = className
|
||||||
} else {
|
} else {
|
||||||
w = {text: w, className: className};
|
w = { text: w, className: className }
|
||||||
}
|
}
|
||||||
return w;
|
return w
|
||||||
};
|
}
|
||||||
addMatches(result, search, defaultTable, function (w) {
|
addMatches(result, search, defaultTable, function (w) {
|
||||||
return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table");
|
return objectOrClass(w, 'CodeMirror-hint-table CodeMirror-hint-default-table')
|
||||||
});
|
})
|
||||||
addMatches(
|
addMatches(
|
||||||
result,
|
result,
|
||||||
search,
|
search,
|
||||||
tables, function (w) {
|
tables, function (w) {
|
||||||
return objectOrClass(w, "CodeMirror-hint-table");
|
return objectOrClass(w, 'CodeMirror-hint-table')
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (!disableKeywords)
|
if (!disableKeywords) {
|
||||||
addMatches(result, search, keywords, function (w) {
|
addMatches(result, search, keywords, function (w) {
|
||||||
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
|
return objectOrClass(w.toUpperCase(), 'CodeMirror-hint-keyword')
|
||||||
});
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//写入一个 钩子,在这里决定提示的内容
|
// 写入一个 钩子,在这里决定提示的内容
|
||||||
if (hinthook) {
|
if (hinthook) {
|
||||||
var params = {
|
const params = {
|
||||||
search, //搜索 关键字
|
search, // 搜索 关键字
|
||||||
keywords, //关键字列表
|
keywords // 关键字列表
|
||||||
};
|
}
|
||||||
if (token.type === 'operator') {
|
if (token.type === 'operator') {
|
||||||
params.leftpart = getLeftpart(cur, token, result, editor) || ''
|
params.leftpart = getLeftpart(cur, token, result, editor) || ''
|
||||||
}
|
}
|
||||||
@@ -347,8 +340,8 @@ export default function (CodeMirror,
|
|||||||
|
|
||||||
/* 之后的参数 是为manualHinthook 预备的 */
|
/* 之后的参数 是为manualHinthook 预备的 */
|
||||||
|
|
||||||
var manualParams = {
|
const manualParams = {
|
||||||
search, //搜索 关键字
|
search, // 搜索 关键字
|
||||||
// keywords, //关键字列表 没啥用
|
// keywords, //关键字列表 没啥用
|
||||||
from: Pos(cur.line, start),
|
from: Pos(cur.line, start),
|
||||||
to: Pos(cur.line, end),
|
to: Pos(cur.line, end),
|
||||||
@@ -360,13 +353,13 @@ export default function (CodeMirror,
|
|||||||
cur
|
cur
|
||||||
}
|
}
|
||||||
|
|
||||||
var refField = matchMain(CodeMirror, params, manualParams);
|
const refField = matchMain(CodeMirror, params, manualParams)
|
||||||
manualParams.refField = refField
|
manualParams.refField = refField
|
||||||
manualParams.leftpart = refField?.label || manualParams.leftpart;
|
manualParams.leftpart = refField?.label || manualParams.leftpart
|
||||||
params.leftpart = refField?.label || params.leftpart;
|
params.leftpart = refField?.label || params.leftpart
|
||||||
|
|
||||||
result = hinthook(result, params, manualParams) || result
|
result = hinthook(result, params, manualParams) || result
|
||||||
}
|
}
|
||||||
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
|
return { list: result, from: Pos(cur.line, start), to: Pos(cur.line, end) }
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
var renderData = [
|
const renderData = [
|
||||||
{
|
{
|
||||||
name: 'COUNT',
|
name: 'COUNT',
|
||||||
syntax: 'count(expr)',
|
syntax: 'count(expr)',
|
||||||
@@ -34,7 +34,7 @@ var renderData = [
|
|||||||
code: 'count(distinct client_ip)'
|
code: 'count(distinct client_ip)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Counts the number of different "Server IP" and "Server port" :`,
|
purpose: 'Counts the number of different "Server IP" and "Server port" :',
|
||||||
code: 'count(distinct server_ip, server_port)'
|
code: 'count(distinct server_ip, server_port)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -50,11 +50,11 @@ var renderData = [
|
|||||||
description: 'Aggregate function is used to calculate the arithmetic mean in the specified field. EXPR must be Integer,Float or Decimal and returned value as Float.',
|
description: 'Aggregate function is used to calculate the arithmetic mean in the specified field. EXPR must be Integer,Float or Decimal and returned value as Float.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Calculates the average(mean) "Byte sent (sent_bytes)" field:`,
|
purpose: 'Calculates the average(mean) "Byte sent (sent_bytes)" field:',
|
||||||
code: 'avg(sent_bytes)'
|
code: 'avg(sent_bytes)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Calculates the average(mean) "Bytes" , rounded to 2 decimal points:`,
|
purpose: 'Calculates the average(mean) "Bytes" , rounded to 2 decimal points:',
|
||||||
code: 'round(avg(sent_bytes+received_bytes),2)'
|
code: 'round(avg(sent_bytes+received_bytes),2)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -70,11 +70,11 @@ var renderData = [
|
|||||||
description: 'Aggregate function is used to sum of the values of the specified field. EXPR must be Integer,Float or Decimal.',
|
description: 'Aggregate function is used to sum of the values of the specified field. EXPR must be Integer,Float or Decimal.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `The sum of the "Byte sent (sent_bytes)" field:`,
|
purpose: 'The sum of the "Byte sent (sent_bytes)" field:',
|
||||||
code: 'sum(sent_bytes)'
|
code: 'sum(sent_bytes)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `The sum of the "sent_bytes" and "received_bytes" fields , and rename as "Bytes ":`,
|
purpose: 'The sum of the "sent_bytes" and "received_bytes" fields , and rename as "Bytes ":',
|
||||||
code: 'sum(sent_bytes+received_bytes) as Bytes'
|
code: 'sum(sent_bytes+received_bytes) as Bytes'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -89,7 +89,7 @@ var renderData = [
|
|||||||
description: 'Aggregate function is used to return the maximum value of the specified field.',
|
description: 'Aggregate function is used to return the maximum value of the specified field.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Returns the maximum value of the "Byte sent (sent_bytes)" field:`,
|
purpose: 'Returns the maximum value of the "Byte sent (sent_bytes)" field:',
|
||||||
code: 'max(sent_bytes)'
|
code: 'max(sent_bytes)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -105,7 +105,7 @@ var renderData = [
|
|||||||
description: 'Aggregate function is used to return the minimum value of the specified field.',
|
description: 'Aggregate function is used to return the minimum value of the specified field.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Returns the minimum value of the "Byte sent (sent_bytes)" field:`,
|
purpose: 'Returns the minimum value of the "Byte sent (sent_bytes)" field:',
|
||||||
code: 'min(sent_bytes)'
|
code: 'min(sent_bytes)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -121,7 +121,7 @@ var renderData = [
|
|||||||
description: 'Rounds down a timestamp, returning it as a new timestamp,optionally from some reference fill, and fills time gaps and impute missing values.',
|
description: 'Rounds down a timestamp, returning it as a new timestamp,optionally from some reference fill, and fills time gaps and impute missing values.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Round the recv_time down to a 5 minutes increment and fill time gaps and impute zero value.`,
|
purpose: 'Round the recv_time down to a 5 minutes increment and fill time gaps and impute zero value.',
|
||||||
code: 'TIME_FLOOR_WITH_FILL(recv_time,\'PT5M\',\'zero\')'
|
code: 'TIME_FLOOR_WITH_FILL(recv_time,\'PT5M\',\'zero\')'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -148,21 +148,21 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'UNIX_TIMESTAMP',
|
name: 'UNIX_TIMESTAMP',
|
||||||
syntax: `UNIX_TIMESTAMP(date)`,
|
syntax: 'UNIX_TIMESTAMP(date)',
|
||||||
description: `Returns a Unix timestamp the value of the argument as seconds since '1970-01-01 00:00:00' UTC.`,
|
description: 'Returns a Unix timestamp the value of the argument as seconds since \'1970-01-01 00:00:00\' UTC.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Specify a datetime string "2019-06-06 19:11:12", calculate the Unix timestamp:`,
|
purpose: 'Specify a datetime string "2019-06-06 19:11:12", calculate the Unix timestamp:',
|
||||||
code: 'UNIX_TIMESTAMP(\'2019-06-06 19:11:12\')'
|
code: 'UNIX_TIMESTAMP(\'2019-06-06 19:11:12\')'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Specify a ISO8601 datetime string with time zone information "2019-10-12T14:20:50+08:00", calculate the Unix timestamp:`,
|
purpose: 'Specify a ISO8601 datetime string with time zone information "2019-10-12T14:20:50+08:00", calculate the Unix timestamp:',
|
||||||
code: 'UNIX_TIMESTAMP(\'2019-10-12T14:20:50+08:00\')'
|
code: 'UNIX_TIMESTAMP(\'2019-10-12T14:20:50+08:00\')'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Specify a ISO8601 datetime string with UTC+0 time zone information "2019-10-12T14:20:50Z", calculate the Unix timestamp:`,
|
purpose: 'Specify a ISO8601 datetime string with UTC+0 time zone information "2019-10-12T14:20:50Z", calculate the Unix timestamp:',
|
||||||
code: 'UNIX_TIMESTAMP(\'2019-10-12T14:20:50Z\')'
|
code: 'UNIX_TIMESTAMP(\'2019-10-12T14:20:50Z\')'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
details () {
|
details () {
|
||||||
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
||||||
@@ -181,13 +181,13 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'FROM_UNIXTIME',
|
name: 'FROM_UNIXTIME',
|
||||||
syntax: `FROM_UNIXTIME(unix_timestamp)`,
|
syntax: 'FROM_UNIXTIME(unix_timestamp)',
|
||||||
description: `Returns a representation of unix_timestamp as a datetime or character string value. The value returned is expressed using the UTC+0 time zone.`,
|
description: 'Returns a representation of unix_timestamp as a datetime or character string value. The value returned is expressed using the UTC+0 time zone.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Specify a Unix Timestamp "1570881546", calculate the datetime string:`,
|
purpose: 'Specify a Unix Timestamp "1570881546", calculate the datetime string:',
|
||||||
code: 'FROM_UNIXTIME(1570881546)'
|
code: 'FROM_UNIXTIME(1570881546)'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
details () {
|
details () {
|
||||||
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
||||||
@@ -198,10 +198,10 @@ var renderData = [
|
|||||||
{
|
{
|
||||||
name: 'DATE_FORMAT',
|
name: 'DATE_FORMAT',
|
||||||
syntax: 'DATE_FORMAT(date, format)',
|
syntax: 'DATE_FORMAT(date, format)',
|
||||||
description: `Formats the date value according to the format string.`,
|
description: 'Formats the date value according to the format string.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Specify a Unix Timestamp "1570881546", calculate the datetime string with format "%Y-%m-%d %H:%i:%s":`,
|
purpose: 'Specify a Unix Timestamp "1570881546", calculate the datetime string with format "%Y-%m-%d %H:%i:%s":',
|
||||||
code: 'DATE_FORMAT(FROM_UNIXTIME(1570881546), \'%Y-%m-%d %H:%i:%s\')'
|
code: 'DATE_FORMAT(FROM_UNIXTIME(1570881546), \'%Y-%m-%d %H:%i:%s\')'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -233,21 +233,21 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CONVERT_TZ',
|
name: 'CONVERT_TZ',
|
||||||
syntax: `CONVERT_TZ(dt, from_tz, to_tz)`,
|
syntax: 'CONVERT_TZ(dt, from_tz, to_tz)',
|
||||||
description: `Converts a datetime value dt from the time zone given by from_tz to the time zone given by to_tz and returns the resulting value.`,
|
description: 'Converts a datetime value dt from the time zone given by from_tz to the time zone given by to_tz and returns the resulting value.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Specify a datetime string "2021-11-11 00:00:00", converted from GMT(Greenwich Mean Time) to Asia/Shanghai time zone:`,
|
purpose: 'Specify a datetime string "2021-11-11 00:00:00", converted from GMT(Greenwich Mean Time) to Asia/Shanghai time zone:',
|
||||||
code: 'CONVERT_TZ(\'2021-11-11 00:00:00\',\'GMT\',\'Asia/Shanghai\')'
|
code: 'CONVERT_TZ(\'2021-11-11 00:00:00\',\'GMT\',\'Asia/Shanghai\')'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Specify a Unix timestamp "1636588800", converted from GMT(Greenwich Mean Time) to Asia/Shanghai time zone:`,
|
purpose: 'Specify a Unix timestamp "1636588800", converted from GMT(Greenwich Mean Time) to Asia/Shanghai time zone:',
|
||||||
code: 'CONVERT_TZ(FROM_UNIXTIME(1636588800),\'GMT\',\'Asia/Shanghai\')'
|
code: 'CONVERT_TZ(FROM_UNIXTIME(1636588800),\'GMT\',\'Asia/Shanghai\')'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
purpose: `Specify a Unix timestamp "1636588800", converted from Europe/London to America/New_York time zone:`,
|
purpose: 'Specify a Unix timestamp "1636588800", converted from Europe/London to America/New_York time zone:',
|
||||||
code: 'CONVERT_TZ(DATE_FORMAT(FROM_UNIXTIME(1636588800), \'%Y-%m-%d %H:%i:%s\'),\'Europe/London\',\'America/New_York\')'
|
code: 'CONVERT_TZ(DATE_FORMAT(FROM_UNIXTIME(1636588800), \'%Y-%m-%d %H:%i:%s\'),\'Europe/London\',\'America/New_York\')'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
details () {
|
details () {
|
||||||
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
// 支持jsx 嵌套写法,万一测试要关键字加重呢
|
||||||
@@ -263,11 +263,11 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'MEDIAN',
|
name: 'MEDIAN',
|
||||||
syntax: `MEDIAN(<expr>)`,
|
syntax: 'MEDIAN(<expr>)',
|
||||||
description: `Aggregate function is used to calculate median value. expr must be Integer, Float or Decimal.`,
|
description: 'Aggregate function is used to calculate median value. expr must be Integer, Float or Decimal.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Calculates the median "TCP Handshake Latency (tcp_handshake_latency_ms)" field:`,
|
purpose: 'Calculates the median "TCP Handshake Latency (tcp_handshake_latency_ms)" field:',
|
||||||
code: 'MEDIAN(tcp_handshake_latency_ms)'
|
code: 'MEDIAN(tcp_handshake_latency_ms)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -279,11 +279,11 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'QUANTILE',
|
name: 'QUANTILE',
|
||||||
syntax: `QUANTILE(<expr>[, <level>])`,
|
syntax: 'QUANTILE(<expr>[, <level>])',
|
||||||
description: `Aggregate function is used to calculate an approximate quantile of a numeric data sequence.`,
|
description: 'Aggregate function is used to calculate an approximate quantile of a numeric data sequence.',
|
||||||
example: [
|
example: [
|
||||||
{
|
{
|
||||||
purpose: `Calculates the 90th percentile "TCP Handshake Latency (tcp_handshake_latency_ms)" field:`,
|
purpose: 'Calculates the 90th percentile "TCP Handshake Latency (tcp_handshake_latency_ms)" field:',
|
||||||
code: 'QUANTILE(tcp_handshake_latency_ms, 0.9)'
|
code: 'QUANTILE(tcp_handshake_latency_ms, 0.9)'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -300,13 +300,13 @@ var renderData = [
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
function main () {
|
function main () {
|
||||||
var functionTips = {}
|
const functionTips = {}
|
||||||
renderData.forEach((item, index) => {
|
renderData.forEach((item, index) => {
|
||||||
var data = item // 这是个闭包
|
const data = item // 这是个闭包
|
||||||
functionTips[item.name] = {
|
functionTips[item.name] = {
|
||||||
name: item.name,
|
name: item.name,
|
||||||
syntax: item.syntax,
|
syntax: item.syntax,
|
||||||
@@ -327,8 +327,9 @@ function main () {
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
<h3> Details: </h3>
|
<h3> Details: </h3>
|
||||||
{Object.prototype.toString.call(data.details) === '[object Function]' ?
|
{Object.prototype.toString.call(data.details) === '[object Function]'
|
||||||
<renderer renderFun={data.details}></renderer> : <p>{data.details} </p>}
|
? <renderer renderFun={data.details}></renderer>
|
||||||
|
: <p>{data.details} </p>}
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,5 +338,5 @@ function main () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const functionList = renderData
|
export const functionList = renderData
|
||||||
var functionTips = main()
|
const functionTips = main()
|
||||||
export default functionTips
|
export default functionTips
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
var renderData = [
|
const renderData = [
|
||||||
{
|
{
|
||||||
name: 'FROM',
|
name: 'FROM',
|
||||||
syntax: `FROM [db.]table |$log_type`,
|
syntax: 'FROM [db.]table |$log_type',
|
||||||
description: {
|
description: {
|
||||||
title: `The table name of logs. If you type $log_type, the variable value is the current table name of logs.`
|
title: 'The table name of logs. If you type $log_type, the variable value is the current table name of logs.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SELECT',
|
name: 'SELECT',
|
||||||
syntax: `Optional. The selected columns(also known as dimensions and metrics).`,
|
syntax: 'Optional. The selected columns(also known as dimensions and metrics).',
|
||||||
description: {
|
description: {
|
||||||
title: '可选,获取列',
|
title: '可选,获取列',
|
||||||
list: [
|
list: [
|
||||||
`aggregate_function(field) - Aggregate functions, default is count.`,
|
'aggregate_function(field) - Aggregate functions, default is count.',
|
||||||
`as field - Use as to specify a aliases for a field or expression.`
|
'as field - Use as to specify a aliases for a field or expression.'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'GROUP BY',
|
name: 'GROUP BY',
|
||||||
syntax: `GROUP BY <field-list>`,
|
syntax: 'GROUP BY <field-list>',
|
||||||
description: {
|
description: {
|
||||||
title: 'Aggregate data. GROUP BY clause switches the SELECT query into an aggregation mode:',
|
title: 'Aggregate data. GROUP BY clause switches the SELECT query into an aggregation mode:',
|
||||||
list: [
|
list: [
|
||||||
`The list of fields known as "grouping key", while each individual expression be referred to as a "key expression".`,
|
'The list of fields known as "grouping key", while each individual expression be referred to as a "key expression".',
|
||||||
`All the expressions in the SELECT, HAVING and ORDER BY , must be "key expression" or on aggregate functions.`,
|
'All the expressions in the SELECT, HAVING and ORDER BY , must be "key expression" or on aggregate functions.',
|
||||||
`The result of aggregating SELECT query will return unique values of "grouping key" in log type.`
|
'The result of aggregating SELECT query will return unique values of "grouping key" in log type.'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'HAVING',
|
name: 'HAVING',
|
||||||
syntax: `HAVING <expression-list>`,
|
syntax: 'HAVING <expression-list>',
|
||||||
description: {
|
description: {
|
||||||
title: `Optional. HAVING clause filtering the aggregation results retrieved by GROUP BY. It is difference is that WHERE is performed before aggregation, while HAVING is performed after it.
|
title: `Optional. HAVING clause filtering the aggregation results retrieved by GROUP BY. It is difference is that WHERE is performed before aggregation, while HAVING is performed after it.
|
||||||
Note: HAVING can't be performed if GROUP BY is not performed.`
|
Note: HAVING can't be performed if GROUP BY is not performed.`
|
||||||
@@ -39,26 +39,26 @@ var renderData = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'LIMIT',
|
name: 'LIMIT',
|
||||||
syntax: `LIMIT [n, ]m`,
|
syntax: 'LIMIT [n, ]m',
|
||||||
description: {
|
description: {
|
||||||
title: `Select the m rows from the aggregate results after skipping the first n rows. Default is 10 rows.`
|
title: 'Select the m rows from the aggregate results after skipping the first n rows. Default is 10 rows.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ORDER BY',
|
name: 'ORDER BY',
|
||||||
syntax: `ORDER BY <sort-field> [ASC|DESC]`,
|
syntax: 'ORDER BY <sort-field> [ASC|DESC]',
|
||||||
description: {
|
description: {
|
||||||
title: `Sort all of the results by the specified fields.`
|
title: 'Sort all of the results by the specified fields.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'WHERE',
|
name: 'WHERE',
|
||||||
syntax: `where $filter [and <expression-list>]`,
|
syntax: 'where $filter [and <expression-list>]',
|
||||||
description: {
|
description: {
|
||||||
title: `Filter the data.`,
|
title: 'Filter the data.',
|
||||||
list: [
|
list: [
|
||||||
`$filter - Default global filter clause. Include Time period, Vsys ID, and other expressions, etc`,
|
'$filter - Default global filter clause. Include Time period, Vsys ID, and other expressions, etc',
|
||||||
`and <expression-list> - filter clauses`
|
'and <expression-list> - filter clauses'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,9 +66,9 @@ var renderData = [
|
|||||||
export const sqlList = renderData
|
export const sqlList = renderData
|
||||||
|
|
||||||
function main () {
|
function main () {
|
||||||
var sqlTips = {}
|
const sqlTips = {}
|
||||||
renderData.forEach((item, index) => {
|
renderData.forEach((item, index) => {
|
||||||
var data = item // 这是个闭包
|
const data = item // 这是个闭包
|
||||||
sqlTips[item.name] = {
|
sqlTips[item.name] = {
|
||||||
name: item.name,
|
name: item.name,
|
||||||
syntax: item.syntax,
|
syntax: item.syntax,
|
||||||
@@ -93,5 +93,5 @@ function main () {
|
|||||||
return sqlTips
|
return sqlTips
|
||||||
}
|
}
|
||||||
|
|
||||||
var sqlTips = main()
|
const sqlTips = main()
|
||||||
export default sqlTips
|
export default sqlTips
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var renderData = [
|
const renderData = [
|
||||||
{
|
{
|
||||||
name: '$LOG_TYPE',
|
name: '$LOG_TYPE',
|
||||||
description: 'A variable is a symbolic representation of data that enables you to access a value without having to enter it manually wherever you need it. You can use $ to reference variables throughout Advanced Search. ',
|
description: 'A variable is a symbolic representation of data that enables you to access a value without having to enter it manually wherever you need it. You can use $ to reference variables throughout Advanced Search. ',
|
||||||
@@ -34,8 +34,9 @@ function main () {
|
|||||||
<h3> Description: </h3>
|
<h3> Description: </h3>
|
||||||
<p> {data.description}</p>
|
<p> {data.description}</p>
|
||||||
<h3> Details: </h3>
|
<h3> Details: </h3>
|
||||||
{Object.prototype.toString.call(data.details) === '[object Function]' ?
|
{Object.prototype.toString.call(data.details) === '[object Function]'
|
||||||
<renderer renderFun={data.details}></renderer> : <p>{data.details} </p>}
|
? <renderer renderFun={data.details}></renderer>
|
||||||
|
: <p>{data.details} </p>}
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import {dataTemplate, fieldTemplate} from './template'
|
import { dataTemplate, fieldTemplate } from './template'
|
||||||
|
|
||||||
export class DeviceTag {
|
export class DeviceTag {
|
||||||
constructor(context, params) {
|
constructor (context, params) {
|
||||||
//先从缓存获取数据
|
// 先从缓存获取数据
|
||||||
this.queryparams = params
|
this.queryparams = params
|
||||||
this.context = context
|
this.context = context
|
||||||
}
|
}
|
||||||
|
|
||||||
filterQueryData(list) {
|
filterQueryData (list) {
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataFromRemote() {
|
getDataFromRemote () {
|
||||||
//从 远程,也就是请求接口获取数据
|
// 从 远程,也就是请求接口获取数据
|
||||||
return this.context.$get('/deviceTag', this.queryparams).then((res) => {
|
return this.context.$get('/deviceTag', this.queryparams).then((res) => {
|
||||||
this.context.initDataReadyCb && this.context.initDataReadyCb(res.data || null); //组件 请求 文件成功回调
|
this.context.initDataReadyCb && this.context.initDataReadyCb(res.data || null) // 组件 请求 文件成功回调
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
var data = res.data && res.data.list;
|
const data = res.data && res.data.list
|
||||||
return data
|
return data
|
||||||
} else {
|
} else {
|
||||||
// this.context.$message({
|
// this.context.$message({
|
||||||
@@ -31,40 +31,40 @@ export class DeviceTag {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
formatData(data) {
|
formatData (data) {
|
||||||
//格式化 获取的数据
|
// 格式化 获取的数据
|
||||||
const resultData = {
|
const resultData = {
|
||||||
operatesList: [
|
operatesList: [
|
||||||
{
|
{
|
||||||
"name": "AND",
|
name: 'AND',
|
||||||
"function": "A AND B",
|
function: 'A AND B',
|
||||||
type: "abstract",
|
type: 'abstract',
|
||||||
label: "AND"
|
label: 'AND'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filtersList: data ? this.filterQueryData(data.fields || []) : [],
|
filtersList: data ? this.filterQueryData(data.fields || []) : [],
|
||||||
//操作符仓库 用于记录 类型 和 操作符之间的映射关系
|
// 操作符仓库 用于记录 类型 和 操作符之间的映射关系
|
||||||
operatesDic: data ? data.doc.schema_query.references.operator || [] : [],
|
operatesDic: data ? data.doc.schema_query.references.operator || [] : [],
|
||||||
//operator 记录运算符的label 和 value 映射 以及操作符的使用方法
|
// operator 记录运算符的label 和 value 映射 以及操作符的使用方法
|
||||||
operatorManual: data ? data.doc.functions.operator || [] : []
|
operatorManual: data ? data.doc.functions.operator || [] : []
|
||||||
}
|
}
|
||||||
return resultData
|
return resultData
|
||||||
}
|
}
|
||||||
|
|
||||||
organizeData(data=[]) {
|
organizeData (data = []) {
|
||||||
var fields = []
|
const fields = []
|
||||||
var res = JSON.parse(JSON.stringify(dataTemplate));
|
const res = JSON.parse(JSON.stringify(dataTemplate))
|
||||||
if (!data ) {
|
if (!data) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.forEach((item, index) => {
|
data.forEach((item, index) => {
|
||||||
var fieldItem = JSON.parse(JSON.stringify(fieldTemplate));
|
const fieldItem = JSON.parse(JSON.stringify(fieldTemplate))
|
||||||
fieldItem.name = item.tagValue
|
fieldItem.name = item.tagValue
|
||||||
fieldItem.type = "Array"
|
fieldItem.type = 'Array'
|
||||||
fieldItem.label = item.tagName
|
fieldItem.label = item.tagName
|
||||||
fieldItem.doc.data = (item.subTags || []).map(tagItem => {
|
fieldItem.doc.data = (item.subTags || []).map(tagItem => {
|
||||||
return {
|
return {
|
||||||
code: `'${tagItem.tagValue}'`, //匹配SQL 的时候,这个Code 要加 ''
|
code: `'${tagItem.tagValue}'`, // 匹配SQL 的时候,这个Code 要加 ''
|
||||||
value: tagItem.tagName,
|
value: tagItem.tagName,
|
||||||
type: tagItem.tagType
|
type: tagItem.tagType
|
||||||
}
|
}
|
||||||
@@ -75,20 +75,20 @@ export class DeviceTag {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormatedData(callback) {
|
getFormatedData (callback) {
|
||||||
this.getDataFromRemote().then(data => {
|
this.getDataFromRemote().then(data => {
|
||||||
//组织数据 模拟scama
|
// 组织数据 模拟scama
|
||||||
var organizedData = this.organizeData(data);
|
const organizedData = this.organizeData(data)
|
||||||
//格式化数据
|
// 格式化数据
|
||||||
this.data = this.formatData(organizedData)
|
this.data = this.formatData(organizedData)
|
||||||
//获取scameData的时候 查询映射字段
|
// 获取scameData的时候 查询映射字段
|
||||||
callback && callback(this.data)
|
callback && callback(this.data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(){
|
dispose () {
|
||||||
this.context=null
|
this.context = null
|
||||||
this.queryparams=null
|
this.queryparams = null
|
||||||
this.data=null
|
this.data = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,156 +1,156 @@
|
|||||||
export const dataTemplate = {
|
export const dataTemplate = {
|
||||||
"doc": {
|
doc: {
|
||||||
"functions": {
|
functions: {
|
||||||
"aggregation": [
|
aggregation: [
|
||||||
{
|
{
|
||||||
"name": "COUNT",
|
name: 'COUNT',
|
||||||
"function": "count(expr)",
|
function: 'count(expr)',
|
||||||
"label": "COUNT"
|
label: 'COUNT'
|
||||||
}, {
|
}, {
|
||||||
"name": "COUNT_DISTINCT",
|
name: 'COUNT_DISTINCT',
|
||||||
"function": "count(distinct expr)",
|
function: 'count(distinct expr)',
|
||||||
"label": "COUNT_DISTINCT"
|
label: 'COUNT_DISTINCT'
|
||||||
}, {
|
}, {
|
||||||
"name": "AVG",
|
name: 'AVG',
|
||||||
"function": "avg(expr)",
|
function: 'avg(expr)',
|
||||||
"label": "AVG"
|
label: 'AVG'
|
||||||
}, {
|
}, {
|
||||||
"name": "SUM",
|
name: 'SUM',
|
||||||
"function": "sum(expr)",
|
function: 'sum(expr)',
|
||||||
"label": "SUM"
|
label: 'SUM'
|
||||||
}, {
|
}, {
|
||||||
"name": "MAX",
|
name: 'MAX',
|
||||||
"function": "max(expr)",
|
function: 'max(expr)',
|
||||||
"label": "MAX"
|
label: 'MAX'
|
||||||
}, {
|
}, {
|
||||||
"name": "MIN",
|
name: 'MIN',
|
||||||
"function": "min(expr)",
|
function: 'min(expr)',
|
||||||
"label": "MIN"
|
label: 'MIN'
|
||||||
}],
|
}],
|
||||||
"operator": [
|
operator: [
|
||||||
{
|
{
|
||||||
"name": "=",
|
name: '=',
|
||||||
"function": "expr = value",
|
function: 'expr = value',
|
||||||
"label": "="
|
label: '='
|
||||||
}, {
|
}, {
|
||||||
"name": "!=",
|
name: '!=',
|
||||||
"function": "expr != value",
|
function: 'expr != value',
|
||||||
"label": "!="
|
label: '!='
|
||||||
}, {
|
}, {
|
||||||
"name": ">",
|
name: '>',
|
||||||
"function": "expr > value",
|
function: 'expr > value',
|
||||||
"label": ">"
|
label: '>'
|
||||||
}, {
|
}, {
|
||||||
"name": "<",
|
name: '<',
|
||||||
"function": "expr < value",
|
function: 'expr < value',
|
||||||
"label": "<"
|
label: '<'
|
||||||
}, {
|
}, {
|
||||||
"name": ">=",
|
name: '>=',
|
||||||
"function": "expr >= value",
|
function: 'expr >= value',
|
||||||
"label": ">="
|
label: '>='
|
||||||
}, {
|
}, {
|
||||||
"name": "<=",
|
name: '<=',
|
||||||
"function": "expr <= value",
|
function: 'expr <= value',
|
||||||
"label": "<="
|
label: '<='
|
||||||
}, {
|
}, {
|
||||||
"name": "has",
|
name: 'has',
|
||||||
"function": "has(expr, value)",
|
function: 'has(expr, value)',
|
||||||
"label": "HAS"
|
label: 'HAS'
|
||||||
}, {
|
}, {
|
||||||
"name": "in",
|
name: 'in',
|
||||||
"function": "expr in (values)",
|
function: 'expr in (values)',
|
||||||
"label": "IN"
|
label: 'IN'
|
||||||
}, {
|
}, {
|
||||||
"name": "not in",
|
name: 'not in',
|
||||||
"function": "expr not in (values)",
|
function: 'expr not in (values)',
|
||||||
"label": "NOT IN"
|
label: 'NOT IN'
|
||||||
}, {
|
}, {
|
||||||
"name": "like",
|
name: 'like',
|
||||||
"function": "expr like value",
|
function: 'expr like value',
|
||||||
"label": "LIKE"
|
label: 'LIKE'
|
||||||
}, {
|
}, {
|
||||||
"name": "not like",
|
name: 'not like',
|
||||||
"function": "expr not like value",
|
function: 'expr not like value',
|
||||||
"label": "NOT LIKE"
|
label: 'NOT LIKE'
|
||||||
}, {
|
}, {
|
||||||
"name": "notEmpty",
|
name: 'notEmpty',
|
||||||
"function": "notEmpty(expr)",
|
function: 'notEmpty(expr)',
|
||||||
"label": "NOT EMPTY"
|
label: 'NOT EMPTY'
|
||||||
}, {
|
}, {
|
||||||
"name": "empty",
|
name: 'empty',
|
||||||
"function": "empty(expr)",
|
function: 'empty(expr)',
|
||||||
"label": "EMPTY"
|
label: 'EMPTY'
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"schema_query": {
|
schema_query: {
|
||||||
"references": {
|
references: {
|
||||||
"aggregation": [
|
aggregation: [
|
||||||
{
|
{
|
||||||
"type": "int",
|
type: 'int',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
|
||||||
}, {
|
}, {
|
||||||
"type": "long",
|
type: 'long',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
|
||||||
}, {
|
}, {
|
||||||
"type": "float",
|
type: 'float',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
|
||||||
}, {
|
}, {
|
||||||
"type": "double",
|
type: 'double',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
|
||||||
}, {
|
}, {
|
||||||
"type": "string",
|
type: 'string',
|
||||||
"functions": "COUNT,COUNT_DISTINCT"
|
functions: 'COUNT,COUNT_DISTINCT'
|
||||||
}, {
|
}, {
|
||||||
"type": "date",
|
type: 'date',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,MAX,MIN'
|
||||||
}, {
|
}, {
|
||||||
"type": "timestamp",
|
type: 'timestamp',
|
||||||
"functions": "COUNT,COUNT_DISTINCT,MAX,MIN"
|
functions: 'COUNT,COUNT_DISTINCT,MAX,MIN'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"operator": [
|
operator: [
|
||||||
{
|
{
|
||||||
"type": "int",
|
type: 'int',
|
||||||
"functions": "=,!=,>,<,>=,<=,in,not in"
|
functions: '=,!=,>,<,>=,<=,in,not in'
|
||||||
}, {
|
}, {
|
||||||
"type": "long",
|
type: 'long',
|
||||||
"functions": "=,!=,>,<,>=,<=,in,not in"
|
functions: '=,!=,>,<,>=,<=,in,not in'
|
||||||
}, {
|
}, {
|
||||||
"type": "float",
|
type: 'float',
|
||||||
"functions": "=,!=,>,<,>=,<="
|
functions: '=,!=,>,<,>=,<='
|
||||||
}, {
|
}, {
|
||||||
"type": "double",
|
type: 'double',
|
||||||
"functions": "=,!=,>,<,>=,<="
|
functions: '=,!=,>,<,>=,<='
|
||||||
}, {
|
}, {
|
||||||
"type": "string",
|
type: 'string',
|
||||||
"functions": "=,!=,in,not in,like,not like,notEmpty,empty"
|
functions: '=,!=,in,not in,like,not like,notEmpty,empty'
|
||||||
}, {
|
}, {
|
||||||
"type": "date",
|
type: 'date',
|
||||||
"functions": "=,!=,>,<,>=,<="
|
functions: '=,!=,>,<,>=,<='
|
||||||
}, {
|
}, {
|
||||||
"type": "timestamp",
|
type: 'timestamp',
|
||||||
"functions": "=,!=,>,<,>=,<="
|
functions: '=,!=,>,<,>=,<='
|
||||||
}, {
|
}, {
|
||||||
"type": "array",
|
type: 'array',
|
||||||
"functions": "has"
|
functions: 'has'
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fields": []
|
fields: []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fieldTemplate = {
|
export const fieldTemplate = {
|
||||||
"name": "",
|
name: '',
|
||||||
"label": "",
|
label: '',
|
||||||
"doc": {
|
doc: {
|
||||||
"allow_query": "true",
|
allow_query: 'true',
|
||||||
"visibility": null,
|
visibility: null,
|
||||||
"constraints": {
|
constraints: {
|
||||||
"type": "tag",
|
type: 'tag',
|
||||||
"operator_functions": "in,not in"
|
operator_functions: 'in,not in'
|
||||||
},
|
},
|
||||||
"data": []
|
data: []
|
||||||
},
|
},
|
||||||
"type": "Array"
|
type: 'Array'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ import {
|
|||||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useDark, useToggle } from '@vueuse/core'
|
import { useToggle } from '@vueuse/core'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
@@ -336,8 +336,7 @@ export default {
|
|||||||
wholeScreenRouterMapping,
|
wholeScreenRouterMapping,
|
||||||
logo: 'images/logo-header.svg',
|
logo: 'images/logo-header.svg',
|
||||||
ZH,
|
ZH,
|
||||||
EN,
|
EN
|
||||||
// isDark: useDark()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import indexedDBUtils from '@/indexedDB'
|
import indexedDBUtils from '@/indexedDB'
|
||||||
import { storageKey, dbTableColumnCustomizeConfigPre,dbTableColumnCustomizeConfig } from '@/utils/constants'
|
import { storageKey, dbTableColumnCustomizeConfigPre, dbTableColumnCustomizeConfig } from '@/utils/constants'
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
customTableTitle: Array, // 自定义的title
|
customTableTitle: Array, // 自定义的title
|
||||||
@@ -153,7 +153,7 @@ export default {
|
|||||||
this.$emit('update', this.custom)
|
this.$emit('update', this.custom)
|
||||||
const userId = localStorage.getItem(storageKey.userId)
|
const userId = localStorage.getItem(storageKey.userId)
|
||||||
const tableName = dbTableColumnCustomizeConfigPre + '-' + this.tableId
|
const tableName = dbTableColumnCustomizeConfigPre + '-' + this.tableId
|
||||||
/*
|
/*
|
||||||
const defaultConfigInDb = await indexedDBUtils.selectTable(tableName).get({ id: userId })
|
const defaultConfigInDb = await indexedDBUtils.selectTable(tableName).get({ id: userId })
|
||||||
let fullVersion = ''
|
let fullVersion = ''
|
||||||
if (defaultConfigInDb && defaultConfigInDb.version) {
|
if (defaultConfigInDb && defaultConfigInDb.version) {
|
||||||
@@ -168,8 +168,8 @@ export default {
|
|||||||
fullVersion = BASE_CONFIG.version + '.1'
|
fullVersion = BASE_CONFIG.version + '.1'
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
let curTableConfig = dbTableColumnCustomizeConfig.find(item => item.tableName === tableName)
|
const curTableConfig = dbTableColumnCustomizeConfig.find(item => item.tableName === tableName)
|
||||||
if(curTableConfig) {
|
if (curTableConfig) {
|
||||||
await indexedDBUtils.selectTable(tableName).put({
|
await indexedDBUtils.selectTable(tableName).put({
|
||||||
id: userId,
|
id: userId,
|
||||||
version: curTableConfig.version,
|
version: curTableConfig.version,
|
||||||
|
|||||||
@@ -464,222 +464,222 @@ export default {
|
|||||||
axios.get(url, { params: params }).then(response => {
|
axios.get(url, { params: params }).then(response => {
|
||||||
const res = response.data
|
const res = response.data
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.isNoDataForPsiphon3 = res.data.result.length === 0
|
this.isNoDataForPsiphon3 = res.data.result.length === 0
|
||||||
this.showErrorForPsiphon3 = false
|
this.showErrorForPsiphon3 = false
|
||||||
if (!this.isNoDataForPsiphon3) {
|
if (!this.isNoDataForPsiphon3) {
|
||||||
const chartsData = res.data.result.map(item => {
|
const chartsData = res.data.result.map(item => {
|
||||||
return [getMillisecond(item.statTime), item.count]
|
return [getMillisecond(item.statTime), item.count]
|
||||||
})
|
})
|
||||||
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
||||||
this.echartsInit(chartsData)
|
this.echartsInit(chartsData)
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.httpError(res)
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
this.httpError(e)
|
|
||||||
}).finally(() => {
|
|
||||||
this.psiphon3Loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
httpError (e) {
|
|
||||||
this.isNoDataForPsiphon3 = false
|
|
||||||
this.showErrorForPsiphon3 = true
|
|
||||||
this.errorMsgForPsiphon3 = this.errorMsgHandler(e)
|
|
||||||
},
|
|
||||||
handleActiveBar () {
|
|
||||||
if (document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')) {
|
|
||||||
const {
|
|
||||||
offsetLeft,
|
|
||||||
clientWidth,
|
|
||||||
clientLeft
|
|
||||||
} = document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')
|
|
||||||
const activeBar = document.querySelector('.psiphon3-bar .bar-value-active')
|
|
||||||
activeBar.style.cssText += `width: ${clientWidth}px; left: ${offsetLeft + this.leftOffset + clientLeft}px;`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resize () {
|
|
||||||
if (this.myChart) {
|
|
||||||
this.myChart.resize()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dispatchSelectAction (type, name) {
|
|
||||||
this.myChart && this.myChart.dispatchAction({
|
|
||||||
type: type,
|
|
||||||
name: name
|
|
||||||
})
|
|
||||||
},
|
|
||||||
legendSelectChange (item) {
|
|
||||||
this.dispatchSelectAction('legendSelect', item.name)
|
|
||||||
this.tabs.forEach((t) => {
|
|
||||||
if (t.name !== item.name) {
|
|
||||||
this.dispatchSelectAction('legendUnSelect', t.name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
timeChange () {
|
|
||||||
if (this.updateKnowledge.source === 'cn_psiphon3_ip') {
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.handleActiveBar()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
activeChange (item) { // isClick:代表是通过点击操作来的
|
|
||||||
if (item) {
|
|
||||||
this.tabType = item.class
|
|
||||||
}
|
|
||||||
this.legendSelectChange(item)
|
|
||||||
if (this.updateKnowledge.source === 'cn_psiphon3_ip') {
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mouseenterTab (item) {
|
|
||||||
if (this.isNoDataForPsiphon3) return
|
|
||||||
this.mousemoveCursor = item.class
|
|
||||||
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.handleActiveBar()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mouseleaveTab () {
|
|
||||||
this.mousemoveCursor = ''
|
|
||||||
},
|
|
||||||
fileChange (file, fileList) {
|
|
||||||
// 判断后缀,仅支持.csv
|
|
||||||
if (!_.endsWith(file.name, '.csv')) {
|
|
||||||
this.fileList = []
|
|
||||||
this.$message.error(this.$t('validate.fileTypeLimit', { types: this.fileTypeLimit }))
|
|
||||||
} else if (file.size > this.uploadFileSizeLimit) { // 判断文件大小
|
|
||||||
this.$message.error(this.$t('validate.fileSizeLimit', { size: unitConvert(this.uploadFileSizeLimit, unitTypes.byte).join('') }))
|
|
||||||
this.fileList = []
|
|
||||||
} else {
|
|
||||||
this.fileList = fileList.slice(-1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uploadError (error) {
|
|
||||||
let errorMsg
|
|
||||||
if (error.message) {
|
|
||||||
errorMsg = JSON.parse(error.message).message
|
|
||||||
} else {
|
|
||||||
errorMsg = 'error'
|
|
||||||
}
|
|
||||||
this.uploadLoading = false
|
|
||||||
this.$message.error(this.$t('tip.uploadFailed', { msg: errorMsg }))
|
|
||||||
},
|
|
||||||
uploadSuccess (response) {
|
|
||||||
this.uploadLoading = false
|
|
||||||
this.uploaded = true
|
|
||||||
this.$message.success(this.$t('tip.success'))
|
|
||||||
this.showAddUpdateDialog = false
|
|
||||||
this.getCurTabData()
|
|
||||||
},
|
|
||||||
beforeUpload (file) {
|
|
||||||
this.uploadLoading = true
|
|
||||||
this.showConfirmDialog = false
|
|
||||||
},
|
|
||||||
submitConfirm () {
|
|
||||||
this.showConfirmDialog = true
|
|
||||||
},
|
|
||||||
submit () {
|
|
||||||
this.$refs.knowledgeUpload.submit()
|
|
||||||
},
|
|
||||||
cancle () {
|
|
||||||
this.showAddUpdateDialog = false
|
|
||||||
},
|
|
||||||
clickCard (data, event) {
|
|
||||||
if (data.isSelected) { // 原来为选中,当前点击后未选中
|
|
||||||
const index = this.checkList.indexOf(data)
|
|
||||||
if (index > -1) {
|
|
||||||
this.checkList.splice(index, 1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const index = this.checkList.indexOf(data)
|
|
||||||
if (index === -1) {
|
|
||||||
this.checkList.push(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const val = !data.isSelected
|
|
||||||
data.isSelected = val
|
|
||||||
this.$emit('checkboxStatusChange', val, data)
|
|
||||||
},
|
|
||||||
checkboxStatusChange (val, data) {
|
|
||||||
data.isSelected = val
|
|
||||||
this.$emit('checkboxStatusChange', val, data)
|
|
||||||
},
|
|
||||||
beforeClose (done) {
|
|
||||||
if (this.myChart) {
|
|
||||||
this.myChart.dispose()
|
|
||||||
this.myChart = null
|
|
||||||
}
|
|
||||||
done()
|
|
||||||
},
|
|
||||||
handleClose () {
|
|
||||||
this.showUpdateDialog = false
|
|
||||||
this.showAddUpdateDialog = false
|
|
||||||
this.uploadLoading = false
|
|
||||||
},
|
|
||||||
handleConfirmClose () {
|
|
||||||
this.showConfirmDialog = false
|
|
||||||
},
|
|
||||||
handleUpdateClose () {
|
|
||||||
this.showAddUpdateDialog = false
|
|
||||||
},
|
|
||||||
showUpdate () {
|
|
||||||
this.showUpdateDialog = true
|
|
||||||
this.showAddUpdateDialog = false
|
|
||||||
},
|
|
||||||
async jumpToUpdatePage (data, showEnable) {
|
|
||||||
this.updateKnowledge = data
|
|
||||||
this.showEnable = showEnable
|
|
||||||
await this.getCurTabData()
|
|
||||||
if (data.source === 'cn_psiphon3_ip') {
|
|
||||||
await this.init()
|
|
||||||
}
|
|
||||||
this.showUpdate()
|
|
||||||
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.handleActiveBar()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uploadRecord () {
|
|
||||||
this.showAddUpdateDialog = true
|
|
||||||
this.updateObject.name = this.updateKnowledge.name
|
|
||||||
this.updateObject.label = this.$t(this.updateKnowledge.label)
|
|
||||||
this.updateObject.description = ''
|
|
||||||
},
|
|
||||||
getCurTabData () { // showEnable:true 为psiphon3的知识库,false为其它知识库
|
|
||||||
let params = {
|
|
||||||
pageSize: -1
|
|
||||||
}
|
|
||||||
if (this.showEnable) {
|
|
||||||
if (this.activeTab === knowledgeCardUpdateRecordType.updateRecord) {
|
|
||||||
params = {
|
|
||||||
...params,
|
|
||||||
opUser: -1
|
|
||||||
}
|
|
||||||
} else if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
|
||||||
params = {
|
|
||||||
...params,
|
|
||||||
opUser: 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.httpError(res)
|
||||||
}
|
}
|
||||||
this.updateLogLoading = true
|
}).catch(e => {
|
||||||
this.updateHistoryList = []
|
console.error(e)
|
||||||
axios.get(api.knowledgeBaseLog + '/' + this.updateKnowledge.knowledgeId, { params: params }).then(res => {
|
this.httpError(e)
|
||||||
this.updateHistoryList = res.data.data.list
|
}).finally(() => {
|
||||||
if (this.updateHistoryList[0]) {
|
this.psiphon3Loading = false
|
||||||
this.currentVersion = this.updateHistoryList[0].commitVersion + 1
|
})
|
||||||
|
},
|
||||||
|
httpError (e) {
|
||||||
|
this.isNoDataForPsiphon3 = false
|
||||||
|
this.showErrorForPsiphon3 = true
|
||||||
|
this.errorMsgForPsiphon3 = this.errorMsgHandler(e)
|
||||||
|
},
|
||||||
|
handleActiveBar () {
|
||||||
|
if (document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')) {
|
||||||
|
const {
|
||||||
|
offsetLeft,
|
||||||
|
clientWidth,
|
||||||
|
clientLeft
|
||||||
|
} = document.querySelector('.psiphon3-bar .bar-value-tabs.is-active')
|
||||||
|
const activeBar = document.querySelector('.psiphon3-bar .bar-value-active')
|
||||||
|
activeBar.style.cssText += `width: ${clientWidth}px; left: ${offsetLeft + this.leftOffset + clientLeft}px;`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resize () {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.resize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dispatchSelectAction (type, name) {
|
||||||
|
this.myChart && this.myChart.dispatchAction({
|
||||||
|
type: type,
|
||||||
|
name: name
|
||||||
|
})
|
||||||
|
},
|
||||||
|
legendSelectChange (item) {
|
||||||
|
this.dispatchSelectAction('legendSelect', item.name)
|
||||||
|
this.tabs.forEach((t) => {
|
||||||
|
if (t.name !== item.name) {
|
||||||
|
this.dispatchSelectAction('legendUnSelect', t.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
timeChange () {
|
||||||
|
if (this.updateKnowledge.source === 'cn_psiphon3_ip') {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeChange (item) { // isClick:代表是通过点击操作来的
|
||||||
|
if (item) {
|
||||||
|
this.tabType = item.class
|
||||||
|
}
|
||||||
|
this.legendSelectChange(item)
|
||||||
|
if (this.updateKnowledge.source === 'cn_psiphon3_ip') {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseenterTab (item) {
|
||||||
|
if (this.isNoDataForPsiphon3) return
|
||||||
|
this.mousemoveCursor = item.class
|
||||||
|
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseleaveTab () {
|
||||||
|
this.mousemoveCursor = ''
|
||||||
|
},
|
||||||
|
fileChange (file, fileList) {
|
||||||
|
// 判断后缀,仅支持.csv
|
||||||
|
if (!_.endsWith(file.name, '.csv')) {
|
||||||
|
this.fileList = []
|
||||||
|
this.$message.error(this.$t('validate.fileTypeLimit', { types: this.fileTypeLimit }))
|
||||||
|
} else if (file.size > this.uploadFileSizeLimit) { // 判断文件大小
|
||||||
|
this.$message.error(this.$t('validate.fileSizeLimit', { size: unitConvert(this.uploadFileSizeLimit, unitTypes.byte).join('') }))
|
||||||
|
this.fileList = []
|
||||||
|
} else {
|
||||||
|
this.fileList = fileList.slice(-1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadError (error) {
|
||||||
|
let errorMsg
|
||||||
|
if (error.message) {
|
||||||
|
errorMsg = JSON.parse(error.message).message
|
||||||
|
} else {
|
||||||
|
errorMsg = 'error'
|
||||||
|
}
|
||||||
|
this.uploadLoading = false
|
||||||
|
this.$message.error(this.$t('tip.uploadFailed', { msg: errorMsg }))
|
||||||
|
},
|
||||||
|
uploadSuccess (response) {
|
||||||
|
this.uploadLoading = false
|
||||||
|
this.uploaded = true
|
||||||
|
this.$message.success(this.$t('tip.success'))
|
||||||
|
this.showAddUpdateDialog = false
|
||||||
|
this.getCurTabData()
|
||||||
|
},
|
||||||
|
beforeUpload (file) {
|
||||||
|
this.uploadLoading = true
|
||||||
|
this.showConfirmDialog = false
|
||||||
|
},
|
||||||
|
submitConfirm () {
|
||||||
|
this.showConfirmDialog = true
|
||||||
|
},
|
||||||
|
submit () {
|
||||||
|
this.$refs.knowledgeUpload.submit()
|
||||||
|
},
|
||||||
|
cancle () {
|
||||||
|
this.showAddUpdateDialog = false
|
||||||
|
},
|
||||||
|
clickCard (data, event) {
|
||||||
|
if (data.isSelected) { // 原来为选中,当前点击后未选中
|
||||||
|
const index = this.checkList.indexOf(data)
|
||||||
|
if (index > -1) {
|
||||||
|
this.checkList.splice(index, 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const index = this.checkList.indexOf(data)
|
||||||
|
if (index === -1) {
|
||||||
|
this.checkList.push(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const val = !data.isSelected
|
||||||
|
data.isSelected = val
|
||||||
|
this.$emit('checkboxStatusChange', val, data)
|
||||||
|
},
|
||||||
|
checkboxStatusChange (val, data) {
|
||||||
|
data.isSelected = val
|
||||||
|
this.$emit('checkboxStatusChange', val, data)
|
||||||
|
},
|
||||||
|
beforeClose (done) {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.dispose()
|
||||||
|
this.myChart = null
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
},
|
||||||
|
handleClose () {
|
||||||
|
this.showUpdateDialog = false
|
||||||
|
this.showAddUpdateDialog = false
|
||||||
|
this.uploadLoading = false
|
||||||
|
},
|
||||||
|
handleConfirmClose () {
|
||||||
|
this.showConfirmDialog = false
|
||||||
|
},
|
||||||
|
handleUpdateClose () {
|
||||||
|
this.showAddUpdateDialog = false
|
||||||
|
},
|
||||||
|
showUpdate () {
|
||||||
|
this.showUpdateDialog = true
|
||||||
|
this.showAddUpdateDialog = false
|
||||||
|
},
|
||||||
|
async jumpToUpdatePage (data, showEnable) {
|
||||||
|
this.updateKnowledge = data
|
||||||
|
this.showEnable = showEnable
|
||||||
|
await this.getCurTabData()
|
||||||
|
if (data.source === 'cn_psiphon3_ip') {
|
||||||
|
await this.init()
|
||||||
|
}
|
||||||
|
this.showUpdate()
|
||||||
|
if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.handleActiveBar()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadRecord () {
|
||||||
|
this.showAddUpdateDialog = true
|
||||||
|
this.updateObject.name = this.updateKnowledge.name
|
||||||
|
this.updateObject.label = this.$t(this.updateKnowledge.label)
|
||||||
|
this.updateObject.description = ''
|
||||||
|
},
|
||||||
|
getCurTabData () { // showEnable:true 为psiphon3的知识库,false为其它知识库
|
||||||
|
let params = {
|
||||||
|
pageSize: -1
|
||||||
|
}
|
||||||
|
if (this.showEnable) {
|
||||||
|
if (this.activeTab === knowledgeCardUpdateRecordType.updateRecord) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
opUser: -1
|
||||||
}
|
}
|
||||||
/*
|
} else if (this.activeTab === knowledgeCardUpdateRecordType.intelligenceLearning) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
opUser: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateLogLoading = true
|
||||||
|
this.updateHistoryList = []
|
||||||
|
axios.get(api.knowledgeBaseLog + '/' + this.updateKnowledge.knowledgeId, { params: params }).then(res => {
|
||||||
|
this.updateHistoryList = res.data.data.list
|
||||||
|
if (this.updateHistoryList[0]) {
|
||||||
|
this.currentVersion = this.updateHistoryList[0].commitVersion + 1
|
||||||
|
}
|
||||||
|
/*
|
||||||
this.hasUpdatingRecord = false
|
this.hasUpdatingRecord = false
|
||||||
this.updateHistoryList.forEach(item => {
|
this.updateHistoryList.forEach(item => {
|
||||||
if (item.isUpdating) { // if(item.isUpdating){//????????
|
if (item.isUpdating) { // if(item.isUpdating){//????????
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
statusChange (plugin) {
|
statusChange (plugin) {
|
||||||
let triggerStatus = plugin.triggerStatus
|
const triggerStatus = plugin.triggerStatus
|
||||||
let statusUrl = triggerStatus === '1' ? api.pluginStatusEnable : api.pluginStatusDisable
|
let statusUrl = triggerStatus === '1' ? api.pluginStatusEnable : api.pluginStatusDisable
|
||||||
statusUrl = statusUrl.replace('{{id}}', plugin.id)
|
statusUrl = statusUrl.replace('{{id}}', plugin.id)
|
||||||
axios.post(statusUrl).then(response => {
|
axios.post(statusUrl).then(response => {
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
setup () {
|
setup () {
|
||||||
const { query } = useRoute()
|
const { query } = useRoute()
|
||||||
/*// 获取url携带的range、startTime、endTime
|
/* // 获取url携带的range、startTime、endTime
|
||||||
const rangeParam = query.range
|
const rangeParam = query.range
|
||||||
const startTimeParam = query.startTime
|
const startTimeParam = query.startTime
|
||||||
const endTimeParam = query.endTime
|
const endTimeParam = query.endTime
|
||||||
@@ -250,7 +250,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
timeFilter.value.startTime = parseInt(startTimeParam)
|
timeFilter.value.startTime = parseInt(startTimeParam)
|
||||||
timeFilter.value.endTime = parseInt(endTimeParam)
|
timeFilter.value.endTime = parseInt(endTimeParam)
|
||||||
}*/
|
} */
|
||||||
|
|
||||||
const dateRangeValue = DEFAULT_TIME_FILTER_RANGE.tag.activeEntity || 60
|
const dateRangeValue = DEFAULT_TIME_FILTER_RANGE.tag.activeEntity || 60
|
||||||
const timeFilter = ref({ dateRangeValue })
|
const timeFilter = ref({ dateRangeValue })
|
||||||
@@ -472,9 +472,9 @@ export default {
|
|||||||
desc = this.$t('tag.observedEntities2')
|
desc = this.$t('tag.observedEntities2')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if (this.observedCount > 0) {
|
/* if (this.observedCount > 0) {
|
||||||
desc += `, IP ${this.observedIpCount}, ${this.$t('overall.domain2')} ${this.observedDomainCount}`
|
desc += `, IP ${this.observedIpCount}, ${this.$t('overall.domain2')} ${this.observedDomainCount}`
|
||||||
}*/
|
} */
|
||||||
} else {
|
} else {
|
||||||
// 只有单种实体时,单个描述
|
// 只有单种实体时,单个描述
|
||||||
if (this.disableToEntity) {
|
if (this.disableToEntity) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { tableSort } from '@/utils/tools'
|
import { tableSort } from '@/utils/tools'
|
||||||
import { defaultPageSize, fromRoute, position, storageKey, dbTableColumnCustomizeConfigPre,dbTableColumnCustomizeConfig } from '@/utils/constants'
|
import { defaultPageSize, fromRoute, position, storageKey, dbTableColumnCustomizeConfigPre, dbTableColumnCustomizeConfig } from '@/utils/constants'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import pagination from '@/components/common/Pagination'
|
import pagination from '@/components/common/Pagination'
|
||||||
@@ -428,11 +428,11 @@ export default {
|
|||||||
localStorageTableTitle = await indexedDBUtils.selectTable(tableName).get({ id: userId })
|
localStorageTableTitle = await indexedDBUtils.selectTable(tableName).get({ id: userId })
|
||||||
}
|
}
|
||||||
|
|
||||||
let curTableTitles = this.$refs.dataTable && this.$refs.dataTable.tableTitle ? this.$refs.dataTable.tableTitle : []
|
const curTableTitles = this.$refs.dataTable && this.$refs.dataTable.tableTitle ? this.$refs.dataTable.tableTitle : []
|
||||||
let curTableConfig = dbTableColumnCustomizeConfig.find(item => item.tableName === tableName)
|
const curTableConfig = dbTableColumnCustomizeConfig.find(item => item.tableName === tableName)
|
||||||
if(localStorageTableTitle && curTableConfig &&
|
if (localStorageTableTitle && curTableConfig &&
|
||||||
localStorageTableTitle.version !== curTableConfig.version && curTableTitles) {
|
localStorageTableTitle.version !== curTableConfig.version && curTableTitles) {
|
||||||
if(this.$refs.dataList) {
|
if (this.$refs.dataList) {
|
||||||
this.$refs.dataList.updateCustomTableTitle(curTableTitles)
|
this.$refs.dataList.updateCustomTableTitle(curTableTitles)
|
||||||
}
|
}
|
||||||
await indexedDBUtils.selectTable(tableName).put({
|
await indexedDBUtils.selectTable(tableName).put({
|
||||||
|
|||||||
@@ -337,43 +337,43 @@ if (openMock) {
|
|||||||
data: {
|
data: {
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
"subscriberId":111,
|
subscriberId: 111,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 1
|
active: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"subscriberId":444,
|
subscriberId: 444,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 1
|
active: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"subscriberId":555,
|
subscriberId: 555,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 0
|
active: 0
|
||||||
},{
|
}, {
|
||||||
"subscriberId":666,
|
subscriberId: 666,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 1
|
active: 1
|
||||||
},{
|
}, {
|
||||||
"subscriberId":777,
|
subscriberId: 777,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 0
|
active: 0
|
||||||
},{
|
}, {
|
||||||
"subscriberId":888,
|
subscriberId: 888,
|
||||||
"group": "terrorist",
|
group: 'terrorist',
|
||||||
"info": "terrorist leader",
|
info: 'terrorist leader',
|
||||||
"location": "china",
|
location: 'china',
|
||||||
"active": 1
|
active: 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -384,53 +384,53 @@ if (openMock) {
|
|||||||
msg: 'success',
|
msg: 'success',
|
||||||
code: 200,
|
code: 200,
|
||||||
data: {
|
data: {
|
||||||
total:1,
|
total: 1,
|
||||||
pageSize:20,
|
pageSize: 20,
|
||||||
pageNo:1,
|
pageNo: 1,
|
||||||
pages:1,
|
pages: 1,
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
"subscriberId":111,
|
subscriberId: 111,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680302,
|
phone_number: 18601680302,
|
||||||
"follow": 1
|
follow: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"subscriberId":222,
|
subscriberId: 222,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680303,
|
phone_number: 18601680303,
|
||||||
"follow": 0
|
follow: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"subscriberId":333,
|
subscriberId: 333,
|
||||||
"active": 0,
|
active: 0,
|
||||||
"phone_number": 18601680304,
|
phone_number: 18601680304,
|
||||||
"follow": 0
|
follow: 0
|
||||||
},{
|
}, {
|
||||||
"subscriberId":444,
|
subscriberId: 444,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680305,
|
phone_number: 18601680305,
|
||||||
"follow": 1
|
follow: 1
|
||||||
},{
|
}, {
|
||||||
"subscriberId":555,
|
subscriberId: 555,
|
||||||
"active": 0,
|
active: 0,
|
||||||
"phone_number": 18601680306,
|
phone_number: 18601680306,
|
||||||
"follow": 1
|
follow: 1
|
||||||
},{
|
}, {
|
||||||
"subscriberId":666,
|
subscriberId: 666,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680307,
|
phone_number: 18601680307,
|
||||||
"follow": 1
|
follow: 1
|
||||||
},{
|
}, {
|
||||||
"subscriberId":777,
|
subscriberId: 777,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680308,
|
phone_number: 18601680308,
|
||||||
"follow": 1
|
follow: 1
|
||||||
},{
|
}, {
|
||||||
"subscriberId":888,
|
subscriberId: 888,
|
||||||
"active": 1,
|
active: 1,
|
||||||
"phone_number": 18601680300,
|
phone_number: 18601680300,
|
||||||
"follow": 1
|
follow: 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,22 +56,22 @@ export const dbTableColumnCustomizeConfig = [
|
|||||||
{
|
{
|
||||||
version: '24.04.06',
|
version: '24.04.06',
|
||||||
tableName: dbUserTableColumnCustomizeConfig
|
tableName: dbUserTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbRoleTableColumnCustomizeConfig
|
tableName: dbRoleTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbOperationLogTableColumnCustomizeConfig
|
tableName: dbOperationLogTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbChartTableColumnCustomizeConfig
|
tableName: dbChartTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbI18nTableColumnCustomizeConfig
|
tableName: dbI18nTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbReportTableColumnCustomizeConfig
|
tableName: dbReportTableColumnCustomizeConfig
|
||||||
},{
|
}, {
|
||||||
version: '24.04.01',
|
version: '24.04.01',
|
||||||
tableName: dbGalaxySettingTableColumnCustomizeConfig
|
tableName: dbGalaxySettingTableColumnCustomizeConfig
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,34 +2,34 @@ import vue from '@/main.js'
|
|||||||
// import Moment from "moment/moment";
|
// import Moment from "moment/moment";
|
||||||
// import {transformToUTCTime} from './TimeZone.js'
|
// import {transformToUTCTime} from './TimeZone.js'
|
||||||
|
|
||||||
//默认Schema 延时15s ,时间粒度 1s
|
// 默认Schema 延时15s ,时间粒度 1s
|
||||||
const defaultSchema = {
|
const defaultSchema = {
|
||||||
"doc": {
|
doc: {
|
||||||
"measurements": {
|
measurements: {
|
||||||
"granularity": 1,
|
granularity: 1,
|
||||||
"ingestion_delay": 15
|
ingestion_delay: 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let schemaDict=null;
|
let schemaDict = null
|
||||||
function getSchemaFromLocal(schemaType) {
|
function getSchemaFromLocal (schemaType) {
|
||||||
let schemaData=null
|
let schemaData = null
|
||||||
// if(schemaDict?.[schemaType]){
|
// if(schemaDict?.[schemaType]){
|
||||||
// schemaData=schemaDict
|
// schemaData=schemaDict
|
||||||
// }else{
|
// }else{
|
||||||
schemaData = localStorage.getItem('TSGSchema')
|
schemaData = localStorage.getItem('TSGSchema')
|
||||||
// }
|
// }
|
||||||
if (!schemaData) {
|
if (!schemaData) {
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
const storeData = JSON.parse(schemaData)[schemaType];
|
const storeData = JSON.parse(schemaData)[schemaType]
|
||||||
// 如果根据key没有找到数据,直接返回空
|
// 如果根据key没有找到数据,直接返回空
|
||||||
if (!storeData) {
|
if (!storeData) {
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
const parsedData = storeData;
|
const parsedData = storeData
|
||||||
const currentTimestamp = new Date().getTime();
|
const currentTimestamp = new Date().getTime()
|
||||||
|
|
||||||
// 将当前的时间戳和保存在storage中的timestamp进行比较
|
// 将当前的时间戳和保存在storage中的timestamp进行比较
|
||||||
// 如果时间差小于等于过期时间说明没有过期,直接返回数据
|
// 如果时间差小于等于过期时间说明没有过期,直接返回数据
|
||||||
@@ -37,9 +37,9 @@ function getSchemaFromLocal(schemaType) {
|
|||||||
if (currentTimestamp - parsedData.timestamp <= parsedData.expire) {
|
if (currentTimestamp - parsedData.timestamp <= parsedData.expire) {
|
||||||
return parsedData.value ? JSON.parse(parsedData.value) : parsedData.value
|
return parsedData.value ? JSON.parse(parsedData.value) : parsedData.value
|
||||||
} else {
|
} else {
|
||||||
setDashboardSchema(schemaType,'')
|
setDashboardSchema(schemaType, '')
|
||||||
}
|
}
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,37 +48,36 @@ function getSchemaFromLocal(schemaType) {
|
|||||||
* @param {*} value 保存的数据
|
* @param {*} value 保存的数据
|
||||||
* @param {*} expire 过期时间,默认为1分钟
|
* @param {*} expire 过期时间,默认为1分钟
|
||||||
*/
|
*/
|
||||||
function setDashboardSchema(schemaType, value, expire = 60000) {
|
function setDashboardSchema (schemaType, value, expire = 60000) {
|
||||||
let schemaData = localStorage.getItem('TSGSchema');
|
const schemaData = localStorage.getItem('TSGSchema')
|
||||||
if (!schemaData) {
|
if (!schemaData) {
|
||||||
localStorage.setItem('TSGSchema', '{}')
|
localStorage.setItem('TSGSchema', '{}')
|
||||||
}
|
}
|
||||||
let TSGSchema = JSON.parse(localStorage.getItem('TSGSchema'))
|
const TSGSchema = JSON.parse(localStorage.getItem('TSGSchema'))
|
||||||
TSGSchema[schemaType] = {
|
TSGSchema[schemaType] = {
|
||||||
value: value,
|
value: value,
|
||||||
expire: expire,
|
expire: expire,
|
||||||
timestamp: new Date().getTime()
|
timestamp: new Date().getTime()
|
||||||
}
|
}
|
||||||
const stringfiedData = JSON.stringify(TSGSchema);
|
const stringfiedData = JSON.stringify(TSGSchema)
|
||||||
localStorage.setItem('TSGSchema', stringfiedData);
|
localStorage.setItem('TSGSchema', stringfiedData)
|
||||||
schemaDict=TSGSchema;
|
schemaDict = TSGSchema
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取过期时间毫秒数
|
// 获取过期时间毫秒数
|
||||||
function getExpireTime(data){
|
function getExpireTime (data) {
|
||||||
let expireDate=data.expireDate
|
const expireDate = data.expireDate
|
||||||
if(!expireDate){
|
if (!expireDate) {
|
||||||
return 24 * 60 * 60 * 1000
|
return 24 * 60 * 60 * 1000
|
||||||
}
|
}
|
||||||
let expireTime=new Date().getTime()-expireDate
|
const expireTime = new Date().getTime() - expireDate
|
||||||
return expireTime
|
return expireTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSchemaFromRemote (schemaType) {
|
||||||
function getSchemaFromRemote(schemaType) {
|
|
||||||
return vue.$get(`/interface/gateway/api/galaxy/v1/metadata/schema/${schemaType}`).then(res => {
|
return vue.$get(`/interface/gateway/api/galaxy/v1/metadata/schema/${schemaType}`).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
let expireTime=getExpireTime(res.data)
|
const expireTime = getExpireTime(res.data)
|
||||||
setDashboardSchema(schemaType, JSON.stringify(res.data), expireTime)
|
setDashboardSchema(schemaType, JSON.stringify(res.data), expireTime)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
@@ -89,14 +88,13 @@ function getSchemaFromRemote(schemaType) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// async 延时时间
|
// async 延时时间
|
||||||
// 转换时间 start end schmaType 相对时间 绝对时间
|
// 转换时间 start end schmaType 相对时间 绝对时间
|
||||||
// 时间粒度
|
// 时间粒度
|
||||||
|
|
||||||
//获取Schema数据,存在于local 直接取,不存在 直接请求,存本地
|
// 获取Schema数据,存在于local 直接取,不存在 直接请求,存本地
|
||||||
async function getSchemaInfo(schemaType = '') {
|
async function getSchemaInfo (schemaType = '') {
|
||||||
var schemaInfo = getSchemaFromLocal(schemaType)
|
let schemaInfo = getSchemaFromLocal(schemaType)
|
||||||
if (!schemaInfo) {
|
if (!schemaInfo) {
|
||||||
schemaInfo = await getSchemaFromRemote(schemaType)
|
schemaInfo = await getSchemaFromRemote(schemaType)
|
||||||
}
|
}
|
||||||
@@ -110,26 +108,26 @@ async function getSchemaInfo(schemaType = '') {
|
|||||||
*
|
*
|
||||||
* granularity 单位必须是S 秒
|
* granularity 单位必须是S 秒
|
||||||
* */
|
* */
|
||||||
async function getTimeQueryParams({start, end, schemaType = '', granularity = 1, toUtc = false, delay = false}) {
|
async function getTimeQueryParams ({ start, end, schemaType = '', granularity = 1, toUtc = false, delay = false }) {
|
||||||
let schemaData = await getSchemaInfo(schemaType);
|
const schemaData = await getSchemaInfo(schemaType)
|
||||||
|
|
||||||
const schema_ingestion_delay = schemaData?.doc?.measurements?.ingestion_delay || 0;
|
const schema_ingestion_delay = schemaData?.doc?.measurements?.ingestion_delay || 0
|
||||||
const schema_granularity = schemaData?.doc?.measurements?.granularity || 1;
|
const schema_granularity = schemaData?.doc?.measurements?.granularity || 1
|
||||||
|
|
||||||
//这里需要考虑 传入的是UTC 时间,Moment 可以正常处理吗
|
// 这里需要考虑 传入的是UTC 时间,Moment 可以正常处理吗
|
||||||
var delayTime = delay ? schema_ingestion_delay : 0;
|
const delayTime = delay ? schema_ingestion_delay : 0
|
||||||
// let startDate = Moment(start).subtract(delayTime, 'seconds')
|
// let startDate = Moment(start).subtract(delayTime, 'seconds')
|
||||||
// let endDate = Moment(end).subtract(delayTime, 'seconds')
|
// let endDate = Moment(end).subtract(delayTime, 'seconds')
|
||||||
let startDate = '1'
|
const startDate = '1'
|
||||||
let endDate = '2'
|
const endDate = '2'
|
||||||
|
|
||||||
var startStr = startDate.format('YYYY-MM-DD HH:mm:ss')
|
let startStr = startDate.format('YYYY-MM-DD HH:mm:ss')
|
||||||
var endStr = endDate.format('YYYY-MM-DD HH:mm:ss')
|
let endStr = endDate.format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
|
||||||
//前端计算时间粒度,不能比Schema 支持的最小时间粒度 小
|
// 前端计算时间粒度,不能比Schema 支持的最小时间粒度 小
|
||||||
var alignmentPeriod = schema_granularity > granularity ? schema_granularity : granularity
|
const alignmentPeriod = schema_granularity > granularity ? schema_granularity : granularity
|
||||||
|
|
||||||
//UTC 转换
|
// UTC 转换
|
||||||
if (toUtc) {
|
if (toUtc) {
|
||||||
// startStr = transformToUTCTime(startStr)
|
// startStr = transformToUTCTime(startStr)
|
||||||
// endStr = transformToUTCTime(endStr)
|
// endStr = transformToUTCTime(endStr)
|
||||||
@@ -139,8 +137,8 @@ async function getTimeQueryParams({start, end, schemaType = '', granularity = 1,
|
|||||||
return {
|
return {
|
||||||
start: startStr,
|
start: startStr,
|
||||||
end: endStr,
|
end: endStr,
|
||||||
granularity: 'PT'+schema_granularity+'S',
|
granularity: 'PT' + schema_granularity + 'S',
|
||||||
alignmentPeriod: 'PT'+alignmentPeriod+'S',
|
alignmentPeriod: 'PT' + alignmentPeriod + 'S'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,4 +146,4 @@ export default {
|
|||||||
getTimeQueryParams,
|
getTimeQueryParams,
|
||||||
getSchemaInfo
|
getSchemaInfo
|
||||||
}
|
}
|
||||||
export {getSchemaFromLocal, getSchemaInfo, setDashboardSchema, getSchemaFromRemote, getTimeQueryParams};
|
export { getSchemaFromLocal, getSchemaInfo, setDashboardSchema, getSchemaFromRemote, getTimeQueryParams }
|
||||||
|
|||||||
@@ -140,8 +140,8 @@ export function getUnitType (column) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 单位转换,返回转换后的[value, unit],type=time时若value<1ms,返回<1ms,type=percent时若value<0.01%,返回<0.01% */
|
/* 单位转换,返回转换后的[value, unit],type=time时若value<1ms,返回<1ms,type=percent时若value<0.01%,返回<0.01% */
|
||||||
export function valueToRangeValue (value, unitType,sourceUnit, targetUnit, dot) {
|
export function valueToRangeValue (value, unitType, sourceUnit, targetUnit, dot) {
|
||||||
const values = unitConvert(value, unitType,sourceUnit, targetUnit, dot)
|
const values = unitConvert(value, unitType, sourceUnit, targetUnit, dot)
|
||||||
if (values[0] === '-') {
|
if (values[0] === '-') {
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default {
|
|||||||
dateIssued: '',
|
dateIssued: '',
|
||||||
dateExpires: ''
|
dateExpires: ''
|
||||||
},
|
},
|
||||||
loading:false
|
loading: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -167,10 +167,10 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
resize () {
|
resize () {
|
||||||
if(this.myChart) {
|
if (this.myChart) {
|
||||||
this.myChart.resize()
|
this.myChart.resize()
|
||||||
}
|
}
|
||||||
if(this.myChart2) {
|
if (this.myChart2) {
|
||||||
this.myChart2.resize()
|
this.myChart2.resize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -838,7 +838,7 @@ export const tagLineChartOption = {
|
|||||||
// return unitConvert(value, unitTypes.number).join('')
|
// return unitConvert(value, unitTypes.number).join('')
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
minInterval:1
|
minInterval: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
series: []
|
series: []
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export default {
|
|||||||
const initialData = await this.generateInitialData()
|
const initialData = await this.generateInitialData()
|
||||||
this.initialData = _.cloneDeep(initialData) // 初始化数据
|
this.initialData = _.cloneDeep(initialData) // 初始化数据
|
||||||
let hoverNode = null
|
let hoverNode = null
|
||||||
let canvasHeight = document.body.clientHeight - 100
|
const canvasHeight = document.body.clientHeight - 100
|
||||||
this.graph = ForceGraph()(document.getElementById('entityGraph'))
|
this.graph = ForceGraph()(document.getElementById('entityGraph'))
|
||||||
.height(canvasHeight)
|
.height(canvasHeight)
|
||||||
.graphData(initialData)
|
.graphData(initialData)
|
||||||
@@ -113,9 +113,9 @@ export default {
|
|||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
ctx.arc(node.x, node.y, nodeStyle.shadowR, 0, 2 * Math.PI, false)
|
ctx.arc(node.x, node.y, nodeStyle.shadowR, 0, 2 * Math.PI, false)
|
||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.fillStyle = node === this.clickNode || node === hoverNode ?
|
ctx.fillStyle = node === this.clickNode || node === hoverNode
|
||||||
nodeStyle.hoveredShadowColor :
|
? nodeStyle.hoveredShadowColor
|
||||||
nodeStyle.shadowColor
|
: nodeStyle.shadowColor
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
// 内部挖空
|
// 内部挖空
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
@@ -132,7 +132,7 @@ export default {
|
|||||||
ctx.strokeStyle = nodeStyle.borderColor
|
ctx.strokeStyle = nodeStyle.borderColor
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
// 图片
|
// 图片
|
||||||
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight);
|
ctx.drawImage(node.img, node.x - nodeStyle.iconWidth / 2, node.y - nodeStyle.iconHeight / 2, nodeStyle.iconWidth, nodeStyle.iconHeight)
|
||||||
// 文字
|
// 文字
|
||||||
ctx.font = nodeStyle.font
|
ctx.font = nodeStyle.font
|
||||||
const textWidth = ctx.measureText(node.label).width
|
const textWidth = ctx.measureText(node.label).width
|
||||||
@@ -275,7 +275,7 @@ export default {
|
|||||||
ctx.fillStyle = color
|
ctx.fillStyle = color
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.restore() // 恢复之前保存的状态
|
ctx.restore() // 恢复之前保存的状态
|
||||||
/*if (link.source.x !== undefined && link.source.y !== undefined && link.target.x !== undefined && link.target.y !== undefined) {
|
/* if (link.source.x !== undefined && link.source.y !== undefined && link.target.x !== undefined && link.target.y !== undefined) {
|
||||||
const nodeStyle = this.getNodeStyle(link.target.type, link.target.data.entityType)
|
const nodeStyle = this.getNodeStyle(link.target.type, link.target.data.entityType)
|
||||||
|
|
||||||
ctx.lineWidth = 0.5
|
ctx.lineWidth = 0.5
|
||||||
@@ -303,7 +303,7 @@ export default {
|
|||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
}*/
|
} */
|
||||||
})
|
})
|
||||||
.autoPauseRedraw(false) // keep redrawing after engine has stopped如果您有依赖于画布的不断重绘的自定义动态对象,建议关闭此选项。
|
.autoPauseRedraw(false) // keep redrawing after engine has stopped如果您有依赖于画布的不断重绘的自定义动态对象,建议关闭此选项。
|
||||||
.onNodeHover(node => {
|
.onNodeHover(node => {
|
||||||
@@ -332,8 +332,8 @@ export default {
|
|||||||
}
|
}
|
||||||
const toAddNodes = []
|
const toAddNodes = []
|
||||||
const toAddLinks = []
|
const toAddLinks = []
|
||||||
let keyCount = Object.keys(node.data.relatedEntities).length
|
const keyCount = Object.keys(node.data.relatedEntities).length
|
||||||
Object.keys(node.data.relatedEntities).forEach((k,i) => {
|
Object.keys(node.data.relatedEntities).forEach((k, i) => {
|
||||||
if (node.data.relatedEntities[k].total) {
|
if (node.data.relatedEntities[k].total) {
|
||||||
// 若已有同级同类型的listNode,不生成此tempNode
|
// 若已有同级同类型的listNode,不生成此tempNode
|
||||||
const neighbors = node.getNeighbors(this.graph.graphData())
|
const neighbors = node.getNeighbors(this.graph.graphData())
|
||||||
@@ -349,12 +349,12 @@ export default {
|
|||||||
node,
|
node,
|
||||||
this.getIconUrl(k, false, false)
|
this.getIconUrl(k, false, false)
|
||||||
)
|
)
|
||||||
//临时节点的初始固定坐标为其对应的entity节点坐标,展示直线动画
|
// 临时节点的初始固定坐标为其对应的entity节点坐标,展示直线动画
|
||||||
//tempNode.fx = node.x
|
// tempNode.fx = node.x
|
||||||
//tempNode.fy = node.y
|
// tempNode.fy = node.y
|
||||||
let tempNodePoint = this.pointOfRotate({x:node.sourceNode.x,y:node.sourceNode.y},{x:node.x,y:node.y},this.getTempNodeAngle(keyCount,i))//临时节点固定角度,为以entity节点为center,list节点为from,旋转到临时节点的角度
|
const tempNodePoint = this.pointOfRotate({ x: node.sourceNode.x, y: node.sourceNode.y }, { x: node.x, y: node.y }, this.getTempNodeAngle(keyCount, i))// 临时节点固定角度,为以entity节点为center,list节点为from,旋转到临时节点的角度
|
||||||
let finalTempNodePoint = this.pointOfLine({x:node.x,y:node.y},tempNodePoint,this.defaultLinkDistance)//start,end,lineLength
|
const finalTempNodePoint = this.pointOfLine({ x: node.x, y: node.y }, tempNodePoint, this.defaultLinkDistance)// start,end,lineLength
|
||||||
if(tempNodePoint.x && tempNodePoint.y) {
|
if (tempNodePoint.x && tempNodePoint.y) {
|
||||||
tempNode.fx = (node.x + finalTempNodePoint.x) / 2
|
tempNode.fx = (node.x + finalTempNodePoint.x) / 2
|
||||||
tempNode.fy = (node.y + finalTempNodePoint.y) / 2
|
tempNode.fy = (node.y + finalTempNodePoint.y) / 2
|
||||||
}
|
}
|
||||||
@@ -388,18 +388,18 @@ export default {
|
|||||||
// 若已达第六层,则只生成listNode,不再展开entityNode
|
// 若已达第六层,则只生成listNode,不再展开entityNode
|
||||||
const nodes = []
|
const nodes = []
|
||||||
const links = []
|
const links = []
|
||||||
let stackNodes = []
|
const stackNodes = []
|
||||||
const stackLinks = []
|
const stackLinks = []
|
||||||
const sourceNode = node.getSourceNode(this.graph.graphData())
|
const sourceNode = node.getSourceNode(this.graph.graphData())
|
||||||
const k1 = (node.x - sourceNode.x) / linkDistance.normal
|
const k1 = (node.x - sourceNode.x) / linkDistance.normal
|
||||||
const k2 = (node.y - sourceNode.y) / linkDistance.normal
|
const k2 = (node.y - sourceNode.y) / linkDistance.normal
|
||||||
const listNode = new Node(
|
const listNode = new Node(
|
||||||
nodeType.listNode,
|
nodeType.listNode,
|
||||||
`${sourceNode.realId}__${node.data.entityType}-list`,
|
`${sourceNode.realId}__${node.data.entityType}-list`,
|
||||||
{
|
{
|
||||||
entityType: node.data.entityType,
|
entityType: node.data.entityType,
|
||||||
fx: sourceNode.x + k1 * linkDistance.entityToList,
|
fx: sourceNode.x + k1 * linkDistance.entityToList,
|
||||||
fy: sourceNode.y + k2 * linkDistance.entityToList,
|
fy: sourceNode.y + k2 * linkDistance.entityToList
|
||||||
},
|
},
|
||||||
sourceNode,
|
sourceNode,
|
||||||
this.getIconUrl(node.data.entityType, false, false)
|
this.getIconUrl(node.data.entityType, false, false)
|
||||||
@@ -423,7 +423,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const entities = await sourceNode.queryRelatedEntities(listNode.data.entityType)
|
const entities = await sourceNode.queryRelatedEntities(listNode.data.entityType)
|
||||||
sourceNode.data.relatedEntities[listNode.data.entityType].list.push(...entities.list)
|
sourceNode.data.relatedEntities[listNode.data.entityType].list.push(...entities.list)
|
||||||
let curNodes = this.graph.graphData().nodes
|
const curNodes = this.graph.graphData().nodes
|
||||||
entities.list.forEach(entity => {
|
entities.list.forEach(entity => {
|
||||||
const entityNode = new Node(nodeType.entityNode, entity.vertex, {
|
const entityNode = new Node(nodeType.entityNode, entity.vertex, {
|
||||||
entityType: listNode.data.entityType,
|
entityType: listNode.data.entityType,
|
||||||
@@ -432,16 +432,16 @@ export default {
|
|||||||
y: listNode.y + Math.random() * 10 - 5
|
y: listNode.y + Math.random() * 10 - 5
|
||||||
}, listNode, this.getIconUrl(listNode.data.entityType, false, false))
|
}, listNode, this.getIconUrl(listNode.data.entityType, false, false))
|
||||||
nodes.push(entityNode)
|
nodes.push(entityNode)
|
||||||
let link = new Link(listNode, entityNode)
|
const link = new Link(listNode, entityNode)
|
||||||
links.push(link)
|
links.push(link)
|
||||||
if(curNodes.findIndex(node => node.id === entityNode.id) === -1) {//过滤掉已有的节点
|
if (curNodes.findIndex(node => node.id === entityNode.id) === -1) { // 过滤掉已有的节点
|
||||||
stackNodes.push(_.cloneDeep(entityNode))
|
stackNodes.push(_.cloneDeep(entityNode))
|
||||||
}
|
}
|
||||||
stackLinks.push(_.cloneDeep(link))
|
stackLinks.push(_.cloneDeep(link))
|
||||||
})
|
})
|
||||||
this.addItems(nodes, links, false)
|
this.addItems(nodes, links, false)
|
||||||
//由于点击临时节点后增加节点分为了2步,所以需要将2步的所有节点一起缓存
|
// 由于点击临时节点后增加节点分为了2步,所以需要将2步的所有节点一起缓存
|
||||||
this.stackData.undo.push({nodes:stackNodes, links:stackLinks})
|
this.stackData.undo.push({ nodes: stackNodes, links: stackLinks })
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
listNode.fx = null
|
listNode.fx = null
|
||||||
@@ -485,65 +485,65 @@ export default {
|
|||||||
.d3Force('charge', d3.forceManyBody().strength(this.defaultChargeStrength))
|
.d3Force('charge', d3.forceManyBody().strength(this.defaultChargeStrength))
|
||||||
.onNodeDrag((node, translate) => {
|
.onNodeDrag((node, translate) => {
|
||||||
const { nodes, links } = this.graph.graphData()
|
const { nodes, links } = this.graph.graphData()
|
||||||
//拖动entity节点时,如果此entity节点有临时节点,则同时移动临时节点
|
// 拖动entity节点时,如果此entity节点有临时节点,则同时移动临时节点
|
||||||
if(node.type === nodeType.entityNode) {
|
if (node.type === nodeType.entityNode) {
|
||||||
//查询点击entity节点对应的list节点
|
// 查询点击entity节点对应的list节点
|
||||||
let fromX = node.sourceNode.preDragX ? node.sourceNode.preDragX : node.sourceNode.x
|
const fromX = node.sourceNode.preDragX ? node.sourceNode.preDragX : node.sourceNode.x
|
||||||
let fromY = node.sourceNode.preDragY ? node.sourceNode.preDragY : node.sourceNode.y
|
const fromY = node.sourceNode.preDragY ? node.sourceNode.preDragY : node.sourceNode.y
|
||||||
let from = {x:fromX,y:fromY}
|
const from = { x: fromX, y: fromY }
|
||||||
let centerX = node.preDragX ? node.preDragX : node.x
|
const centerX = node.preDragX ? node.preDragX : node.x
|
||||||
let centerY = node.preDragY ? node.preDragY : node.y
|
const centerY = node.preDragY ? node.preDragY : node.y
|
||||||
let center = {x:centerX,y:centerY}
|
const center = { x: centerX, y: centerY }
|
||||||
|
|
||||||
const tempLinks = links.filter(link => link.source.id === node.id && link.type === linkType.temp)
|
const tempLinks = links.filter(link => link.source.id === node.id && link.type === linkType.temp)
|
||||||
tempLinks.forEach(link => {
|
tempLinks.forEach(link => {
|
||||||
const tempNodeGroup = nodes.filter(node => node.id === link.target.id)
|
const tempNodeGroup = nodes.filter(node => node.id === link.target.id)
|
||||||
tempNodeGroup.forEach(tempNode => {
|
tempNodeGroup.forEach(tempNode => {
|
||||||
let toX = tempNode.fx ? tempNode.fx : tempNode.x
|
const toX = tempNode.fx ? tempNode.fx : tempNode.x
|
||||||
let toY = tempNode.fy ? tempNode.fy : tempNode.y
|
const toY = tempNode.fy ? tempNode.fy : tempNode.y
|
||||||
let to = {x:toX,y:toY}
|
const to = { x: toX, y: toY }
|
||||||
if(!tempNode.angle) {//每次拖拽,每个临时节点计算一次角度即可,因为角度不会发生改变
|
if (!tempNode.angle) { // 每次拖拽,每个临时节点计算一次角度即可,因为角度不会发生改变
|
||||||
tempNode.angle = this.angleOfRotate(from,to,center)
|
tempNode.angle = this.angleOfRotate(from, to, center)
|
||||||
}
|
}
|
||||||
|
|
||||||
let toPoint = this.pointOfRotate({x: node.sourceNode.x, y: node.sourceNode.y}, {x:node.x + translate.x ,y:node.y + translate.y}, tempNode.angle)
|
const toPoint = this.pointOfRotate({ x: node.sourceNode.x, y: node.sourceNode.y }, { x: node.x + translate.x, y: node.y + translate.y }, tempNode.angle)
|
||||||
//因为在拖拽的过长中,list节点到entity节点之间的距离是变化的,且我们要求的是,临时节点到entity节点之间的距离不发生变化,所以此处需要再次进行计算转换,得到最终的坐标
|
// 因为在拖拽的过长中,list节点到entity节点之间的距离是变化的,且我们要求的是,临时节点到entity节点之间的距离不发生变化,所以此处需要再次进行计算转换,得到最终的坐标
|
||||||
//已知2个点的坐标,求从起点开始指定长度线段的终点坐标
|
// 已知2个点的坐标,求从起点开始指定长度线段的终点坐标
|
||||||
if(!tempNode.lineLength) {//每次拖拽,每个临时节点计算一次与实体节点的距离即可,因为距离在当前拖拽中不会发生改变
|
if (!tempNode.lineLength) { // 每次拖拽,每个临时节点计算一次与实体节点的距离即可,因为距离在当前拖拽中不会发生改变
|
||||||
tempNode.lineLength = Math.sqrt(Math.pow(node.x - tempNode.fx,2) + Math.pow(node.y - tempNode.fy,2))
|
tempNode.lineLength = Math.sqrt(Math.pow(node.x - tempNode.fx, 2) + Math.pow(node.y - tempNode.fy, 2))
|
||||||
}
|
}
|
||||||
let finalTo = this.pointOfLine({x:node.x + translate.x ,y:node.y + translate.y},toPoint,tempNode.lineLength)
|
const finalTo = this.pointOfLine({ x: node.x + translate.x, y: node.y + translate.y }, toPoint, tempNode.lineLength)
|
||||||
tempNode.fx = finalTo.x
|
tempNode.fx = finalTo.x
|
||||||
tempNode.fy = finalTo.y
|
tempNode.fy = finalTo.y
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//拖动list节点时,如果此list节点对应的entity节点有临时节点,则同时移动临时节点
|
// 拖动list节点时,如果此list节点对应的entity节点有临时节点,则同时移动临时节点
|
||||||
if(node.type === nodeType.listNode) {
|
if (node.type === nodeType.listNode) {
|
||||||
//根据list节点,找到list节点连接的线
|
// 根据list节点,找到list节点连接的线
|
||||||
const listLinks = links.filter(link => link.source.id === node.id)
|
const listLinks = links.filter(link => link.source.id === node.id)
|
||||||
let fromX = node.preDragX ? node.preDragX : node.x
|
const fromX = node.preDragX ? node.preDragX : node.x
|
||||||
let fromY = node.preDragY ? node.preDragY : node.y
|
const fromY = node.preDragY ? node.preDragY : node.y
|
||||||
listLinks.forEach(link => {
|
listLinks.forEach(link => {
|
||||||
//找到连接临时节点的虚线
|
// 找到连接临时节点的虚线
|
||||||
const tempLinks = links.filter(entityLink => entityLink.source.id === link.target.id && entityLink.type === linkType.temp)
|
const tempLinks = links.filter(entityLink => entityLink.source.id === link.target.id && entityLink.type === linkType.temp)
|
||||||
if(tempLinks && tempLinks.length > 0) {
|
if (tempLinks && tempLinks.length > 0) {
|
||||||
tempLinks.forEach(tempLink => {
|
tempLinks.forEach(tempLink => {
|
||||||
//找到entity节点
|
// 找到entity节点
|
||||||
const entityNode = nodes.find(normalNode => normalNode.id === tempLink.source.id && normalNode.type === nodeType.entityNode)
|
const entityNode = nodes.find(normalNode => normalNode.id === tempLink.source.id && normalNode.type === nodeType.entityNode)
|
||||||
if(entityNode) {
|
if (entityNode) {
|
||||||
let entityNodeX = entityNode.fx ? entityNode.fx : entityNode.x
|
const entityNodeX = entityNode.fx ? entityNode.fx : entityNode.x
|
||||||
let entityNodeY = entityNode.fy ? entityNode.fy : entityNode.y
|
const entityNodeY = entityNode.fy ? entityNode.fy : entityNode.y
|
||||||
let angle = this.angleOfRotate({x:fromX,y:fromY},{x:node.x + translate.x,y:node.y + translate.y},{x:entityNodeX,y:entityNodeY})
|
const angle = this.angleOfRotate({ x: fromX, y: fromY }, { x: node.x + translate.x, y: node.y + translate.y }, { x: entityNodeX, y: entityNodeY })
|
||||||
const tempNodes = nodes.filter(normalNode => normalNode.id === tempLink.target.id && normalNode.type === nodeType.tempNode)//找到临时节点
|
const tempNodes = nodes.filter(normalNode => normalNode.id === tempLink.target.id && normalNode.type === nodeType.tempNode)// 找到临时节点
|
||||||
tempNodes.forEach(tempNode => {
|
tempNodes.forEach(tempNode => {
|
||||||
let tempNodeX = tempNode.fx ? tempNode.fx : tempNode.x
|
const tempNodeX = tempNode.fx ? tempNode.fx : tempNode.x
|
||||||
let tempNodeY = tempNode.fy ? tempNode.fy : tempNode.y
|
const tempNodeY = tempNode.fy ? tempNode.fy : tempNode.y
|
||||||
let sourceNodeX = tempLink.source.fx ? tempLink.source.fx : tempLink.source.x
|
const sourceNodeX = tempLink.source.fx ? tempLink.source.fx : tempLink.source.x
|
||||||
let sourceNodeY = tempLink.source.fy ? tempLink.source.fy : tempLink.source.y
|
const sourceNodeY = tempLink.source.fy ? tempLink.source.fy : tempLink.source.y
|
||||||
//rotate为list节点旋转的角度,根据旋转角度,及临时节点的位置,及entity节点的坐标,得到临时节点旋转后的坐标
|
// rotate为list节点旋转的角度,根据旋转角度,及临时节点的位置,及entity节点的坐标,得到临时节点旋转后的坐标
|
||||||
let to = this.pointOfRotate({x:tempNodeX, y:tempNodeY}, {x:sourceNodeX,y:sourceNodeY}, angle)
|
const to = this.pointOfRotate({ x: tempNodeX, y: tempNodeY }, { x: sourceNodeX, y: sourceNodeY }, angle)
|
||||||
tempNode.fx = to.x
|
tempNode.fx = to.x
|
||||||
tempNode.fy = to.y
|
tempNode.fy = to.y
|
||||||
})
|
})
|
||||||
@@ -552,33 +552,33 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//记录上次拖拽时节点的坐标,否则计算时出现误差。
|
// 记录上次拖拽时节点的坐标,否则计算时出现误差。
|
||||||
node.preDragX = node.x + translate.x
|
node.preDragX = node.x + translate.x
|
||||||
node.preDragY = node.y + translate.y
|
node.preDragY = node.y + translate.y
|
||||||
})
|
})
|
||||||
.cooldownTime(2000)//到时间后,才执行onEngineStop
|
.cooldownTime(2000)// 到时间后,才执行onEngineStop
|
||||||
.onNodeDragEnd((node, translate) => { // 修复拖动节点
|
.onNodeDragEnd((node, translate) => { // 修复拖动节点
|
||||||
node.fx = node.x
|
node.fx = node.x
|
||||||
node.fy = node.y
|
node.fy = node.y
|
||||||
//拖拽结束时,把所有临时节点的的angle置为null,便于拖动其它节点时的计算
|
// 拖拽结束时,把所有临时节点的的angle置为null,便于拖动其它节点时的计算
|
||||||
this.graph.graphData().nodes.forEach(node => {
|
this.graph.graphData().nodes.forEach(node => {
|
||||||
if(node.type === nodeType.tempNode) {
|
if (node.type === nodeType.tempNode) {
|
||||||
node.angle = null
|
node.angle = null
|
||||||
node.lineLength = null
|
node.lineLength = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.onEngineTick(() => {
|
.onEngineTick(() => {
|
||||||
if(this.isClicking) {
|
if (this.isClicking) {
|
||||||
const tempNodeGroup = this.graph.graphData().nodes.filter(node => node.type === nodeType.tempNode)
|
const tempNodeGroup = this.graph.graphData().nodes.filter(node => node.type === nodeType.tempNode)
|
||||||
if(tempNodeGroup.length > 0) {
|
if (tempNodeGroup.length > 0) {
|
||||||
let keyCount = tempNodeGroup.length
|
const keyCount = tempNodeGroup.length
|
||||||
tempNodeGroup.forEach((tempNode,i) => {
|
tempNodeGroup.forEach((tempNode, i) => {
|
||||||
let tempNodeSource = tempNode.sourceNode
|
const tempNodeSource = tempNode.sourceNode
|
||||||
if(tempNodeSource) {
|
if (tempNodeSource) {
|
||||||
let tempNodePoint = this.pointOfRotate({x:tempNodeSource.sourceNode.x,y:tempNodeSource.sourceNode.y},{x:tempNodeSource.x,y:tempNodeSource.y},this.getTempNodeAngle(keyCount,i))//临时节点固定角度,为以entity节点为center,list节点为from,旋转到临时节点的角度
|
const tempNodePoint = this.pointOfRotate({ x: tempNodeSource.sourceNode.x, y: tempNodeSource.sourceNode.y }, { x: tempNodeSource.x, y: tempNodeSource.y }, this.getTempNodeAngle(keyCount, i))// 临时节点固定角度,为以entity节点为center,list节点为from,旋转到临时节点的角度
|
||||||
let finalTempNodePoint = this.pointOfLine({x:tempNodeSource.x,y:tempNodeSource.y},tempNodePoint,this.defaultLinkDistance)//start,end,lineLength
|
const finalTempNodePoint = this.pointOfLine({ x: tempNodeSource.x, y: tempNodeSource.y }, tempNodePoint, this.defaultLinkDistance)// start,end,lineLength
|
||||||
if(tempNodePoint.x && tempNodePoint.y) {
|
if (tempNodePoint.x && tempNodePoint.y) {
|
||||||
tempNode.fx = finalTempNodePoint.x
|
tempNode.fx = finalTempNodePoint.x
|
||||||
tempNode.fy = finalTempNodePoint.y
|
tempNode.fy = finalTempNodePoint.y
|
||||||
}
|
}
|
||||||
@@ -595,31 +595,31 @@ export default {
|
|||||||
this.rightBox.loading = false
|
this.rightBox.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTempNodeAngle(nodeCount,i) {
|
getTempNodeAngle (nodeCount, i) {
|
||||||
switch (nodeCount) {
|
switch (nodeCount) {
|
||||||
case 1:
|
case 1:
|
||||||
return 180
|
return 180
|
||||||
case 2:
|
case 2:
|
||||||
return 150 + i*60
|
return 150 + i * 60
|
||||||
case 3:
|
case 3:
|
||||||
return 150 + i*30
|
return 150 + i * 30
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//根据3个点坐标,计算节点旋转的角度
|
// 根据3个点坐标,计算节点旋转的角度
|
||||||
angleOfRotate(from, to, center) {
|
angleOfRotate (from, to, center) {
|
||||||
let ab = {}
|
const ab = {}
|
||||||
let ac = {}
|
const ac = {}
|
||||||
ab.x = from.x - center.x
|
ab.x = from.x - center.x
|
||||||
ab.y = from.y - center.y
|
ab.y = from.y - center.y
|
||||||
ac.x = to.x - center.x
|
ac.x = to.x - center.x
|
||||||
ac.y = to.y - center.y
|
ac.y = to.y - center.y
|
||||||
let direct = (ab.x * ac.y) - (ab.y * ac.x)//求节点是顺时针还是逆时针旋转
|
const direct = (ab.x * ac.y) - (ab.y * ac.x)// 求节点是顺时针还是逆时针旋转
|
||||||
let lengthAb = Math.sqrt(Math.pow(center.x - from.x,2) + Math.pow(center.y - from.y,2)),
|
const lengthAb = Math.sqrt(Math.pow(center.x - from.x, 2) + Math.pow(center.y - from.y, 2))
|
||||||
lengthAc = Math.sqrt(Math.pow(center.x - to.x,2) + Math.pow(center.y - to.y,2)),
|
const lengthAc = Math.sqrt(Math.pow(center.x - to.x, 2) + Math.pow(center.y - to.y, 2))
|
||||||
lengthBc = Math.sqrt(Math.pow(from.x - to.x,2) + Math.pow(from.y - to.y,2))
|
const lengthBc = Math.sqrt(Math.pow(from.x - to.x, 2) + Math.pow(from.y - to.y, 2))
|
||||||
let cosA = (Math.pow(lengthAb,2) + Math.pow(lengthAc,2) - Math.pow(lengthBc,2)) / (2 * lengthAb * lengthAc)//余弦定理求出旋转角
|
const cosA = (Math.pow(lengthAb, 2) + Math.pow(lengthAc, 2) - Math.pow(lengthBc, 2)) / (2 * lengthAb * lengthAc)// 余弦定理求出旋转角
|
||||||
let angleA = Math.acos(cosA) * 180 / Math.PI
|
let angleA = Math.acos(cosA) * 180 / Math.PI
|
||||||
if(direct < 0) {//负数表示逆时针旋转,正数表示顺时针旋转
|
if (direct < 0) { // 负数表示逆时针旋转,正数表示顺时针旋转
|
||||||
angleA = -angleA
|
angleA = -angleA
|
||||||
}
|
}
|
||||||
return angleA
|
return angleA
|
||||||
@@ -628,46 +628,46 @@ export default {
|
|||||||
// center: 圆心点;
|
// center: 圆心点;
|
||||||
// angle: 旋转角度° -- [angle * M_PI / 180]:将角度换算为弧度
|
// angle: 旋转角度° -- [angle * M_PI / 180]:将角度换算为弧度
|
||||||
// 【注意】angle 逆时针为正,顺时针为负
|
// 【注意】angle 逆时针为正,顺时针为负
|
||||||
pointOfRotate(from,center,angle){
|
pointOfRotate (from, center, angle) {
|
||||||
var a = center.x
|
const a = center.x
|
||||||
var b = center.y
|
const b = center.y
|
||||||
var x0 = from.x
|
const x0 = from.x
|
||||||
var y0 = from.y
|
const y0 = from.y
|
||||||
var rx = a + (x0-a) * Math.cos(angle * Math.PI / 180) - (y0-b) * Math.sin(angle * Math.PI / 180)
|
const rx = a + (x0 - a) * Math.cos(angle * Math.PI / 180) - (y0 - b) * Math.sin(angle * Math.PI / 180)
|
||||||
var ry = b + (x0-a) * Math.sin(angle * Math.PI / 180) + (y0-b) * Math.cos(angle * Math.PI / 180)
|
const ry = b + (x0 - a) * Math.sin(angle * Math.PI / 180) + (y0 - b) * Math.cos(angle * Math.PI / 180)
|
||||||
if(rx && ry) {
|
if (rx && ry) {
|
||||||
return {x:rx,y:ry}
|
return { x: rx, y: ry }
|
||||||
} else {
|
} else {
|
||||||
return from
|
return from
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//已知2个点的坐标,求从起点开始指定长度线段的终点坐标
|
// 已知2个点的坐标,求从起点开始指定长度线段的终点坐标
|
||||||
pointOfLine(start, end, lineLength) {
|
pointOfLine (start, end, lineLength) {
|
||||||
// 计算总距离
|
// 计算总距离
|
||||||
let totalDistance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))
|
const totalDistance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))
|
||||||
let cosA = (end.x - start.x)/totalDistance
|
const cosA = (end.x - start.x) / totalDistance
|
||||||
let sinA = (end.y - start.y) / totalDistance
|
const sinA = (end.y - start.y) / totalDistance
|
||||||
let finalX = start.x + cosA * lineLength
|
const finalX = start.x + cosA * lineLength
|
||||||
let finalY = start.y + sinA * lineLength
|
const finalY = start.y + sinA * lineLength
|
||||||
|
|
||||||
return {x:finalX, y:finalY}
|
return { x: finalX, y: finalY }
|
||||||
},
|
},
|
||||||
handleToolsbarClick (code) {
|
handleToolsbarClick (code) {
|
||||||
if (code === 'undo') {//上一步
|
if (code === 'undo') { // 上一步
|
||||||
const data = this.stackData.undo.pop()
|
const data = this.stackData.undo.pop()
|
||||||
this.stackData.justUndo = true
|
this.stackData.justUndo = true
|
||||||
if(data) {
|
if (data) {
|
||||||
const { nodes, links } = this.graph.graphData()
|
const { nodes, links } = this.graph.graphData()
|
||||||
data.nodes.forEach(popNode => {
|
data.nodes.forEach(popNode => {
|
||||||
const popNodeIndex = nodes.findIndex(item => item.id === popNode.id)
|
const popNodeIndex = nodes.findIndex(item => item.id === popNode.id)
|
||||||
if (popNodeIndex > -1) {
|
if (popNodeIndex > -1) {
|
||||||
nodes.splice(popNodeIndex,1)
|
nodes.splice(popNodeIndex, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
data.links.forEach(link => {
|
data.links.forEach(link => {
|
||||||
const linksIndex = links.findIndex(item => item.source.id === link.source && item.target.id === link.target)
|
const linksIndex = links.findIndex(item => item.source.id === link.source && item.target.id === link.target)
|
||||||
if (linksIndex > -1) {
|
if (linksIndex > -1) {
|
||||||
links.splice(linksIndex,1)
|
links.splice(linksIndex, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.cleanTempItems()
|
this.cleanTempItems()
|
||||||
@@ -677,9 +677,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.onCloseBlock()
|
this.onCloseBlock()
|
||||||
}
|
}
|
||||||
} else if (code === 'redo') {//下一步
|
} else if (code === 'redo') { // 下一步
|
||||||
const data = this.stackData.redo.pop()
|
const data = this.stackData.redo.pop()
|
||||||
if(data) {
|
if (data) {
|
||||||
this.stackData.justRedo = true
|
this.stackData.justRedo = true
|
||||||
this.addItems(data.nodes, data.links)
|
this.addItems(data.nodes, data.links)
|
||||||
this.cleanTempItems()
|
this.cleanTempItems()
|
||||||
@@ -689,7 +689,7 @@ export default {
|
|||||||
this.onCloseBlock()
|
this.onCloseBlock()
|
||||||
}
|
}
|
||||||
} else if (code === 'autoZoom') {
|
} else if (code === 'autoZoom') {
|
||||||
this.graph.zoomToFit(100,100)
|
this.graph.zoomToFit(100, 100)
|
||||||
} else if (code === 'zoomOut') {
|
} else if (code === 'zoomOut') {
|
||||||
this.graph.zoom(this.graph.zoom() + 0.2)
|
this.graph.zoom(this.graph.zoom() + 0.2)
|
||||||
} else if (code === 'zoomIn') {
|
} else if (code === 'zoomIn') {
|
||||||
@@ -930,7 +930,7 @@ export default {
|
|||||||
y: cy + cy - sy + Math.random() * 30 - 15
|
y: cy + cy - sy + Math.random() * 30 - 15
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addItems (toAddNodes, toAddLinks,stack = true) {
|
addItems (toAddNodes, toAddLinks, stack = true) {
|
||||||
if (toAddNodes.length || toAddLinks.length) {
|
if (toAddNodes.length || toAddLinks.length) {
|
||||||
const { nodes, links } = this.graph.graphData()
|
const { nodes, links } = this.graph.graphData()
|
||||||
const nodes2 = toAddNodes.filter(n => !nodes.some(n2 => n.id === n2.id))
|
const nodes2 = toAddNodes.filter(n => !nodes.some(n2 => n.id === n2.id))
|
||||||
@@ -938,8 +938,8 @@ export default {
|
|||||||
links.push(...toAddLinks)
|
links.push(...toAddLinks)
|
||||||
this.graph.graphData({ nodes, links })
|
this.graph.graphData({ nodes, links })
|
||||||
|
|
||||||
if(stack) {
|
if (stack) {
|
||||||
this.stackData.undo.push(_.cloneDeep({nodes:nodes2, links:toAddLinks}))
|
this.stackData.undo.push(_.cloneDeep({ nodes: nodes2, links: toAddLinks }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -950,20 +950,20 @@ export default {
|
|||||||
if (newNodes.length !== nodes.length || newLinks.length !== links.length) {
|
if (newNodes.length !== nodes.length || newLinks.length !== links.length) {
|
||||||
this.graph.graphData({ nodes: newNodes, links: newLinks })
|
this.graph.graphData({ nodes: newNodes, links: newLinks })
|
||||||
}
|
}
|
||||||
//清理临时节点时,同时释放临时节点对应的entity节点,不再固定位置
|
// 清理临时节点时,同时释放临时节点对应的entity节点,不再固定位置
|
||||||
const tempNodes = nodes.filter(n => n.type === nodeType.tempNode)
|
const tempNodes = nodes.filter(n => n.type === nodeType.tempNode)
|
||||||
tempNodes.forEach(n => {
|
tempNodes.forEach(n => {
|
||||||
if(n.sourceNode) {
|
if (n.sourceNode) {
|
||||||
n.sourceNode.fx = null
|
n.sourceNode.fx = null
|
||||||
n.sourceNode.fy = null
|
n.sourceNode.fy = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//点击节点的时候,把所有list节点的的preDragX和preDragY置为null,便于拖动其它节点时的计算
|
// 点击节点的时候,把所有list节点的的preDragX和preDragY置为null,便于拖动其它节点时的计算
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
//if(node.type === nodeType.listNode) {
|
// if(node.type === nodeType.listNode) {
|
||||||
node.preDragX = null
|
node.preDragX = null
|
||||||
node.preDragY = null
|
node.preDragY = null
|
||||||
//}
|
// }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async generateInitialData (clickNode) {
|
async generateInitialData (clickNode) {
|
||||||
@@ -1033,7 +1033,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (sourceNode.data.relatedEntities[expandType].list.length < 50) {
|
if (sourceNode.data.relatedEntities[expandType].list.length < 50) {
|
||||||
//this.rightBox.loading = true
|
// this.rightBox.loading = true
|
||||||
try {
|
try {
|
||||||
const entities = await sourceNode.queryRelatedEntities(expandType)
|
const entities = await sourceNode.queryRelatedEntities(expandType)
|
||||||
sourceNode.data.relatedEntities[expandType].list.push(...entities.list)
|
sourceNode.data.relatedEntities[expandType].list.push(...entities.list)
|
||||||
@@ -1072,7 +1072,7 @@ export default {
|
|||||||
const toAddNodes = []
|
const toAddNodes = []
|
||||||
const toAddLinks = []
|
const toAddLinks = []
|
||||||
|
|
||||||
//this.rightBox.loading = true
|
// this.rightBox.loading = true
|
||||||
try {
|
try {
|
||||||
const entities = await node.queryRelatedEntities(expandType)
|
const entities = await node.queryRelatedEntities(expandType)
|
||||||
node.data.relatedEntities[expandType].list.push(...entities.list)
|
node.data.relatedEntities[expandType].list.push(...entities.list)
|
||||||
|
|||||||
@@ -1228,11 +1228,11 @@ export default {
|
|||||||
async scrollList (e) {
|
async scrollList (e) {
|
||||||
if (!this.isChecked) {
|
if (!this.isChecked) {
|
||||||
const obj = document.getElementById('locationMap-subscriber-scroll')
|
const obj = document.getElementById('locationMap-subscriber-scroll')
|
||||||
let scrollTop = obj.scrollTop
|
const scrollTop = obj.scrollTop
|
||||||
let scroll = scrollTop - this.preScrollTop;
|
const scroll = scrollTop - this.preScrollTop
|
||||||
this.preScrollTop = scrollTop;
|
this.preScrollTop = scrollTop
|
||||||
//向下滚动才进行加载数据
|
// 向下滚动才进行加载数据
|
||||||
if(scroll >= 0 && (obj.scrollHeight - obj.scrollTop - obj.clientHeight <= 10) &&
|
if (scroll >= 0 && (obj.scrollHeight - obj.scrollTop - obj.clientHeight <= 10) &&
|
||||||
(obj.scrollHeight - obj.scrollTop - obj.clientHeight > 1) &&
|
(obj.scrollHeight - obj.scrollTop - obj.clientHeight > 1) &&
|
||||||
obj.scrollHeight !== 0 &&
|
obj.scrollHeight !== 0 &&
|
||||||
!this.loading.subscriberLoading) {
|
!this.loading.subscriberLoading) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export const pieOption = {
|
export const pieOption = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
appendToBody: true//解决提示框被遮挡的问题
|
appendToBody: true// 解决提示框被遮挡的问题
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|||||||
@@ -1173,11 +1173,11 @@ export default {
|
|||||||
this.editTagErrorTip = ''
|
this.editTagErrorTip = ''
|
||||||
this.showImportedData[index].isValid = 1
|
this.showImportedData[index].isValid = 1
|
||||||
this.showImportedData[index].msg = this.$t('overall.success')
|
this.showImportedData[index].msg = this.$t('overall.success')
|
||||||
/*if (this.hasErrorImportedData()) {
|
/* if (this.hasErrorImportedData()) {
|
||||||
this.previewErrorTip = this.$t('validate.pleaseCheckForErrorItem')
|
this.previewErrorTip = this.$t('validate.pleaseCheckForErrorItem')
|
||||||
} else {
|
} else {
|
||||||
this.previewErrorTip = ''
|
this.previewErrorTip = ''
|
||||||
}*/
|
} */
|
||||||
} else {
|
} else {
|
||||||
this.showImportedData[index].isValid = 0
|
this.showImportedData[index].isValid = 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user