fix: 执行lint,调整书写格式

This commit is contained in:
chenjinsong
2024-06-27 10:19:28 +08:00
parent 6df4e871cd
commit fc2115e883
31 changed files with 4285 additions and 4314 deletions

View File

@@ -12,11 +12,13 @@ export default function createHint (hitType = 'default', CodeMirror, {
keyboardDown,
keyboardEnter
}) {
hitType === 'default' ? showHint(CodeMirror) : manualShowHint(CodeMirror, {
cb: callback,
keyboardUp,
keyboardDown,
keyboardEnter
})
hitType === 'default'
? showHint(CodeMirror)
: manualShowHint(CodeMirror, {
cb: callback,
keyboardUp,
keyboardDown,
keyboardEnter
})
sqlHint(CodeMirror, { dataset, hinthook, keywordshook })
}

View File

@@ -1,25 +1,25 @@
export default function (CodeMirror,{
export default function (CodeMirror, {
cb,
keyboardUp,
keyboardDown,
keyboardEnter
}) {
var HINT_ELEMENT_CLASS = 'CodeMirror-hint'
var ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
const HINT_ELEMENT_CLASS = 'CodeMirror-hint'
const ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
// This is the old interface, kept around for now to stay
// backwards-compatible.
CodeMirror.showHint = function (cm, getHints, options) {
if (!getHints) return cm.showHint(options)
if (options && options.async) getHints.async = true
var newOpts = { hint: getHints }
if (options) for (var prop in options) newOpts[prop] = options[prop]
const newOpts = { hint: getHints }
if (options) for (const prop in options) newOpts[prop] = options[prop]
return cm.showHint(newOpts)
}
CodeMirror.defineExtension('showHint', function (options) {
options = parseOptions(this, this.getCursor('start'), options)
var selections = this.listSelections()
const selections = this.listSelections()
if (selections.length > 1) return
// By default, don't allow completion when something is selected.
// A hint function can have a `supportsSelection` property to
@@ -27,7 +27,7 @@ export default function (CodeMirror,{
if (this.somethingSelected()) {
if (!options.hint.supportsSelection) return
// 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
}
}
@@ -55,17 +55,17 @@ export default function (CodeMirror,{
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length
if (this.options.updateOnCursorActivity) {
var self = this
const self = this
cm.on('cursorActivity', this.activityFunc = function () {
self.cursorActivity()
})
}
}
var requestAnimationFrame = window.requestAnimationFrame || function (fn) {
const requestAnimationFrame = window.requestAnimationFrame || function (fn) {
return setTimeout(fn, 1000 / 60)
}
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
const cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
Completion.prototype = {
close: function () {
@@ -116,7 +116,7 @@ export default function (CodeMirror,{
this.debounce = 0
}
var identStart = this.startPos
let identStart = this.startPos
if (this.data) {
identStart = this.data.from
}
@@ -127,7 +127,7 @@ export default function (CodeMirror,{
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close()
} else {
var self = this
const self = this
this.debounce = requestAnimationFrame(function () {
self.update()
})
@@ -137,7 +137,7 @@ export default function (CodeMirror,{
update: function (first) {
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) {
if (self.tick == myTick) self.finishUpdate(data, first)
})
@@ -189,7 +189,7 @@ export default function (CodeMirror,{
}
function buildKeyMap (completion, handle) {
var baseMap = {
const baseMap = {
Up: function () {
handle.moveFocus(-1)
},
@@ -215,7 +215,7 @@ export default function (CodeMirror,{
Esc: handle.close
}
var mac = /Mac/.test(navigator.platform)
const mac = /Mac/.test(navigator.platform)
if (mac) {
baseMap['Ctrl-P'] = function () {
@@ -226,11 +226,11 @@ export default function (CodeMirror,{
}
}
var custom = completion.options.customKeys
var ourMap = custom ? {} : baseMap
const custom = completion.options.customKeys
const ourMap = custom ? {} : baseMap
function addBinding (key, val) {
var bound
let bound
if (typeof val != 'string') {
bound = function (cm) {
return val(cm, handle)
@@ -251,7 +251,7 @@ export default function (CodeMirror,{
}
}
}
var extra = completion.options.extraKeys
const extra = completion.options.extraKeys
if (extra) {
for (var key in extra) {
if (extra.hasOwnProperty(key)) {
@@ -274,25 +274,25 @@ export default function (CodeMirror,{
this.completion = completion
this.data = data
this.picked = false
var widget = this, cm = completion.cm
var ownerDocument = cm.getInputField().ownerDocument
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
const widget = this; const cm = completion.cm
const ownerDocument = cm.getInputField().ownerDocument
const parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
var hints = this.hints = ownerDocument.createElement('ul')
const hints = this.hints = ownerDocument.createElement('ul')
// $(hints).append(`
// <h1>lalallalla</h1>
// `)
hints.setAttribute('role', 'listbox')
hints.setAttribute('aria-expanded', 'true')
hints.id = this.id
var theme = completion.cm.options.theme
const theme = completion.cm.options.theme
hints.className = 'CodeMirror-hints ' + theme
this.selectedHint = data.selectedHint || 0
var completions = data.list
for (var i = 0; i < completions.length; ++i) {
var elt = hints.appendChild(ownerDocument.createElement('li')), cur = completions[i]
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
const completions = data.list
for (let i = 0; i < completions.length; ++i) {
const elt = hints.appendChild(ownerDocument.createElement('li')); const cur = completions[i]
let className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
if (cur.className != null) className = cur.className + ' ' + className
elt.className = className
if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true')
@@ -306,16 +306,16 @@ export default function (CodeMirror,{
elt.hintId = i
}
var container = completion.options.container || ownerDocument.body
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
var left = pos.left, top = pos.bottom, below = true
var offsetLeft = 0, offsetTop = 0
const container = completion.options.container || ownerDocument.body
let pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
let left = pos.left; let top = pos.bottom; let below = true
let offsetLeft = 0; let offsetTop = 0
if (container !== ownerDocument.body) {
// 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
var offsetParent = isContainerPositioned ? container : container.offsetParent
var offsetParentPosition = offsetParent.getBoundingClientRect()
var bodyPosition = ownerDocument.body.getBoundingClientRect()
const isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1
const offsetParent = isContainerPositioned ? container : container.offsetParent
const offsetParentPosition = offsetParent.getBoundingClientRect()
const bodyPosition = ownerDocument.body.getBoundingClientRect()
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft)
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop)
}
@@ -325,10 +325,10 @@ export default function (CodeMirror,{
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.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
const winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
const winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
//不用默认的DOM 下拉提示
// 不用默认的DOM 下拉提示
// container.appendChild(hints);
hints.remove()
@@ -336,25 +336,25 @@ export default function (CodeMirror,{
cm.getInputField().setAttribute('aria-owns', this.id)
cm.getInputField().setAttribute('aria-activedescendant', this.id + '-' + this.selectedHint)
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
let box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
const scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
// Compute in the timeout to avoid reflow on init
var startScroll
let startScroll
setTimeout(function () {
startScroll = cm.getScrollInfo()
})
var overlapY = box.bottom - winH
const overlapY = box.bottom - winH
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
hints.style.top = (top = pos.top - height - offsetTop) + 'px'
below = false
} else if (height > winH) {
hints.style.height = (winH - 5) + '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) {
pos = cm.cursorCoords(cursor)
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 (overlapX > 0) {
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'
}
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'
}
}
@@ -400,7 +400,7 @@ export default function (CodeMirror,{
}))
if (completion.options.closeOnUnfocus) {
var closingOnBlur
let closingOnBlur
cm.on('blur', this.onBlur = function () {
closingOnBlur = setTimeout(function () {
completion.close()
@@ -412,10 +412,10 @@ export default function (CodeMirror,{
}
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()
var newTop = top + startScroll.top - curScroll.top
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
const newTop = top + startScroll.top - curScroll.top
let point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
if (!below) point += hints.offsetHeight
if (point <= editor.top || point >= editor.bottom) return completion.close()
hints.style.top = newTop + 'px'
@@ -423,7 +423,7 @@ export default function (CodeMirror,{
})
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) {
widget.changeActive(t.hintId)
widget.pick()
@@ -431,7 +431,7 @@ export default function (CodeMirror,{
})
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) {
widget.changeActive(t.hintId)
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
var selectedHintRange = this.getSelectedHintRange()
const selectedHintRange = this.getSelectedHintRange()
if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
this.scrollToActive()
}
@@ -460,11 +460,11 @@ export default function (CodeMirror,{
this.completion.widget = null
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints)
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-owns')
var cm = this.completion.cm
const cm = this.completion.cm
if (this.completion.options.closeOnUnfocus) {
cm.off('blur', this.onBlur)
cm.off('focus', this.onFocus)
@@ -474,7 +474,7 @@ export default function (CodeMirror,{
disable: function () {
this.completion.cm.removeKeyMap(this.keyMap)
var widget = this
const widget = this
this.keyMap = {
Enter: function () {
widget.picked = true
@@ -494,7 +494,7 @@ export default function (CodeMirror,{
i = avoidWrap ? 0 : this.data.list.length - 1
}
if (this.selectedHint == i) return
var node = this.hints.childNodes[this.selectedHint]
let node = this.hints.childNodes[this.selectedHint]
if (node) {
node.className = node.className.replace(' ' + ACTIVE_HINT_ELEMENT_CLASS, '')
node.removeAttribute('aria-selected')
@@ -508,10 +508,10 @@ export default function (CodeMirror,{
},
scrollToActive: function () {
var selectedHintRange = this.getSelectedHintRange()
var node1 = this.hints.childNodes[selectedHintRange.from]
var node2 = this.hints.childNodes[selectedHintRange.to]
var firstNode = this.hints.firstChild
const selectedHintRange = this.getSelectedHintRange()
const node1 = this.hints.childNodes[selectedHintRange.from]
const node2 = this.hints.childNodes[selectedHintRange.to]
const firstNode = this.hints.firstChild
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) {
@@ -524,18 +524,18 @@ export default function (CodeMirror,{
},
getSelectedHintRange: function () {
var margin = this.completion.options.scrollMargin || 0
const margin = this.completion.options.scrollMargin || 0
return {
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) {
if (!cm.somethingSelected()) return helpers
var result = []
for (var i = 0; i < helpers.length; i++) {
const result = []
for (let i = 0; i < helpers.length; i++) {
if (helpers[i].supportsSelection) result.push(helpers[i])
}
return result
@@ -545,7 +545,7 @@ export default function (CodeMirror,{
if (hint.async) {
hint(cm, callback, options)
} else {
var result = hint(cm, options)
const result = hint(cm, options)
if (result && result.then) {
result.then(callback)
} else {
@@ -555,10 +555,10 @@ export default function (CodeMirror,{
}
function resolveAutoHints (cm, pos) {
var helpers = cm.getHelpers(pos, 'hint'), words
const helpers = cm.getHelpers(pos, 'hint'); let words
if (helpers.length) {
var resolved = function (cm, callback, options) {
var app = applicableHelpers(cm, helpers)
const resolved = function (cm, callback, options) {
const app = applicableHelpers(cm, helpers)
function run (i) {
if (i == app.length) return callback(null)
@@ -595,17 +595,17 @@ export default function (CodeMirror,{
})
CodeMirror.registerHelper('hint', 'fromList', function (cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
const cur = cm.getCursor(); const token = cm.getTokenAt(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))) {
term = token.string.substr(0, cur.ch - token.start)
} else {
term = ''
from = cur
}
var found = []
for (var i = 0; i < options.words.length; i++) {
var word = options.words[i]
const found = []
for (let i = 0; i < options.words.length; i++) {
const word = options.words[i]
if (word.slice(0, term.length) == term) {
found.push(word)
}
@@ -620,7 +620,7 @@ export default function (CodeMirror,{
}
})
CodeMirror.commands.autocomplete = CodeMirror.showHint;
CodeMirror.commands.autocomplete = CodeMirror.showHint
var defaultOptions = {
hint: CodeMirror.hint.auto,
@@ -629,7 +629,7 @@ export default function (CodeMirror,{
closeCharacters: /[\s()\[\]{};:>,]/,
closeOnPick: false,
closeOnUnfocus: false, //阻止提示信息 失焦关闭
closeOnUnfocus: false, // 阻止提示信息 失焦关闭
// closeOnUnfocus: false,
updateOnCursorActivity: true,
@@ -638,8 +638,7 @@ export default function (CodeMirror,{
customKeys: null,
extraKeys: null,
paddingForScrollbar: true,
moveOnOverlap: true,
};
CodeMirror.defineOption("hintOptions", null);
moveOnOverlap: true
}
CodeMirror.defineOption('hintOptions', null)
}

View File

@@ -1,222 +1,216 @@
//正则 向前去找关键字
// 正则 向前去找关键字
/* 用于匹配关系数据 */
function matchOperator(CodeMirror, hintParams = {}) {
var editor = hintParams.editor;
var Pos = CodeMirror.Pos
var cur = hintParams.cur;
var token = hintParams.token;
function matchOperator (CodeMirror, hintParams = {}) {
const editor = hintParams.editor
const Pos = CodeMirror.Pos
const cur = hintParams.cur
let token = hintParams.token
if (!editor) {
return
}
var start = token.start;
var cont = true;
var leftTokenGroup = [];
let start = token.start
let cont = true
const leftTokenGroup = []
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(token.string.match(/^[ ]*$/) || start === 0); //只用空格做终止条件
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
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
var reg = /^(.*?)(=|!=|>|<|>=|<=)([^ ]*?)$/;
// 判断是不是满足 运算符 表达式的正则
// test 如果是ig 会改变正则指针: https://my.oschina.net/jamesview/blog/5460753
const reg = /^(.*?)(=|!=|>|<|>=|<=)([^ ]*?)$/
if (reg.test(cursorLeftString)) {
var execArr = reg.exec(cursorLeftString) || []
const execArr = reg.exec(cursorLeftString) || []
return {
leftTokenGroup,
cursorLeftString,
label: execArr[1],
sign: execArr[2],
value: execArr[3],
value: execArr[3]
}
}
return null
}
function matchCommon(CodeMirror, hintParams = {}) {
//通用情况 QUANTILE(expr,level) 左括号右侧第一个就是 关键字
var editor = hintParams.editor;
var Pos = CodeMirror.Pos
var cur = hintParams.cur;
var token = hintParams.token;
function matchCommon (CodeMirror, hintParams = {}) {
// 通用情况 QUANTILE(expr,level) 左括号右侧第一个就是 关键字
const editor = hintParams.editor
const Pos = CodeMirror.Pos
const cur = hintParams.cur
let token = hintParams.token
if (!editor) {
return
}
var start = token.start;
var cont = true;
var leftTokenGroup = [];
let start = token.start
let cont = true
const leftTokenGroup = []
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(token.string.match(/^[ (]*$/) || start === 0); //括号或者空格为终止条件
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
cont = !(token.string.match(/^[ (]*$/) || start === 0) // 括号或者空格为终止条件
//括号补上
// 括号补上
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)) {
var execArr = reg.exec(cursorLeftString) || []
const execArr = reg.exec(cursorLeftString) || []
return {
leftTokenGroup,
cursorLeftString,
label: execArr[1],
sign: 'unknown', //没必要判断
value: execArr[2],
sign: 'unknown', // 没必要判断
value: execArr[2]
}
}
return null
}
function matchIn(CodeMirror, hintParams = {}) {
//in 的情况比较特殊
//通用情况 expr not in (values) expr in (values)
var editor = hintParams.editor;
var Pos = CodeMirror.Pos
var cur = hintParams.cur;
var token = hintParams.token;
function matchIn (CodeMirror, hintParams = {}) {
// in 的情况比较特殊
// 通用情况 expr not in (values) expr in (values)
const editor = hintParams.editor
const Pos = CodeMirror.Pos
const cur = hintParams.cur
let token = hintParams.token
if (!editor) {
return
}
let start = token.start
let cont = true
const leftTokenGroup = []
var start = token.start;
var cont = true;
var leftTokenGroup = [];
//找到左括号
// 找到左括号
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(token.string.match(/^[ (]*$/) || start === 0); //括号或者空格为终止条件
//左括号补上
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
cont = !(token.string.match(/^[ (]*$/) || start === 0) // 括号或者空格为终止条件
// 左括号补上
if (token.string === '(') {
leftTokenGroup.unshift(token);
leftTokenGroup.unshift(token)
}
}
//左括号继续向右找
// 左括号继续向右找
cont = true
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(!token.string.match(/^(in|not| )/g) || start === 0); //括号或者空格为终止条件
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
cont = !(!token.string.match(/^(in|not| )/g) || start === 0) // 括号或者空格为终止条件
//string-2
// 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)) {
var execArr = reg.exec(cursorLeftString) || []
const execArr = reg.exec(cursorLeftString) || []
return {
leftTokenGroup,
cursorLeftString,
label: execArr[1],
sign: execArr[2],
value: execArr[3],
value: execArr[3]
}
}
return null
}
function matchLike(CodeMirror, hintParams = {}) {
//like 的情况比较特殊 expr like value , expr not like value
var editor = hintParams.editor;
var Pos = CodeMirror.Pos
var cur = hintParams.cur;
var token = hintParams.token;
function matchLike (CodeMirror, hintParams = {}) {
// like 的情况比较特殊 expr like value , expr not like value
const editor = hintParams.editor
const Pos = CodeMirror.Pos
const cur = hintParams.cur
let token = hintParams.token
if (!editor) {
return
}
let start = token.start
let cont = true
const leftTokenGroup = []
var start = token.start;
var cont = true;
var leftTokenGroup = [];
//找到左括号
// 找到左括号
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(token.string.match(/^[ ]*$/) || start === 0); //括号或者空格为终止条件
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
cont = !(token.string.match(/^[ ]*$/) || start === 0) // 括号或者空格为终止条件
}
//左括号继续向右找
// 左括号继续向右找
cont = true
while (cont) {
start = token.start;
leftTokenGroup.unshift(token);
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = !(!token.string.match(/^(like|not| )/g) || start === 0); //括号或者空格为终止条件
start = token.start
leftTokenGroup.unshift(token)
token = editor.getTokenAt(Pos(cur.line, token.start))
cont = !(!token.string.match(/^(like|not| )/g) || start === 0) // 括号或者空格为终止条件
//string-2
// 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)) {
var execArr = reg.exec(cursorLeftString) || []
const execArr = reg.exec(cursorLeftString) || []
return {
leftTokenGroup,
cursorLeftString,
label: execArr[1],
sign: execArr[2],
value: execArr[3],
value: execArr[3]
}
}
return null
}
export const matchMain = (CodeMirror, params, manualParams = {}) => {
var matchRes = null
//匹配 运算符表达式
let matchRes = null
// 匹配 运算符表达式
matchRes = matchOperator(CodeMirror, manualParams)
if (matchRes) {
return matchRes
}
//匹配 in表达式
// 匹配 in表达式
matchRes = matchIn(CodeMirror, manualParams)
if (matchRes) {
return matchRes
}
//匹配 like表达式
// 匹配 like表达式
matchRes = matchLike(CodeMirror, manualParams)
if (matchRes) {
return matchRes
}
//这里缺少一个对 count(distinct expr) 模式的匹配, 感觉大数据涉及存在缺陷, 先暂时不写
// 这里缺少一个对 count(distinct expr) 模式的匹配, 感觉大数据涉及存在缺陷, 先暂时不写
//匹配 其他表达式 (expr,value1,value2....) 模式的匹配
// 匹配 其他表达式 (expr,value1,value2....) 模式的匹配
matchRes = matchCommon(CodeMirror, manualParams)
if (matchRes) {
// 说明这是一个 运算符表达式

View File

@@ -1,525 +1,521 @@
export default function showHint(CodeMirror) {
"use strict";
export default function showHint (CodeMirror) {
'use strict'
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
const HINT_ELEMENT_CLASS = 'CodeMirror-hint'
const ACTIVE_HINT_ELEMENT_CLASS = 'CodeMirror-hint-active'
// This is the old interface, kept around for now to stay
// backwards-compatible.
CodeMirror.showHint = function (cm, getHints, options) {
if (!getHints) return cm.showHint(options);
if (options && options.async) getHints.async = true;
var newOpts = {hint: getHints};
if (options) for (var prop in options) newOpts[prop] = options[prop];
return cm.showHint(newOpts);
};
if (!getHints) return cm.showHint(options)
if (options && options.async) getHints.async = true
const newOpts = { hint: getHints }
if (options) for (const prop in options) newOpts[prop] = options[prop]
return cm.showHint(newOpts)
}
CodeMirror.defineExtension("showHint", function (options) {
options = parseOptions(this, this.getCursor("start"), options);
var selections = this.listSelections()
if (selections.length > 1) return;
CodeMirror.defineExtension('showHint', function (options) {
options = parseOptions(this, this.getCursor('start'), options)
const selections = this.listSelections()
if (selections.length > 1) return
// By default, don't allow completion when something is selected.
// A hint function can have a `supportsSelection` property to
// indicate that it can handle selections.
if (this.somethingSelected()) {
if (!options.hint.supportsSelection) return;
if (!options.hint.supportsSelection) return
// Don't try with cross-line selections
for (var i = 0; i < selections.length; i++)
if (selections[i].head.line != selections[i].anchor.line) return;
for (let i = 0; i < selections.length; i++) { if (selections[i].head.line != selections[i].anchor.line) return }
}
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
if (!completion.options.hint) return;
if (this.state.completionActive) this.state.completionActive.close()
const completion = this.state.completionActive = new Completion(this, options)
if (!completion.options.hint) return
CodeMirror.signal(this, "startCompletion", this);
completion.update(true);
});
CodeMirror.signal(this, 'startCompletion', this)
completion.update(true)
})
CodeMirror.defineExtension("closeHint", function () {
CodeMirror.defineExtension('closeHint', function () {
if (this.state.completionActive) this.state.completionActive.close()
})
function Completion(cm, options) {
this.cm = cm;
this.options = options;
this.widget = null;
this.debounce = 0;
this.tick = 0;
this.startPos = this.cm.getCursor("start");
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
function Completion (cm, options) {
this.cm = cm
this.options = options
this.widget = null
this.debounce = 0
this.tick = 0
this.startPos = this.cm.getCursor('start')
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length
if (this.options.updateOnCursorActivity) {
var self = this;
cm.on("cursorActivity", this.activityFunc = function () {
self.cursorActivity();
});
const self = this
cm.on('cursorActivity', this.activityFunc = function () {
self.cursorActivity()
})
}
}
var requestAnimationFrame = window.requestAnimationFrame || function (fn) {
return setTimeout(fn, 1000 / 60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
const requestAnimationFrame = window.requestAnimationFrame || function (fn) {
return setTimeout(fn, 1000 / 60)
}
const cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout
Completion.prototype = {
close: function () {
if (!this.active()) return;
this.cm.state.completionActive = null;
this.tick = null;
if (!this.active()) return
this.cm.state.completionActive = null
this.tick = null
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.widget.close();
CodeMirror.signal(this.cm, "endCompletion", this.cm);
if (this.widget && this.data) CodeMirror.signal(this.data, 'close')
if (this.widget) this.widget.close()
CodeMirror.signal(this.cm, 'endCompletion', this.cm)
},
active: function () {
return this.cm.state.completionActive == this;
return this.cm.state.completionActive == this
},
pick: function (data, i) {
var completion = data.list[i], self = this;
const completion = data.list[i]; const self = this
this.cm.operation(function () {
if (completion.hint)
completion.hint(self.cm, data, completion);
else
if (completion.hint) { completion.hint(self.cm, data, completion) } else {
self.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion);
self.cm.scrollIntoView();
});
completion.to || data.to, 'complete')
}
CodeMirror.signal(data, 'pick', completion)
self.cm.scrollIntoView()
})
if (this.options.closeOnPick) {
this.close();
this.close()
}
},
cursorActivity: function () {
if (this.debounce) {
cancelAnimationFrame(this.debounce);
this.debounce = 0;
cancelAnimationFrame(this.debounce)
this.debounce = 0
}
var identStart = this.startPos;
let identStart = this.startPos
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 ||
pos.ch < identStart.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
this.close()
} else {
var self = this;
const self = this
this.debounce = requestAnimationFrame(function () {
self.update();
});
if (this.widget) this.widget.disable();
self.update()
})
if (this.widget) this.widget.disable()
}
},
update: function (first) {
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) {
if (self.tick == myTick) self.finishUpdate(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);
if (this.widget) this.widget.close();
const picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle)
if (this.widget) this.widget.close()
this.data = data;
this.data = data
if (data && data.list.length) {
if (picked && data.list.length == 1) {
this.pick(data, 0);
this.pick(data, 0)
} else {
this.widget = new Widget(this, data);
CodeMirror.signal(data, "shown");
this.widget = new Widget(this, data)
CodeMirror.signal(data, 'shown')
}
}
}
};
}
function parseOptions(cm, pos, options) {
var editor = cm.options.hintOptions;
var out = {};
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
if (editor) 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];
function parseOptions (cm, pos, options) {
const editor = cm.options.hintOptions
const out = {}
for (var prop in defaultOptions) out[prop] = defaultOptions[prop]
if (editor) {
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 (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
return out;
return out
}
function getText(completion) {
if (typeof completion == "string") return completion;
else return completion.text;
function getText (completion) {
if (typeof completion == 'string') return completion
else return completion.text
}
function buildKeyMap(completion, handle) {
var baseMap = {
function buildKeyMap (completion, handle) {
const baseMap = {
Up: function () {
handle.moveFocus(-1);
handle.moveFocus(-1)
},
Down: function () {
handle.moveFocus(1);
handle.moveFocus(1)
},
PageUp: function () {
handle.moveFocus(-handle.menuSize() + 1, true);
handle.moveFocus(-handle.menuSize() + 1, true)
},
PageDown: function () {
handle.moveFocus(handle.menuSize() - 1, true);
handle.moveFocus(handle.menuSize() - 1, true)
},
Home: function () {
handle.setFocus(0);
handle.setFocus(0)
},
End: function () {
handle.setFocus(handle.length - 1);
handle.setFocus(handle.length - 1)
},
Enter: handle.pick,
Tab: handle.pick,
Esc: handle.close
};
}
var mac = /Mac/.test(navigator.platform);
const mac = /Mac/.test(navigator.platform)
if (mac) {
baseMap["Ctrl-P"] = function () {
handle.moveFocus(-1);
};
baseMap["Ctrl-N"] = function () {
handle.moveFocus(1);
};
baseMap['Ctrl-P'] = function () {
handle.moveFocus(-1)
}
baseMap['Ctrl-N'] = function () {
handle.moveFocus(1)
}
}
var custom = completion.options.customKeys;
var ourMap = custom ? {} : baseMap;
const custom = completion.options.customKeys
const ourMap = custom ? {} : baseMap
function addBinding(key, val) {
var bound;
if (typeof val != "string")
function addBinding (key, val) {
let bound
if (typeof val != 'string') {
bound = function (cm) {
return val(cm, handle);
};
return val(cm, handle)
}
}
// This mechanism is deprecated
else if (baseMap.hasOwnProperty(val))
bound = baseMap[val];
else
bound = val;
ourMap[key] = bound;
else if (baseMap.hasOwnProperty(val)) { bound = baseMap[val] } else { bound = val }
ourMap[key] = bound
}
if (custom)
for (var key in custom) if (custom.hasOwnProperty(key))
addBinding(key, custom[key]);
var extra = completion.options.extraKeys;
if (extra)
for (var key in extra) if (extra.hasOwnProperty(key))
addBinding(key, extra[key]);
return ourMap;
if (custom) {
for (var key in custom) {
if (custom.hasOwnProperty(key)) { addBinding(key, custom[key]) }
}
}
const extra = completion.options.extraKeys
if (extra) {
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) {
if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
el = el.parentNode;
if (el.nodeName.toUpperCase() === 'LI' && el.parentNode == hintsElement) return el
el = el.parentNode
}
}
function Widget(completion, data) {
this.id = "cm-complete-" + Math.floor(Math.random(1e6))
this.completion = completion;
this.data = data;
this.picked = false;
var widget = this, cm = completion.cm;
var ownerDocument = cm.getInputField().ownerDocument;
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
function Widget (completion, data) {
this.id = 'cm-complete-' + Math.floor(Math.random(1e6))
this.completion = completion
this.data = data
this.picked = false
const widget = this; const cm = completion.cm
const ownerDocument = cm.getInputField().ownerDocument
const parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow
var hints = this.hints = ownerDocument.createElement("ul");
const hints = this.hints = ownerDocument.createElement('ul')
// $(hints).append(`
// <h1>lalallalla</h1>
// `)
hints.setAttribute("role", "listbox")
hints.setAttribute("aria-expanded", "true")
hints.setAttribute('role', 'listbox')
hints.setAttribute('aria-expanded', 'true')
hints.id = this.id
var theme = completion.cm.options.theme;
hints.className = "CodeMirror-hints " + theme;
this.selectedHint = data.selectedHint || 0;
const theme = completion.cm.options.theme
hints.className = 'CodeMirror-hints ' + theme
this.selectedHint = data.selectedHint || 0
var completions = data.list;
for (var i = 0; i < completions.length; ++i) {
var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i];
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
if (cur.className != null) className = cur.className + " " + className;
elt.className = className;
if (i == this.selectedHint) elt.setAttribute("aria-selected", "true")
elt.id = this.id + "-" + i
elt.setAttribute("role", "option")
if (cur.render) cur.render(elt, data, cur);
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
elt.hintId = i;
const completions = data.list
for (let i = 0; i < completions.length; ++i) {
const elt = hints.appendChild(ownerDocument.createElement('li')); const cur = completions[i]
let className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS)
if (cur.className != null) className = cur.className + ' ' + className
elt.className = className
if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true')
elt.id = this.id + '-' + i
elt.setAttribute('role', 'option')
if (cur.render) cur.render(elt, data, cur)
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)))
elt.hintId = i
}
var container = completion.options.container || ownerDocument.body;
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
var offsetLeft = 0, offsetTop = 0;
const container = completion.options.container || ownerDocument.body
let pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null)
let left = pos.left; let top = pos.bottom; let below = true
let offsetLeft = 0; let offsetTop = 0
if (container !== ownerDocument.body) {
// 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;
var offsetParent = isContainerPositioned ? container : container.offsetParent;
var offsetParentPosition = offsetParent.getBoundingClientRect();
var bodyPosition = ownerDocument.body.getBoundingClientRect();
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
const isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1
const offsetParent = isContainerPositioned ? container : container.offsetParent
const offsetParentPosition = offsetParent.getBoundingClientRect()
const bodyPosition = ownerDocument.body.getBoundingClientRect()
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft)
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop)
}
hints.style.left = (left - offsetLeft) + "px";
hints.style.top = (top - offsetTop) + "px";
hints.style.left = (left - offsetLeft) + 'px'
hints.style.top = (top - offsetTop) + 'px'
// todo 隐藏codemirror自带的提示
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.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
//在这里 添加的DOM 元素 -- 该方案 实现复杂算了吧
container.appendChild(hints);
// debugger
// $(container).append(
// `
// <div>
// <h1>hahah</h1>
// ${ hints }
// </div>
// `
// )
cm.getInputField().setAttribute("aria-autocomplete", "list")
cm.getInputField().setAttribute("aria-owns", this.id)
cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint)
const winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth)
const winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight)
// 在这里 添加的DOM 元素 -- 该方案 实现复杂算了吧
container.appendChild(hints)
// debugger
// $(container).append(
// `
// <div>
// <h1>hahah</h1>
// ${ hints }
// </div>
// `
// )
cm.getInputField().setAttribute('aria-autocomplete', 'list')
cm.getInputField().setAttribute('aria-owns', this.id)
cm.getInputField().setAttribute('aria-activedescendant', this.id + '-' + this.selectedHint)
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
let box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect()
const scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false
// Compute in the timeout to avoid reflow on init
var startScroll;
let startScroll
setTimeout(function () {
startScroll = cm.getScrollInfo();
});
startScroll = cm.getScrollInfo()
})
var overlapY = box.bottom - winH;
const overlapY = box.bottom - winH
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
hints.style.top = (top = pos.top - height - offsetTop) + "px";
below = false;
hints.style.top = (top = pos.top - height - offsetTop) + 'px'
below = false
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
var cursor = cm.getCursor();
hints.style.height = (winH - 5) + 'px'
hints.style.top = (top = pos.bottom - box.top - offsetTop) + 'px'
const cursor = cm.getCursor()
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left - offsetLeft) + "px";
box = hints.getBoundingClientRect();
pos = cm.cursorCoords(cursor)
hints.style.left = (left = pos.left - offsetLeft) + 'px'
box = hints.getBoundingClientRect()
}
}
}
var overlapX = box.right - winW;
if (scrolls) overlapX += cm.display.nativeBarWidth;
let overlapX = box.right - winW
if (scrolls) overlapX += cm.display.nativeBarWidth
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW;
hints.style.width = (winW - 5) + 'px'
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
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
moveFocus: function (n, avoidWrap) {
widget.changeActive(widget.selectedHint + n, avoidWrap);
widget.changeActive(widget.selectedHint + n, avoidWrap)
},
setFocus: function (n) {
widget.changeActive(n);
widget.changeActive(n)
},
menuSize: function () {
return widget.screenAmount();
return widget.screenAmount()
},
length: completions.length,
close: function () {
completion.close();
completion.close()
},
pick: function () {
widget.pick();
widget.pick()
},
data: data
}));
}))
if (completion.options.closeOnUnfocus) {
var closingOnBlur;
cm.on("blur", this.onBlur = function () {
let closingOnBlur
cm.on('blur', this.onBlur = function () {
closingOnBlur = setTimeout(function () {
completion.close();
}, 100);
});
cm.on("focus", this.onFocus = function () {
clearTimeout(closingOnBlur);
});
completion.close()
}, 100)
})
cm.on('focus', this.onFocus = function () {
clearTimeout(closingOnBlur)
})
}
cm.on("scroll", this.onScroll = function () {
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
if (!startScroll) startScroll = cm.getScrollInfo();
var newTop = top + startScroll.top - curScroll.top;
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
if (!below) point += hints.offsetHeight;
if (point <= editor.top || point >= editor.bottom) return completion.close();
hints.style.top = newTop + "px";
hints.style.left = (left + startScroll.left - curScroll.left) + "px";
});
cm.on('scroll', this.onScroll = function () {
const curScroll = cm.getScrollInfo(); const editor = cm.getWrapperElement().getBoundingClientRect()
if (!startScroll) startScroll = cm.getScrollInfo()
const newTop = top + startScroll.top - curScroll.top
let point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop)
if (!below) point += hints.offsetHeight
if (point <= editor.top || point >= editor.bottom) return completion.close()
hints.style.top = newTop + 'px'
hints.style.left = (left + startScroll.left - curScroll.left) + 'px'
})
CodeMirror.on(hints, "dblclick", function (e) {
var t = getHintElement(hints, e.target || e.srcElement);
CodeMirror.on(hints, 'dblclick', function (e) {
const t = getHintElement(hints, e.target || e.srcElement)
if (t && t.hintId != null) {
widget.changeActive(t.hintId);
widget.pick();
widget.changeActive(t.hintId)
widget.pick()
}
});
})
CodeMirror.on(hints, "click", function (e) {
var t = getHintElement(hints, e.target || e.srcElement);
CodeMirror.on(hints, 'click', function (e) {
const t = getHintElement(hints, e.target || e.srcElement)
if (t && t.hintId != null) {
widget.changeActive(t.hintId);
if (completion.options.completeOnSingleClick) widget.pick();
widget.changeActive(t.hintId)
if (completion.options.completeOnSingleClick) widget.pick()
}
});
})
CodeMirror.on(hints, "mousedown", function () {
CodeMirror.on(hints, 'mousedown', function () {
setTimeout(function () {
cm.focus();
}, 20);
});
cm.focus()
}, 20)
})
// 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) {
this.scrollToActive();
this.scrollToActive()
}
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
CodeMirror.signal(data, 'select', completions[this.selectedHint], hints.childNodes[this.selectedHint])
return true
}
Widget.prototype = {
close: function () {
if (this.completion.widget != this) return;
this.completion.widget = null;
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
this.completion.cm.removeKeyMap(this.keyMap);
var input = this.completion.cm.getInputField()
input.removeAttribute("aria-activedescendant")
input.removeAttribute("aria-owns")
if (this.completion.widget != this) return
this.completion.widget = null
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints)
this.completion.cm.removeKeyMap(this.keyMap)
const input = this.completion.cm.getInputField()
input.removeAttribute('aria-activedescendant')
input.removeAttribute('aria-owns')
var cm = this.completion.cm;
const cm = this.completion.cm
if (this.completion.options.closeOnUnfocus) {
cm.off("blur", this.onBlur);
cm.off("focus", this.onFocus);
cm.off('blur', this.onBlur)
cm.off('focus', this.onFocus)
}
cm.off("scroll", this.onScroll);
cm.off('scroll', this.onScroll)
},
disable: function () {
this.completion.cm.removeKeyMap(this.keyMap);
var widget = this;
this.completion.cm.removeKeyMap(this.keyMap)
const widget = this
this.keyMap = {
Enter: function () {
widget.picked = true;
widget.picked = true
}
};
this.completion.cm.addKeyMap(this.keyMap);
}
this.completion.cm.addKeyMap(this.keyMap)
},
pick: function () {
this.completion.pick(this.data, this.selectedHint);
this.completion.pick(this.data, this.selectedHint)
},
changeActive: function (i, avoidWrap) {
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;
if (this.selectedHint == i) return;
var node = this.hints.childNodes[this.selectedHint];
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 }
if (this.selectedHint == i) return
let node = this.hints.childNodes[this.selectedHint]
if (node) {
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node.removeAttribute("aria-selected")
node.className = node.className.replace(' ' + ACTIVE_HINT_ELEMENT_CLASS, '')
node.removeAttribute('aria-selected')
}
node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
node.setAttribute("aria-selected", "true")
this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id)
node = this.hints.childNodes[this.selectedHint = i]
node.className += ' ' + ACTIVE_HINT_ELEMENT_CLASS
node.setAttribute('aria-selected', 'true')
this.completion.cm.getInputField().setAttribute('aria-activedescendant', node.id)
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 () {
var selectedHintRange = this.getSelectedHintRange();
var node1 = this.hints.childNodes[selectedHintRange.from];
var node2 = this.hints.childNodes[selectedHintRange.to];
var firstNode = this.hints.firstChild;
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;
const selectedHintRange = this.getSelectedHintRange()
const node1 = this.hints.childNodes[selectedHintRange.from]
const node2 = this.hints.childNodes[selectedHintRange.to]
const firstNode = this.hints.firstChild
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 }
},
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 () {
var margin = this.completion.options.scrollMargin || 0;
const margin = this.completion.options.scrollMargin || 0
return {
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
var result = []
for (var i = 0; i < helpers.length; i++)
if (helpers[i].supportsSelection) result.push(helpers[i])
const result = []
for (let i = 0; i < helpers.length; i++) { if (helpers[i].supportsSelection) result.push(helpers[i]) }
return result
}
function fetchHints(hint, cm, options, callback) {
function fetchHints (hint, cm, options, callback) {
if (hint.async) {
hint(cm, callback, options)
} else {
var result = hint(cm, options)
const result = hint(cm, options)
if (result && result.then) result.then(callback)
else callback(result)
}
}
function resolveAutoHints(cm, pos) {
var helpers = cm.getHelpers(pos, "hint"), words
function resolveAutoHints (cm, pos) {
const helpers = cm.getHelpers(pos, 'hint'); let words
if (helpers.length) {
var resolved = function (cm, callback, options) {
var app = applicableHelpers(cm, helpers);
const resolved = function (cm, callback, options) {
const app = applicableHelpers(cm, helpers)
function run(i) {
function run (i) {
if (i == app.length) return callback(null)
fetchHints(app[i], cm, options, function (result) {
if (result && result.list.length > 0) callback(result)
@@ -532,9 +528,9 @@ export default function showHint(CodeMirror) {
resolved.async = true
resolved.supportsSelection = true
return resolved
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
} else if (words = cm.getHelper(cm.getCursor(), 'hintWords')) {
return function (cm) {
return CodeMirror.hint.fromList(cm, {words: words})
return CodeMirror.hint.fromList(cm, { words: words })
}
} else if (CodeMirror.hint.anyword) {
return function (cm, options) {
@@ -546,30 +542,29 @@ export default function showHint(CodeMirror) {
}
}
CodeMirror.registerHelper("hint", "auto", {
CodeMirror.registerHelper('hint', 'auto', {
resolve: resolveAutoHints
});
})
CodeMirror.registerHelper("hint", "fromList", function (cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
CodeMirror.registerHelper('hint', 'fromList', function (cm, options) {
const cur = cm.getCursor(); const token = cm.getTokenAt(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))) {
term = token.string.substr(0, cur.ch - token.start)
} else {
term = ""
term = ''
from = cur
}
var found = [];
for (var i = 0; i < options.words.length; i++) {
var word = options.words[i];
if (word.slice(0, term.length) == term)
found.push(word);
const found = []
for (let i = 0; i < options.words.length; i++) {
const word = options.words[i]
if (word.slice(0, term.length) == term) { 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 = {
hint: CodeMirror.hint.auto,
@@ -584,8 +579,8 @@ export default function showHint(CodeMirror) {
customKeys: null,
extraKeys: null,
paddingForScrollbar: true,
moveOnOverlap: true,
};
moveOnOverlap: true
}
CodeMirror.defineOption("hintOptions", null);
CodeMirror.defineOption('hintOptions', null)
}

View File

@@ -1,343 +1,336 @@
import {cloneDeep} from 'lodash'
import {matchMain} from './matchRelatedInfo'
import { cloneDeep } from 'lodash'
import { matchMain } from './matchRelatedInfo'
export default function (CodeMirror,
{
dataset,
hinthook, //生成提示的hook 拦截
keywordshook //关键字hook 在关键字里面
}
{
dataset,
hinthook, // 生成提示的hook 拦截
keywordshook // 关键字hook 在关键字里面
}
) {
// "use strict";
var tables;
var defaultTable;
var keywords;
var identifierQuote;
var CONS = {
QUERY_DIV: ";",
ALIAS_KEYWORD: "AS"
};
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
let tables
let defaultTable
let keywords
let identifierQuote
const CONS = {
QUERY_DIV: ';',
ALIAS_KEYWORD: 'AS'
}
const Pos = CodeMirror.Pos; const cmpPos = CodeMirror.cmpPos
function isArray(val) {
return Object.prototype.toString.call(val) == "[object Array]"
function isArray (val) {
return Object.prototype.toString.call(val) == '[object Array]'
}
function getKeywords(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
keywords = CodeMirror.resolveMode(mode).keywords;
function getKeywords (editor) {
let mode = editor.doc.modeOption
if (mode === 'sql') mode = 'text/x-sql'
keywords = CodeMirror.resolveMode(mode).keywords
if (keywordshook) {
keywords = keywordshook(keywords, CodeMirror.resolveMode(mode)) || keywords
}
return keywords
}
function getIdentifierQuote(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).identifierQuote || "`";
function getIdentifierQuote (editor) {
let mode = editor.doc.modeOption
if (mode === 'sql') mode = 'text/x-sql'
return CodeMirror.resolveMode(mode).identifierQuote || '`'
}
function getText(item) {
return typeof item == "string" ? item : item.text;
function getText (item) {
return typeof item == 'string' ? item : item.text
}
function wrapTable(name, value) {
if (isArray(value)) value = {columns: value}
function wrapTable (name, value) {
if (isArray(value)) value = { columns: value }
if (!value.text) value.text = name
return value
}
function parseTables(input) {
//table 名称变大写 统一变成对象格式 columns text
var result = {}
function parseTables (input) {
// table 名称变大写 统一变成对象格式 columns text
const result = {}
if (isArray(input)) {
for (var i = input.length - 1; i >= 0; i--) {
var item = input[i]
for (let i = input.length - 1; i >= 0; i--) {
const item = input[i]
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
}
} else if (input) {
for (var name in input)
result[name.toUpperCase()] = wrapTable(name, input[name])
for (const name in input) { result[name.toUpperCase()] = wrapTable(name, input[name]) }
}
return result
}
function getTable(name) {
function getTable (name) {
return tables[name.toUpperCase()]
}
function shallowClone(object) {
var result = {};
for (var key in object) if (object.hasOwnProperty(key))
result[key] = object[key];
return result;
function shallowClone (object) {
const result = {}
for (const key in object) {
if (object.hasOwnProperty(key)) { result[key] = object[key] }
}
return result
}
function match(string, word) {
var len = string.length;
var sub = getText(word).substr(0, len);
return string.toUpperCase() === sub.toUpperCase();
function match (string, word) {
const len = string.length
const sub = getText(word).substr(0, len)
return string.toUpperCase() === sub.toUpperCase()
}
function addMatches(result, search, wordlist, formatter) {
function addMatches (result, search, wordlist, formatter) {
if (isArray(wordlist)) {
for (var i = 0; i < wordlist.length; i++)
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
for (let i = 0; i < wordlist.length; i++) { if (match(search, wordlist[i])) result.push(formatter(wordlist[i])) }
} else {
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
var val = wordlist[word]
if (!val || val === true)
val = word
else
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
if (match(search, val)) result.push(formatter(val))
for (const word in wordlist) {
if (wordlist.hasOwnProperty(word)) {
let val = wordlist[word]
if (!val || val === true) { val = word } else { 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(.)
if (name.charAt(0) == ".") {
name = name.substr(1);
if (name.charAt(0) == '.') {
name = name.substr(1)
}
// replace duplicated identifierQuotes with single identifierQuotes
// and remove single identifierQuotes
var nameParts = name.split(identifierQuote + identifierQuote);
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote, "g"), "");
return nameParts.join(identifierQuote);
const nameParts = name.split(identifierQuote + identifierQuote)
for (let i = 0; i < nameParts.length; i++) { nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote, 'g'), '') }
return nameParts.join(identifierQuote)
}
function insertIdentifierQuotes(name) {
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
function insertIdentifierQuotes (name) {
const nameParts = getText(name).split('.')
for (let i = 0; i < nameParts.length; i++) {
nameParts[i] = identifierQuote +
// duplicate identifierQuotes
nameParts[i].replace(new RegExp(identifierQuote, "g"), identifierQuote + identifierQuote) +
identifierQuote;
var escaped = nameParts.join(".");
if (typeof name == "string") return escaped;
name = shallowClone(name);
name.text = escaped;
return name;
nameParts[i].replace(new RegExp(identifierQuote, 'g'), identifierQuote + identifierQuote) +
identifierQuote
}
const escaped = nameParts.join('.')
if (typeof name == 'string') return escaped
name = shallowClone(name)
name.text = escaped
return name
}
function getLeftpart(cur, token, result, editor) {
var nameParts = [];
var start = token.start;
var cont = true;
function getLeftpart (cur, token, result, editor) {
const nameParts = []
let start = token.start
let cont = true
while (cont) {
//全是空格 或者 是操作符 就接着往前找
cont = ((token.type === 'operator' || token.string.match(/^[ ]*$/)) && start !== 0);
start = token.start;
nameParts.unshift(token.string);
token = editor.getTokenAt(Pos(cur.line, token.start));
// 全是空格 或者 是操作符 就接着往前找
cont = ((token.type === 'operator' || token.string.match(/^[ ]*$/)) && start !== 0)
start = token.start
nameParts.unshift(token.string)
token = editor.getTokenAt(Pos(cur.line, token.start))
if (token.type === 'operator') {
cont = true;
token = editor.getTokenAt(Pos(cur.line, token.start));
cont = true
token = editor.getTokenAt(Pos(cur.line, token.start))
}
}
return nameParts[0]
}
function isRightpart(cur, token, result, editor) {
token = editor.getTokenAt(Pos(cur.line, token.start));
function isRightpart (cur, token, result, editor) {
token = editor.getTokenAt(Pos(cur.line, token.start))
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
var useIdentifierQuotes = false;
var nameParts = [];
var start = token.start;
var cont = true;
let useIdentifierQuotes = false
const nameParts = []
let start = token.start
let cont = true
while (cont) {
cont = (token.string.charAt(0) == ".");
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
cont = (token.string.charAt(0) == '.')
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote)
start = token.start;
nameParts.unshift(cleanName(token.string));
start = token.start
nameParts.unshift(cleanName(token.string))
token = editor.getTokenAt(Pos(cur.line, token.start));
if (token.string == ".") {
cont = true;
token = editor.getTokenAt(Pos(cur.line, token.start));
token = editor.getTokenAt(Pos(cur.line, token.start))
if (token.string == '.') {
cont = true
token = editor.getTokenAt(Pos(cur.line, token.start))
}
}
// Try to complete table names
var string = nameParts.join(".");
let string = nameParts.join('.')
addMatches(result, string, tables, function (w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
})
// Try to complete columns from defaultTable
addMatches(result, string, defaultTable, function (w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
})
// Try to complete columns
string = nameParts.pop();
var table = nameParts.join(".");
string = nameParts.pop()
let table = nameParts.join('.')
var alias = false;
var aliasTable = table;
let alias = false
const aliasTable = table
// Check if table is available. If not, find table by Alias
if (!getTable(table)) {
var oldTable = table;
table = findTableByAlias(table, editor);
if (table !== oldTable) alias = true;
const oldTable = table
table = findTableByAlias(table, editor)
if (table !== oldTable) alias = true
}
var columns = getTable(table);
if (columns && columns.columns)
columns = columns.columns;
let columns = getTable(table)
if (columns && columns.columns) { columns = columns.columns }
if (columns) {
addMatches(result, string, columns, function (w) {
var tableInsert = table;
if (alias == true) tableInsert = aliasTable;
if (typeof w == "string") {
w = tableInsert + "." + w;
let tableInsert = table
if (alias == true) tableInsert = aliasTable
if (typeof w == 'string') {
w = tableInsert + '.' + w
} else {
w = shallowClone(w);
w.text = tableInsert + "." + w.text;
w = shallowClone(w)
w.text = tableInsert + '.' + w.text
}
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w
})
}
return start;
return start
}
function eachWord(lineText, f) {
var words = lineText.split(/\s+/)
for (var i = 0; i < words.length; i++)
if (words[i]) f(words[i].replace(/[`,;]/g, ''))
function eachWord (lineText, f) {
const words = lineText.split(/\s+/)
for (let i = 0; i < words.length; i++) { if (words[i]) f(words[i].replace(/[`,;]/g, '')) }
}
function findTableByAlias(alias, editor) {
var doc = editor.doc;
var fullQuery = doc.getValue();
var aliasUpperCase = alias.toUpperCase();
var previousWord = "";
var table = "";
var separator = [];
var validRange = {
function findTableByAlias (alias, editor) {
const doc = editor.doc
const fullQuery = doc.getValue()
const aliasUpperCase = alias.toUpperCase()
let previousWord = ''
let table = ''
const separator = []
let validRange = {
start: Pos(0, 0),
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
var prevItem = null;
var current = editor.getCursor()
// add separator
let 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
let prevItem = null
const current = editor.getCursor()
for (var i = 0; i < separator.length; i++) {
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
validRange = {start: prevItem, end: separator[i]};
break;
validRange = { start: prevItem, end: separator[i] }
break
}
prevItem = separator[i];
prevItem = separator[i]
}
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++) {
var lineText = query[i];
const lineText = query[i]
eachWord(lineText, function (word) {
var wordUpperCase = word.toUpperCase();
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
table = previousWord;
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
previousWord = word;
});
if (table) break;
const wordUpperCase = word.toUpperCase()
if (wordUpperCase === aliasUpperCase && getTable(previousWord)) { table = previousWord }
if (wordUpperCase !== CONS.ALIAS_KEYWORD) { previousWord = word }
})
if (table) break
}
}
return table;
return table
}
CodeMirror.registerHelper("hint", "sql", function (editor, options) {
tables = parseTables(options && options.tables);
var defaultTableName = options && options.defaultTable; //默认table 名称
var disableKeywords = options && options.disableKeywords; //禁用的keyword
defaultTable = defaultTableName && getTable(defaultTableName);
keywords = getKeywords(editor); //获取 定义defineMIME 时候的关键字参数
identifierQuote = getIdentifierQuote(editor); //获取 引用标识符
CodeMirror.registerHelper('hint', 'sql', function (editor, options) {
tables = parseTables(options && options.tables)
const defaultTableName = options && options.defaultTable // 默认table 名称
const disableKeywords = options && options.disableKeywords // 禁用的keyword
defaultTable = defaultTableName && getTable(defaultTableName)
keywords = getKeywords(editor) // 获取 定义defineMIME 时候的关键字参数
identifierQuote = getIdentifierQuote(editor) // 获取 引用标识符
if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);
if (defaultTableName && !defaultTable) { defaultTable = findTableByAlias(defaultTableName, editor) }
defaultTable = defaultTable || [];
defaultTable = defaultTable || []
if (defaultTable.columns)
defaultTable = defaultTable.columns;
if (defaultTable.columns) { defaultTable = defaultTable.columns }
var cur = editor.getCursor(); //line 当前行 ch 索引 sticky ??
var result = [];
var token = editor.getTokenAt(cur), start, end, search;
const cur = editor.getCursor() // line 当前行 ch 索引 sticky ??
let result = []
const token = editor.getTokenAt(cur); let start; let end; let search
if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
token.end = cur.ch
token.string = token.string.slice(0, cur.ch - token.start)
}
//start end search 赋值
// start end search 赋值
// todo 此处允许字符串包含 .
// if (token.string.match(/^[.`"'\w@][\w$#]*/g)) {
if (token.string.match(/^[.`"'\w@][\w#]*/g)) {
search = token.string;
start = token.start;
end = token.end;
search = token.string
start = token.start
end = token.end
} else {
start = end = cur.ch;
search = "";
start = end = cur.ch
search = ''
}
//对引用标识符 . 的使用,关联table 列
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor);
// 对引用标识符 . 的使用,关联table 列
if (search.charAt(0) == '.' || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor)
} else {
var objectOrClass = function (w, className) {
if (typeof w === "object") {
w.className = className;
const objectOrClass = function (w, className) {
if (typeof w === 'object') {
w.className = className
} else {
w = {text: w, className: className};
w = { text: w, className: className }
}
return w;
};
return 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(
result,
search,
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) {
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
});
return objectOrClass(w.toUpperCase(), 'CodeMirror-hint-keyword')
})
}
}
//写入一个 钩子,在这里决定提示的内容
// 写入一个 钩子,在这里决定提示的内容
if (hinthook) {
var params = {
search, //搜索 关键字
keywords, //关键字列表
};
const params = {
search, // 搜索 关键字
keywords // 关键字列表
}
if (token.type === 'operator') {
params.leftpart = getLeftpart(cur, token, result, editor) || ''
}
@@ -347,8 +340,8 @@ export default function (CodeMirror,
/* 之后的参数 是为manualHinthook 预备的 */
var manualParams = {
search, //搜索 关键字
const manualParams = {
search, // 搜索 关键字
// keywords, //关键字列表 没啥用
from: Pos(cur.line, start),
to: Pos(cur.line, end),
@@ -360,13 +353,13 @@ export default function (CodeMirror,
cur
}
var refField = matchMain(CodeMirror, params, manualParams);
const refField = matchMain(CodeMirror, params, manualParams)
manualParams.refField = refField
manualParams.leftpart = refField?.label || manualParams.leftpart;
params.leftpart = refField?.label || params.leftpart;
manualParams.leftpart = refField?.label || manualParams.leftpart
params.leftpart = refField?.label || params.leftpart
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

View File

@@ -1,4 +1,4 @@
var renderData = [
const renderData = [
{
name: 'COUNT',
syntax: 'count(expr)',
@@ -34,7 +34,7 @@ var renderData = [
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)'
}
],
@@ -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.',
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)'
},
{
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)'
}
],
@@ -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.',
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)'
},
{
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'
}
],
@@ -89,7 +89,7 @@ var renderData = [
description: 'Aggregate function is used to return the maximum value of the specified field.',
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)'
}
],
@@ -105,7 +105,7 @@ var renderData = [
description: 'Aggregate function is used to return the minimum value of the specified field.',
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)'
}
],
@@ -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.',
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\')'
}
],
@@ -148,21 +148,21 @@ var renderData = [
},
{
name: 'UNIX_TIMESTAMP',
syntax: `UNIX_TIMESTAMP(date)`,
description: `Returns a Unix timestamp the value of the argument as seconds since '1970-01-01 00:00:00' UTC.`,
syntax: 'UNIX_TIMESTAMP(date)',
description: 'Returns a Unix timestamp the value of the argument as seconds since \'1970-01-01 00:00:00\' UTC.',
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\')'
},
{
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\')'
},
{
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\')'
},
}
],
details () {
// 支持jsx 嵌套写法,万一测试要关键字加重呢
@@ -181,13 +181,13 @@ var renderData = [
},
{
name: 'FROM_UNIXTIME',
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.`,
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.',
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)'
},
}
],
details () {
// 支持jsx 嵌套写法,万一测试要关键字加重呢
@@ -198,10 +198,10 @@ var renderData = [
{
name: '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: [
{
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\')'
}
],
@@ -233,21 +233,21 @@ var renderData = [
},
{
name: 'CONVERT_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.`,
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.',
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\')'
},
{
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\')'
},
{
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\')'
},
}
],
details () {
// 支持jsx 嵌套写法,万一测试要关键字加重呢
@@ -263,11 +263,11 @@ var renderData = [
},
{
name: 'MEDIAN',
syntax: `MEDIAN(<expr>)`,
description: `Aggregate function is used to calculate median value. expr must be Integer, Float or Decimal.`,
syntax: 'MEDIAN(<expr>)',
description: 'Aggregate function is used to calculate median value. expr must be Integer, Float or Decimal.',
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)'
}
],
@@ -279,11 +279,11 @@ var renderData = [
},
{
name: 'QUANTILE',
syntax: `QUANTILE(<expr>[, <level>])`,
description: `Aggregate function is used to calculate an approximate quantile of a numeric data sequence.`,
syntax: 'QUANTILE(<expr>[, <level>])',
description: 'Aggregate function is used to calculate an approximate quantile of a numeric data sequence.',
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)'
}
],
@@ -300,13 +300,13 @@ var renderData = [
</ul>
</div>
}
},
}
]
function main () {
var functionTips = {}
const functionTips = {}
renderData.forEach((item, index) => {
var data = item // 这是个闭包
const data = item // 这是个闭包
functionTips[item.name] = {
name: item.name,
syntax: item.syntax,
@@ -327,8 +327,9 @@ function main () {
})}
</ul>
<h3> Details: </h3>
{Object.prototype.toString.call(data.details) === '[object Function]' ?
<renderer renderFun={data.details}></renderer> : <p>{data.details} </p>}
{Object.prototype.toString.call(data.details) === '[object Function]'
? <renderer renderFun={data.details}></renderer>
: <p>{data.details} </p>}
</div>)
}
}
@@ -337,5 +338,5 @@ function main () {
}
export const functionList = renderData
var functionTips = main()
const functionTips = main()
export default functionTips

View File

@@ -1,37 +1,37 @@
var renderData = [
const renderData = [
{
name: 'FROM',
syntax: `FROM [db.]table |$log_type`,
syntax: 'FROM [db.]table |$log_type',
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',
syntax: `Optional. The selected columns(also known as dimensions and metrics).`,
syntax: 'Optional. The selected columns(also known as dimensions and metrics).',
description: {
title: '可选,获取列',
list: [
`aggregate_function(field) - Aggregate functions, default is count.`,
`as field - Use as to specify a aliases for a field or expression.`
'aggregate_function(field) - Aggregate functions, default is count.',
'as field - Use as to specify a aliases for a field or expression.'
]
}
},
{
name: 'GROUP BY',
syntax: `GROUP BY <field-list>`,
syntax: 'GROUP BY <field-list>',
description: {
title: 'Aggregate data. GROUP BY clause switches the SELECT query into an aggregation mode',
list: [
`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.`,
`The result of aggregating SELECT query will return unique values of "grouping key" in log type.`
'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.',
'The result of aggregating SELECT query will return unique values of "grouping key" in log type.'
]
}
},
{
name: 'HAVING',
syntax: `HAVING <expression-list>`,
syntax: 'HAVING <expression-list>',
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.
Note: HAVING can't be performed if GROUP BY is not performed.`
@@ -39,26 +39,26 @@ var renderData = [
},
{
name: 'LIMIT',
syntax: `LIMIT [n, ]m`,
syntax: 'LIMIT [n, ]m',
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',
syntax: `ORDER BY <sort-field> [ASC|DESC]`,
syntax: 'ORDER BY <sort-field> [ASC|DESC]',
description: {
title: `Sort all of the results by the specified fields.`
title: 'Sort all of the results by the specified fields.'
}
},
{
name: 'WHERE',
syntax: `where $filter [and <expression-list>]`,
syntax: 'where $filter [and <expression-list>]',
description: {
title: `Filter the data.`,
title: 'Filter the data.',
list: [
`$filter - Default global filter clause. Include Time period, Vsys ID, and other expressions, etc`,
`and <expression-list> - filter clauses`
'$filter - Default global filter clause. Include Time period, Vsys ID, and other expressions, etc',
'and <expression-list> - filter clauses'
]
}
}
@@ -66,9 +66,9 @@ var renderData = [
export const sqlList = renderData
function main () {
var sqlTips = {}
const sqlTips = {}
renderData.forEach((item, index) => {
var data = item // 这是个闭包
const data = item // 这是个闭包
sqlTips[item.name] = {
name: item.name,
syntax: item.syntax,
@@ -93,5 +93,5 @@ function main () {
return sqlTips
}
var sqlTips = main()
const sqlTips = main()
export default sqlTips

View File

@@ -1,4 +1,4 @@
var renderData = [
const renderData = [
{
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. ',
@@ -34,8 +34,9 @@ function main () {
<h3> Description: </h3>
<p> {data.description}</p>
<h3> Details: </h3>
{Object.prototype.toString.call(data.details) === '[object Function]' ?
<renderer renderFun={data.details}></renderer> : <p>{data.details} </p>}
{Object.prototype.toString.call(data.details) === '[object Function]'
? <renderer renderFun={data.details}></renderer>
: <p>{data.details} </p>}
</div>)
}
}

View File

@@ -1,22 +1,22 @@
import {dataTemplate, fieldTemplate} from './template'
import { dataTemplate, fieldTemplate } from './template'
export class DeviceTag {
constructor(context, params) {
//先从缓存获取数据
constructor (context, params) {
// 先从缓存获取数据
this.queryparams = params
this.context = context
}
filterQueryData(list) {
filterQueryData (list) {
return list
}
getDataFromRemote() {
//从 远程,也就是请求接口获取数据
getDataFromRemote () {
// 从 远程,也就是请求接口获取数据
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) {
var data = res.data && res.data.list;
const data = res.data && res.data.list
return data
} else {
// this.context.$message({
@@ -31,40 +31,40 @@ export class DeviceTag {
})
}
formatData(data) {
//格式化 获取的数据
formatData (data) {
// 格式化 获取的数据
const resultData = {
operatesList: [
{
"name": "AND",
"function": "A AND B",
type: "abstract",
label: "AND"
name: 'AND',
function: 'A AND B',
type: 'abstract',
label: 'AND'
}
],
filtersList: data ? this.filterQueryData(data.fields || []) : [],
//操作符仓库 用于记录 类型 和 操作符之间的映射关系
// 操作符仓库 用于记录 类型 和 操作符之间的映射关系
operatesDic: data ? data.doc.schema_query.references.operator || [] : [],
//operator 记录运算符的label 和 value 映射 以及操作符的使用方法
// operator 记录运算符的label 和 value 映射 以及操作符的使用方法
operatorManual: data ? data.doc.functions.operator || [] : []
}
return resultData
}
organizeData(data=[]) {
var fields = []
var res = JSON.parse(JSON.stringify(dataTemplate));
if (!data ) {
organizeData (data = []) {
const fields = []
const res = JSON.parse(JSON.stringify(dataTemplate))
if (!data) {
return
}
data.forEach((item, index) => {
var fieldItem = JSON.parse(JSON.stringify(fieldTemplate));
const fieldItem = JSON.parse(JSON.stringify(fieldTemplate))
fieldItem.name = item.tagValue
fieldItem.type = "Array"
fieldItem.type = 'Array'
fieldItem.label = item.tagName
fieldItem.doc.data = (item.subTags || []).map(tagItem => {
return {
code: `'${tagItem.tagValue}'`, //匹配SQL 的时候,这个Code 要加 ''
code: `'${tagItem.tagValue}'`, // 匹配SQL 的时候,这个Code 要加 ''
value: tagItem.tagName,
type: tagItem.tagType
}
@@ -75,20 +75,20 @@ export class DeviceTag {
return res
}
getFormatedData(callback) {
getFormatedData (callback) {
this.getDataFromRemote().then(data => {
//组织数据 模拟scama
var organizedData = this.organizeData(data);
//格式化数据
// 组织数据 模拟scama
const organizedData = this.organizeData(data)
// 格式化数据
this.data = this.formatData(organizedData)
//获取scameData的时候 查询映射字段
// 获取scameData的时候 查询映射字段
callback && callback(this.data)
})
}
dispose(){
this.context=null
this.queryparams=null
this.data=null
dispose () {
this.context = null
this.queryparams = null
this.data = null
}
}

View File

@@ -1,156 +1,156 @@
export const dataTemplate = {
"doc": {
"functions": {
"aggregation": [
doc: {
functions: {
aggregation: [
{
"name": "COUNT",
"function": "count(expr)",
"label": "COUNT"
name: 'COUNT',
function: 'count(expr)',
label: 'COUNT'
}, {
"name": "COUNT_DISTINCT",
"function": "count(distinct expr)",
"label": "COUNT_DISTINCT"
name: 'COUNT_DISTINCT',
function: 'count(distinct expr)',
label: 'COUNT_DISTINCT'
}, {
"name": "AVG",
"function": "avg(expr)",
"label": "AVG"
name: 'AVG',
function: 'avg(expr)',
label: 'AVG'
}, {
"name": "SUM",
"function": "sum(expr)",
"label": "SUM"
name: 'SUM',
function: 'sum(expr)',
label: 'SUM'
}, {
"name": "MAX",
"function": "max(expr)",
"label": "MAX"
name: 'MAX',
function: 'max(expr)',
label: 'MAX'
}, {
"name": "MIN",
"function": "min(expr)",
"label": "MIN"
name: 'MIN',
function: 'min(expr)',
label: 'MIN'
}],
"operator": [
operator: [
{
"name": "=",
"function": "expr = value",
"label": "="
name: '=',
function: 'expr = value',
label: '='
}, {
"name": "!=",
"function": "expr != value",
"label": "!="
name: '!=',
function: 'expr != value',
label: '!='
}, {
"name": ">",
"function": "expr > value",
"label": ">"
name: '>',
function: 'expr > value',
label: '>'
}, {
"name": "<",
"function": "expr < value",
"label": "<"
name: '<',
function: 'expr < value',
label: '<'
}, {
"name": ">=",
"function": "expr >= value",
"label": ">="
name: '>=',
function: 'expr >= value',
label: '>='
}, {
"name": "<=",
"function": "expr <= value",
"label": "<="
name: '<=',
function: 'expr <= value',
label: '<='
}, {
"name": "has",
"function": "has(expr, value)",
"label": "HAS"
name: 'has',
function: 'has(expr, value)',
label: 'HAS'
}, {
"name": "in",
"function": "expr in (values)",
"label": "IN"
name: 'in',
function: 'expr in (values)',
label: 'IN'
}, {
"name": "not in",
"function": "expr not in (values)",
"label": "NOT IN"
name: 'not in',
function: 'expr not in (values)',
label: 'NOT IN'
}, {
"name": "like",
"function": "expr like value",
"label": "LIKE"
name: 'like',
function: 'expr like value',
label: 'LIKE'
}, {
"name": "not like",
"function": "expr not like value",
"label": "NOT LIKE"
name: 'not like',
function: 'expr not like value',
label: 'NOT LIKE'
}, {
"name": "notEmpty",
"function": "notEmpty(expr)",
"label": "NOT EMPTY"
name: 'notEmpty',
function: 'notEmpty(expr)',
label: 'NOT EMPTY'
}, {
"name": "empty",
"function": "empty(expr)",
"label": "EMPTY"
name: 'empty',
function: 'empty(expr)',
label: 'EMPTY'
}]
},
"schema_query": {
"references": {
"aggregation": [
schema_query: {
references: {
aggregation: [
{
"type": "int",
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
type: 'int',
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
}, {
"type": "long",
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
type: 'long',
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
}, {
"type": "float",
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
type: 'float',
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
}, {
"type": "double",
"functions": "COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN"
type: 'double',
functions: 'COUNT,COUNT_DISTINCT,AVG,SUM,MAX,MIN'
}, {
"type": "string",
"functions": "COUNT,COUNT_DISTINCT"
type: 'string',
functions: 'COUNT,COUNT_DISTINCT'
}, {
"type": "date",
"functions": "COUNT,COUNT_DISTINCT,MAX,MIN"
type: 'date',
functions: 'COUNT,COUNT_DISTINCT,MAX,MIN'
}, {
"type": "timestamp",
"functions": "COUNT,COUNT_DISTINCT,MAX,MIN"
type: 'timestamp',
functions: 'COUNT,COUNT_DISTINCT,MAX,MIN'
}
],
"operator": [
operator: [
{
"type": "int",
"functions": "=,!=,>,<,>=,<=,in,not in"
type: 'int',
functions: '=,!=,>,<,>=,<=,in,not in'
}, {
"type": "long",
"functions": "=,!=,>,<,>=,<=,in,not in"
type: 'long',
functions: '=,!=,>,<,>=,<=,in,not in'
}, {
"type": "float",
"functions": "=,!=,>,<,>=,<="
type: 'float',
functions: '=,!=,>,<,>=,<='
}, {
"type": "double",
"functions": "=,!=,>,<,>=,<="
type: 'double',
functions: '=,!=,>,<,>=,<='
}, {
"type": "string",
"functions": "=,!=,in,not in,like,not like,notEmpty,empty"
type: 'string',
functions: '=,!=,in,not in,like,not like,notEmpty,empty'
}, {
"type": "date",
"functions": "=,!=,>,<,>=,<="
type: 'date',
functions: '=,!=,>,<,>=,<='
}, {
"type": "timestamp",
"functions": "=,!=,>,<,>=,<="
type: 'timestamp',
functions: '=,!=,>,<,>=,<='
}, {
"type": "array",
"functions": "has"
type: 'array',
functions: 'has'
}]
}
}
},
"fields": []
fields: []
}
export const fieldTemplate = {
"name": "",
"label": "",
"doc": {
"allow_query": "true",
"visibility": null,
"constraints": {
"type": "tag",
"operator_functions": "in,not in"
name: '',
label: '',
doc: {
allow_query: 'true',
visibility: null,
constraints: {
type: 'tag',
operator_functions: 'in,not in'
},
"data": []
data: []
},
"type": "Array"
type: 'Array'
}