@matdata/yasqe 5.20.3 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +76 -59
  3. package/build/prefixes.json +2190 -2136
  4. package/build/ts/grammar/tokenizer.d.ts +9 -3
  5. package/build/ts/grammar/tokenizer.js +34 -6
  6. package/build/ts/grammar/tokenizer.js.map +1 -1
  7. package/build/ts/src/autocompleters/index.d.ts +4 -2
  8. package/build/ts/src/autocompleters/index.js +9 -33
  9. package/build/ts/src/autocompleters/index.js.map +1 -1
  10. package/build/ts/src/autocompleters/variables.js +17 -19
  11. package/build/ts/src/autocompleters/variables.js.map +1 -1
  12. package/build/ts/src/defaults.d.ts +17 -53
  13. package/build/ts/src/defaults.js +2 -5
  14. package/build/ts/src/defaults.js.map +1 -1
  15. package/build/ts/src/editor/autocompletion.d.ts +32 -0
  16. package/build/ts/src/editor/autocompletion.js +94 -0
  17. package/build/ts/src/editor/autocompletion.js.map +1 -0
  18. package/build/ts/src/editor/doc.d.ts +32 -0
  19. package/build/ts/src/editor/doc.js +121 -0
  20. package/build/ts/src/editor/doc.js.map +1 -0
  21. package/build/ts/src/editor/facade.d.ts +94 -0
  22. package/build/ts/src/editor/facade.js +392 -0
  23. package/build/ts/src/editor/facade.js.map +1 -0
  24. package/build/ts/src/editor/folding.d.ts +16 -0
  25. package/build/ts/src/editor/folding.js +190 -0
  26. package/build/ts/src/editor/folding.js.map +1 -0
  27. package/build/ts/src/editor/gutters.d.ts +8 -0
  28. package/build/ts/src/editor/gutters.js +113 -0
  29. package/build/ts/src/editor/gutters.js.map +1 -0
  30. package/build/ts/src/editor/keymap.d.ts +11 -0
  31. package/build/ts/src/editor/keymap.js +88 -0
  32. package/build/ts/src/editor/keymap.js.map +1 -0
  33. package/build/ts/src/editor/language.d.ts +11 -0
  34. package/build/ts/src/editor/language.js +19 -0
  35. package/build/ts/src/editor/language.js.map +1 -0
  36. package/build/ts/src/editor/tokenizerRunner.d.ts +37 -0
  37. package/build/ts/src/editor/tokenizerRunner.js +115 -0
  38. package/build/ts/src/editor/tokenizerRunner.js.map +1 -0
  39. package/build/ts/src/index.d.ts +49 -100
  40. package/build/ts/src/index.js +179 -100
  41. package/build/ts/src/index.js.map +1 -1
  42. package/build/ts/src/prefixes.json +2191 -2137
  43. package/build/ts/src/tooltip.js +9 -6
  44. package/build/ts/src/tooltip.js.map +1 -1
  45. package/build/yasqe.min.css +1 -1
  46. package/build/yasqe.min.css.map +3 -3
  47. package/build/yasqe.min.js +76 -91
  48. package/build/yasqe.min.js.map +4 -4
  49. package/grammar/tokenizer.ts +62 -8
  50. package/package.json +11 -6
  51. package/src/autocompleters/index.ts +24 -53
  52. package/src/autocompleters/show-hint.scss +17 -9
  53. package/src/autocompleters/variables.ts +20 -24
  54. package/src/defaults.ts +2 -6
  55. package/src/editor/autocompletion.ts +147 -0
  56. package/src/editor/doc.ts +151 -0
  57. package/src/editor/facade.ts +558 -0
  58. package/src/editor/folding.ts +225 -0
  59. package/src/editor/gutters.ts +152 -0
  60. package/src/editor/keymap.ts +133 -0
  61. package/src/editor/language.ts +47 -0
  62. package/src/editor/tokenizerRunner.ts +198 -0
  63. package/src/index.ts +193 -127
  64. package/src/prefixes.json +2190 -2136
  65. package/src/scss/buttons.scss +4 -2
  66. package/src/scss/codemirrorMods.scss +107 -11
  67. package/src/scss/yasqe.scss +4 -2
  68. package/src/tooltip.ts +16 -13
  69. package/build/ts/src/CodeMirror.d.ts +0 -30
  70. package/build/ts/src/CodeMirror.js +0 -20
  71. package/build/ts/src/CodeMirror.js.map +0 -1
  72. package/build/ts/src/prefixFold.d.ts +0 -8
  73. package/build/ts/src/prefixFold.js +0 -87
  74. package/build/ts/src/prefixFold.js.map +0 -1
  75. package/src/CodeMirror.ts +0 -54
  76. package/src/prefixFold.ts +0 -94
@@ -1,13 +1,16 @@
1
1
  import "./scss/yasqe.scss";
2
2
  import "./scss/buttons.scss";
3
+ import "./scss/codemirrorMods.scss";
3
4
  import "leaflet/dist/leaflet.css";
4
5
  import { Prefixes } from "./prefixUtils";
5
- import * as sparql11Mode from "../grammar/tokenizer";
6
6
  import { Storage as YStorage } from "@matdata/yasgui-utils";
7
7
  import * as queryString from "query-string";
8
8
  import * as Sparql from "./sparql";
9
9
  import * as Autocompleter from "./autocompleters";
10
- import CodeMirror from "./CodeMirror";
10
+ import { EditorFacade, EditorOptions } from "./editor/facade";
11
+ import type { Position, Token, TokenizerState } from "./editor/tokenizerRunner";
12
+ import type { ExtraKeys } from "./editor/keymap";
13
+ import type { HintFn } from "./editor/autocompletion";
11
14
  import { YasqeAjaxConfig } from "./sparql";
12
15
  export interface Yasqe {
13
16
  on(eventName: "query", handler: (instance: Yasqe, req: Request, abortController?: AbortController) => void): void;
@@ -16,7 +19,6 @@ export interface Yasqe {
16
19
  off(eventName: "queryAbort", handler: (instance: Yasqe, req: Request) => void): void;
17
20
  on(eventName: "queryResponse", handler: (instance: Yasqe, response: any, duration: number) => void): void;
18
21
  off(eventName: "queryResponse", handler: (instance: Yasqe, response: any, duration: number) => void): void;
19
- showHint: (conf: HintConfig) => void;
20
22
  on(eventName: "error", handler: (instance: Yasqe) => void): void;
21
23
  off(eventName: "error", handler: (instance: Yasqe) => void): void;
22
24
  on(eventName: "blur", handler: (instance: Yasqe) => void): void;
@@ -35,9 +37,18 @@ export interface Yasqe {
35
37
  off(eventName: "saveManagedQuery", handler: () => void): void;
36
38
  on(eventName: "downloadRqFile", handler: () => void): void;
37
39
  off(eventName: "downloadRqFile", handler: () => void): void;
38
- on(eventName: string, handler: () => void): void;
40
+ on(eventName: "change", handler: (instance: Yasqe, changeObj?: any) => void): void;
41
+ off(eventName: "change", handler: (instance: Yasqe, changeObj?: any) => void): void;
42
+ on(eventName: "changes", handler: (instance: Yasqe) => void): void;
43
+ off(eventName: "changes", handler: (instance: Yasqe) => void): void;
44
+ on(eventName: "cursorActivity", handler: (instance: Yasqe) => void): void;
45
+ off(eventName: "cursorActivity", handler: (instance: Yasqe) => void): void;
46
+ on(eventName: "focus", handler: (instance: Yasqe) => void): void;
47
+ off(eventName: "focus", handler: (instance: Yasqe) => void): void;
48
+ on(eventName: string, handler: (...args: any[]) => void): void;
49
+ off(eventName: string, handler: (...args: any[]) => void): void;
39
50
  }
40
- export declare class Yasqe extends CodeMirror {
51
+ export declare class Yasqe extends EditorFacade {
41
52
  private static storageNamespace;
42
53
  autocompleters: {
43
54
  [name: string]: Autocompleter.Completer | undefined;
@@ -75,9 +86,10 @@ export declare class Yasqe extends CodeMirror {
75
86
  private handleQuery;
76
87
  private handleQueryResponse;
77
88
  private handleQueryAbort;
89
+ protected getHintFn(): HintFn | undefined;
90
+ private pendingHintFn;
78
91
  private registerEventListeners;
79
92
  private unregisterEventListeners;
80
- emit(event: string, ...data: any[]): void;
81
93
  getStorageId(getter?: Config["persistenceId"]): string | undefined;
82
94
  private drawButtons;
83
95
  private toggleHamburgerMenu;
@@ -114,7 +126,7 @@ export declare class Yasqe extends CodeMirror {
114
126
  [varName: string]: string;
115
127
  } | Array<{
116
128
  [varName: string]: string;
117
- }>): any;
129
+ }>): string;
118
130
  getValueWithoutComments(): string;
119
131
  setCheckSyntaxErrors(isEnabled: boolean): void;
120
132
  checkSyntax(): void;
@@ -133,6 +145,9 @@ export declare class Yasqe extends CodeMirror {
133
145
  enableCompleter(name: string): Promise<void>;
134
146
  disableCompleter(name: string): void;
135
147
  autocomplete(fromAutoShow?: boolean): void;
148
+ private buildHintFn;
149
+ isAutocompletionActive(): boolean;
150
+ hideAutocompletion(): void;
136
151
  collapsePrefixes(collapse?: boolean): void;
137
152
  getPrefixesFromQuery(): Prefixes;
138
153
  addPrefixes(prefixes: string | Prefixes): void;
@@ -147,10 +162,10 @@ export declare class Yasqe extends CodeMirror {
147
162
  getAsWgetString(config?: Sparql.YasqeAjaxConfig): string;
148
163
  hasAuthenticationCredentials(config?: Sparql.YasqeAjaxConfig): boolean;
149
164
  abortQuery(): void;
150
- expandEditor(): void;
165
+ expandEditor: () => void;
151
166
  destroy(): void;
152
167
  static Sparql: typeof Sparql;
153
- static runMode: any;
168
+ static runMode: (text: string, _mode: any, callback: (text: string, style: string | null) => void) => TokenizerState;
154
169
  static clearStorage(): void;
155
170
  static Autocompleters: {
156
171
  [name: string]: Autocompleter.CompleterConfig;
@@ -158,65 +173,31 @@ export declare class Yasqe extends CodeMirror {
158
173
  static registerAutocompleter(value: Autocompleter.CompleterConfig, enable?: boolean): void;
159
174
  static defaults: {
160
175
  requestConfig: PlainRequestConfig;
161
- value?: any;
176
+ value?: string;
177
+ persistenceId: ((yasqe: Yasqe) => string) | string | undefined | null;
178
+ persistencyExpire: number;
179
+ extraKeys: ExtraKeys<Yasqe>;
162
180
  mode: string;
163
- theme?: string;
164
- indentUnit?: number;
165
- smartIndent?: boolean;
181
+ lineNumbers?: boolean;
182
+ lineWrapping?: boolean;
183
+ readOnly?: boolean;
166
184
  tabSize?: number;
185
+ indentUnit?: number;
167
186
  indentWithTabs?: boolean;
168
- electricChars?: boolean;
169
- rtlMoveVisually?: boolean;
170
- keyMap?: string;
171
- extraKeys?: string | import("codemirror").KeyMap;
172
- lineWrapping?: boolean;
173
- lineNumbers?: boolean;
174
- firstLineNumber?: number;
175
- lineNumberFormatter?: (line: number) => string;
187
+ theme?: string;
188
+ tabMode: string;
189
+ foldGutter: boolean | object;
176
190
  gutters?: string[];
177
- foldGutter: any;
178
- fixedGutter?: boolean;
179
- scrollbarStyle?: string;
180
- coverGutterNextToScrollbar?: boolean;
181
- inputStyle?: import("codemirror").InputStyle;
182
- readOnly?: any;
183
- screenReaderLabel?: string;
184
- showCursorWhenSelecting?: boolean;
185
- lineWiseCopyCut?: boolean;
186
- pasteLinesPerSelection?: boolean;
187
- selectionsMayTouch?: boolean;
188
- undoDepth?: number;
189
- historyEventDelay?: number;
190
- tabindex?: number;
191
- autofocus?: boolean;
192
- dragDrop?: boolean;
193
- allowDropFileTypes?: Array<string>;
194
- onDragEvent?: (instance: import("codemirror").Editor, event: DragEvent) => boolean;
195
- onKeyEvent?: (instance: import("codemirror").Editor, event: KeyboardEvent) => boolean;
196
- cursorBlinkRate?: number;
197
- cursorScrollMargin?: number;
198
- cursorHeight?: number;
199
- resetSelectionOnContextMenu?: boolean;
200
- workTime?: number;
201
- workDelay?: number;
202
- pollInterval?: number;
203
- flattenSpans?: boolean;
204
- addModeClass?: boolean;
205
- maxHighlightLength?: number;
206
- viewportMargin?: number;
207
- spellcheck?: boolean;
208
- autocorrect?: boolean;
209
- autocapitalize?: boolean;
210
- lint?: boolean | import("codemirror").LintStateOptions | import("codemirror").Linter | import("codemirror").AsyncLinter;
211
191
  matchBrackets: boolean;
212
- showHint?: boolean;
213
- hintOptions?: import("codemirror").ShowHintOptions;
214
- highlightSelectionMatches: {
192
+ highlightSelectionMatches: boolean | {
215
193
  showToken?: RegExp;
216
194
  annotateScrollbar?: boolean;
217
195
  };
218
- persistenceId: ((yasqe: Yasqe) => string) | string | undefined | null;
219
- persistencyExpire: number;
196
+ autoCloseBrackets?: boolean;
197
+ fixedGutter?: boolean;
198
+ placeholder?: string;
199
+ autofocus?: boolean;
200
+ viewportMargin?: number;
220
201
  collapsePrefixesOnLoad: boolean;
221
202
  syntaxErrorCheck: boolean;
222
203
  createShareableLink: ((yasqe: Yasqe) => string) | undefined | null;
@@ -224,7 +205,6 @@ export declare class Yasqe extends CodeMirror {
224
205
  consumeShareLink: ((yasqe: Yasqe) => void) | undefined | null;
225
206
  showQueryButton: boolean;
226
207
  pluginButtons: (() => HTMLElement[] | HTMLElement) | undefined;
227
- tabMode: string;
228
208
  autocompleters: string[];
229
209
  hintConfig: Partial<HintConfig>;
230
210
  resizeable: boolean;
@@ -241,49 +221,17 @@ export declare class Yasqe extends CodeMirror {
241
221
  name: string;
242
222
  } & Partial<Autocompleter.CompleterConfig>, enable?: boolean): void;
243
223
  }
244
- export type TokenizerState = sparql11Mode.State;
245
- export type Position = CodeMirror.Position;
246
- export type Token = CodeMirror.Token;
247
- export interface HintList {
248
- list: Hint[];
249
- from: Position;
250
- to: Position;
251
- }
252
- export interface Hint {
253
- text: string;
254
- displayText?: string;
255
- className?: string;
256
- render?: (el: HTMLElement, self: Hint, data: any) => void;
257
- from?: Position;
258
- to?: Position;
259
- }
260
- export type HintFn = {
261
- async?: boolean;
262
- } & (() => Promise<HintList> | HintList);
224
+ export type { TokenizerState, Position, Token } from "./editor/tokenizerRunner";
225
+ export type { Hint, HintList, HintFn } from "./editor/autocompletion";
226
+ export type { EditorOptions } from "./editor/facade";
227
+ export type { ExtraKeys } from "./editor/keymap";
263
228
  export interface HintConfig {
264
229
  completeOnSingleClick?: boolean;
265
230
  container?: HTMLElement;
266
231
  closeCharacters?: RegExp;
267
232
  completeSingle?: boolean;
268
- hint: HintFn;
269
233
  alignWithWord?: boolean;
270
234
  closeOnUnfocus?: boolean;
271
- customKeys?: any;
272
- extraKeys?: {
273
- [key: string]: (yasqe: Yasqe, event: {
274
- close: () => void;
275
- data: {
276
- from: Position;
277
- to: Position;
278
- list: Hint[];
279
- };
280
- length: number;
281
- menuSize: () => void;
282
- moveFocus: (movement: number) => void;
283
- pick: () => void;
284
- setFocus: (index: number) => void;
285
- }) => void;
286
- };
287
235
  }
288
236
  export interface BasicAuthConfig {
289
237
  username: string;
@@ -340,8 +288,9 @@ export interface Snippet {
340
288
  code: string;
341
289
  group?: string;
342
290
  }
343
- export interface Config extends Partial<CodeMirror.EditorConfiguration> {
291
+ export interface Config extends Omit<EditorOptions, "extraKeys"> {
344
292
  mode: string;
293
+ extraKeys: ExtraKeys<Yasqe>;
345
294
  collapsePrefixesOnLoad: boolean;
346
295
  syntaxErrorCheck: boolean;
347
296
  createShareableLink: ((yasqe: Yasqe) => string) | undefined | null;
@@ -352,12 +301,12 @@ export interface Config extends Partial<CodeMirror.EditorConfiguration> {
352
301
  showQueryButton: boolean;
353
302
  requestConfig: RequestConfig<Yasqe> | ((yasqe: Yasqe) => RequestConfig<Yasqe>);
354
303
  pluginButtons: (() => HTMLElement[] | HTMLElement) | undefined;
355
- highlightSelectionMatches: {
304
+ highlightSelectionMatches: boolean | {
356
305
  showToken?: RegExp;
357
306
  annotateScrollbar?: boolean;
358
307
  };
359
308
  tabMode: string;
360
- foldGutter: any;
309
+ foldGutter: boolean | object;
361
310
  matchBrackets: boolean;
362
311
  autocompleters: string[];
363
312
  hintConfig: Partial<HintConfig>;
@@ -9,8 +9,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import "./scss/yasqe.scss";
11
11
  import "./scss/buttons.scss";
12
+ import "./scss/codemirrorMods.scss";
12
13
  import "leaflet/dist/leaflet.css";
13
- import { findFirstPrefixLine } from "./prefixFold";
14
+ import { findFirstPrefixLine as findFirstPrefixLineInDoc, foldAt, unfoldAt } from "./editor/folding";
14
15
  import { getPrefixesFromQuery, addPrefixes, removePrefixes } from "./prefixUtils";
15
16
  import { getPreviousNonWsToken, getNextNonWsToken, getCompleteToken } from "./tokenUtils";
16
17
  import { Storage as YStorage } from "@matdata/yasgui-utils";
@@ -21,7 +22,9 @@ import * as Sparql from "./sparql";
21
22
  import * as Autocompleter from "./autocompleters";
22
23
  import { mergeWith, escape } from "lodash-es";
23
24
  import getDefaults from "./defaults";
24
- import CodeMirror from "./CodeMirror";
25
+ import { EditorFacade } from "./editor/facade";
26
+ import { runMode as runTokenizer } from "./editor/tokenizerRunner";
27
+ import { isCompletionActive, openCompletion, hideCompletion } from "./editor/autocompletion";
25
28
  import { spfmt } from "sparql-formatter";
26
29
  import * as L from "leaflet";
27
30
  import { coordinatesToWkt, wrapWktLiteral } from "./mapWidget";
@@ -29,9 +32,53 @@ const TOAST_DEFAULT_DURATION = 3000;
29
32
  const TOAST_WARNING_DURATION = 4000;
30
33
  const TOAST_WARNING_DELAY = 500;
31
34
  const TOAST_FADEOUT_DURATION = 300;
32
- export class Yasqe extends CodeMirror {
35
+ const EDITOR_OPTION_KEYS = [
36
+ "mode",
37
+ "value",
38
+ "lineNumbers",
39
+ "lineWrapping",
40
+ "readOnly",
41
+ "tabSize",
42
+ "indentUnit",
43
+ "indentWithTabs",
44
+ "theme",
45
+ "extraKeys",
46
+ "tabMode",
47
+ "foldGutter",
48
+ "gutters",
49
+ "matchBrackets",
50
+ "highlightSelectionMatches",
51
+ "autoCloseBrackets",
52
+ "fixedGutter",
53
+ "placeholder",
54
+ "autofocus",
55
+ "viewportMargin",
56
+ ];
57
+ function mergeConfig(conf) {
58
+ return mergeWith({}, Yasqe.defaults, conf, (_objValue, srcValue) => {
59
+ if (Array.isArray(srcValue)) {
60
+ return srcValue;
61
+ }
62
+ });
63
+ }
64
+ function createRootEl(parent) {
65
+ if (!parent)
66
+ throw new Error("No parent passed as argument. Dont know where to draw YASQE");
67
+ const rootEl = document.createElement("div");
68
+ rootEl.className = "yasqe";
69
+ parent.appendChild(rootEl);
70
+ return rootEl;
71
+ }
72
+ export class Yasqe extends EditorFacade {
33
73
  constructor(parent, conf = {}) {
34
- super();
74
+ const config = mergeConfig(conf);
75
+ const rootEl = createRootEl(parent);
76
+ const editorOptions = {};
77
+ for (const key of EDITOR_OPTION_KEYS) {
78
+ if (config[key] !== undefined)
79
+ editorOptions[key] = config[key];
80
+ }
81
+ super(rootEl, editorOptions);
35
82
  this.autocompleters = {};
36
83
  this.prevQueryValid = false;
37
84
  this.queryValid = true;
@@ -40,22 +87,70 @@ export class Yasqe extends CodeMirror {
40
87
  var _a, _b;
41
88
  (_b = (_a = this.config).consumeShareLink) === null || _b === void 0 ? void 0 : _b.call(_a, this);
42
89
  };
43
- this.notificationEls = {};
44
- if (!parent)
45
- throw new Error("No parent passed as argument. Dont know where to draw YASQE");
46
- this.rootEl = document.createElement("div");
47
- this.rootEl.className = "yasqe";
48
- parent.appendChild(this.rootEl);
49
- this.config = mergeWith({}, Yasqe.defaults, conf, (objValue, srcValue) => {
50
- if (Array.isArray(srcValue)) {
51
- return srcValue;
90
+ this.handleChange = () => {
91
+ this.checkSyntax();
92
+ this.checkConstructVariables();
93
+ this.updateQueryButton();
94
+ };
95
+ this.handleBlur = () => {
96
+ this.saveQuery();
97
+ };
98
+ this.handleChanges = () => {
99
+ this.checkSyntax();
100
+ this.checkConstructVariables();
101
+ this.updateQueryButton();
102
+ };
103
+ this.handleCursorActivity = () => {
104
+ this.autocomplete(true);
105
+ const cursor = this.getDoc().getCursor();
106
+ const token = this.getTokenAt(cursor);
107
+ if (token && token.type === "variable-3") {
108
+ this.showNotification("uri-describe-hint", "CTRL+click: find triples where URI is subject. CTRL+SHIFT+click: find triples where URI is object.");
52
109
  }
53
- });
54
- const cm = CodeMirror(this.rootEl, this.config);
55
- for (const key of Object.getOwnPropertyNames(Yasqe.prototype)) {
56
- cm[key] = Yasqe.prototype[key].bind(this);
57
- }
58
- Object.assign(this, CodeMirror.prototype, cm);
110
+ else {
111
+ this.hideNotification("uri-describe-hint");
112
+ }
113
+ };
114
+ this.handleQuery = (_yasqe, req, abortController) => {
115
+ this.req = req;
116
+ this.abortController = abortController;
117
+ this.updateQueryButton();
118
+ };
119
+ this.handleQueryResponse = (_yasqe, _response, duration) => {
120
+ this.lastQueryDuration = duration;
121
+ this.req = undefined;
122
+ this.updateQueryButton();
123
+ };
124
+ this.handleQueryAbort = (_yasqe, _req) => {
125
+ this.req = undefined;
126
+ this.updateQueryButton();
127
+ };
128
+ this.initDrag = () => {
129
+ document.documentElement.addEventListener("mousemove", this.doDrag, false);
130
+ document.documentElement.addEventListener("mouseup", this.stopDrag, false);
131
+ };
132
+ this.doDrag = (event) => {
133
+ this.getWrapperElement().style.height = this.calculateDragOffset(event, this.rootEl) + "px";
134
+ };
135
+ this.stopDrag = () => {
136
+ document.documentElement.removeEventListener("mousemove", this.doDrag, false);
137
+ document.documentElement.removeEventListener("mouseup", this.stopDrag, false);
138
+ this.emit("resize", this.getWrapperElement().style.height);
139
+ if (this.getStorageId() && this.persistentConfig) {
140
+ this.persistentConfig.editorHeight = this.getWrapperElement().style.height;
141
+ this.saveQuery();
142
+ }
143
+ this.refresh();
144
+ if (this.snippetsResizeHandler) {
145
+ this.snippetsResizeHandler();
146
+ }
147
+ };
148
+ this.notificationEls = {};
149
+ this.expandEditor = () => {
150
+ this.setSize(null, "100%");
151
+ };
152
+ this.rootEl = rootEl;
153
+ this.config = config;
59
154
  this.storage = new YStorage(Yasqe.storageNamespace);
60
155
  this.drawButtons();
61
156
  this.drawSnippetsBar();
@@ -107,43 +202,11 @@ export class Yasqe extends CodeMirror {
107
202
  this.collapsePrefixes(true);
108
203
  this.registerEventListeners();
109
204
  }
110
- handleChange() {
111
- this.checkSyntax();
112
- this.checkConstructVariables();
113
- this.updateQueryButton();
114
- }
115
- handleBlur() {
116
- this.saveQuery();
117
- }
118
- handleChanges() {
119
- this.checkSyntax();
120
- this.checkConstructVariables();
121
- this.updateQueryButton();
122
- }
123
- handleCursorActivity() {
124
- this.autocomplete(true);
125
- const cursor = this.getDoc().getCursor();
126
- const token = this.getTokenAt(cursor);
127
- if (token && token.type === "variable-3") {
128
- this.showNotification("uri-describe-hint", "Hold CTRL - left mouse click on URI to DESCRIBE");
129
- }
130
- else {
131
- this.hideNotification("uri-describe-hint");
132
- }
133
- }
134
- handleQuery(_yasqe, req, abortController) {
135
- this.req = req;
136
- this.abortController = abortController;
137
- this.updateQueryButton();
138
- }
139
- handleQueryResponse(_yasqe, _response, duration) {
140
- this.lastQueryDuration = duration;
141
- this.req = undefined;
142
- this.updateQueryButton();
143
- }
144
- handleQueryAbort(_yasqe, _req) {
145
- this.req = undefined;
146
- this.updateQueryButton();
205
+ getHintFn() {
206
+ var _a;
207
+ const hintFn = (_a = this.pendingHintFn) !== null && _a !== void 0 ? _a : this.buildHintFn(false);
208
+ this.pendingHintFn = undefined;
209
+ return hintFn;
147
210
  }
148
211
  registerEventListeners() {
149
212
  this.on("change", this.handleChange);
@@ -163,9 +226,6 @@ export class Yasqe extends CodeMirror {
163
226
  this.off("queryResponse", this.handleQueryResponse);
164
227
  this.off("queryAbort", this.handleQueryAbort);
165
228
  }
166
- emit(event, ...data) {
167
- CodeMirror.signal(this, event, this, ...data);
168
- }
169
229
  getStorageId(getter) {
170
230
  const persistenceId = getter || this.config.persistenceId;
171
231
  if (!persistenceId)
@@ -1179,10 +1239,6 @@ export class Yasqe extends CodeMirror {
1179
1239
  this.horizontalResizeWrapper.addEventListener("dblclick", this.expandEditor);
1180
1240
  this.rootEl.appendChild(this.horizontalResizeWrapper);
1181
1241
  }
1182
- initDrag() {
1183
- document.documentElement.addEventListener("mousemove", this.doDrag, false);
1184
- document.documentElement.addEventListener("mouseup", this.stopDrag, false);
1185
- }
1186
1242
  calculateDragOffset(event, rootEl) {
1187
1243
  let parentOffset = 0;
1188
1244
  if (rootEl.offsetParent)
@@ -1195,22 +1251,6 @@ export class Yasqe extends CodeMirror {
1195
1251
  }
1196
1252
  return event.clientY - parentOffset - this.rootEl.offsetTop + scrollOffset;
1197
1253
  }
1198
- doDrag(event) {
1199
- this.getWrapperElement().style.height = this.calculateDragOffset(event, this.rootEl) + "px";
1200
- }
1201
- stopDrag() {
1202
- document.documentElement.removeEventListener("mousemove", this.doDrag, false);
1203
- document.documentElement.removeEventListener("mouseup", this.stopDrag, false);
1204
- this.emit("resize", this.getWrapperElement().style.height);
1205
- if (this.getStorageId() && this.persistentConfig) {
1206
- this.persistentConfig.editorHeight = this.getWrapperElement().style.height;
1207
- this.saveQuery();
1208
- }
1209
- this.refresh();
1210
- if (this.snippetsResizeHandler) {
1211
- this.snippetsResizeHandler();
1212
- }
1213
- }
1214
1254
  duplicateLine() {
1215
1255
  const cur = this.getDoc().getCursor();
1216
1256
  if (cur) {
@@ -1405,10 +1445,7 @@ export class Yasqe extends CodeMirror {
1405
1445
  if (!this.getDoc().somethingSelected())
1406
1446
  this.execCommand("selectAll");
1407
1447
  const from = this.getDoc().getCursor("start");
1408
- var to = {
1409
- line: this.getDoc().getCursor("end").line,
1410
- ch: this.getDoc().getSelection().length,
1411
- };
1448
+ const to = this.getDoc().getCursor("end");
1412
1449
  var absStart = this.getDoc().indexFromPos(from);
1413
1450
  var absEnd = this.getDoc().indexFromPos(to);
1414
1451
  const res = this.autoformatSelection(absStart, absEnd);
@@ -1417,7 +1454,7 @@ export class Yasqe extends CodeMirror {
1417
1454
  var startLine = this.getDoc().posFromIndex(absStart).line;
1418
1455
  var endLine = this.getDoc().posFromIndex(absStart + res.length).line;
1419
1456
  for (var i = startLine; i <= endLine; i++) {
1420
- this.indentLine(i, "smart");
1457
+ this.indentLine(i);
1421
1458
  }
1422
1459
  });
1423
1460
  }
@@ -1508,6 +1545,7 @@ export class Yasqe extends CodeMirror {
1508
1545
  checkSyntax() {
1509
1546
  this.queryValid = true;
1510
1547
  this.clearGutter("gutterErrorBar");
1548
+ this.clearSyntaxErrorHighlight();
1511
1549
  var state;
1512
1550
  for (var l = 0; l < this.getDoc().lineCount(); ++l) {
1513
1551
  var precise = false;
@@ -1530,6 +1568,16 @@ export class Yasqe extends CodeMirror {
1530
1568
  }
1531
1569
  return;
1532
1570
  }
1571
+ const lineLength = this.getDoc().getLine(l).length;
1572
+ const startCh = typeof state.errorStartPos === "number"
1573
+ ? Math.max(0, Math.min(lineLength, state.errorStartPos))
1574
+ : Math.max(0, Math.min(lineLength, token.start));
1575
+ const fallbackEnd = token.string ? startCh + token.string.length : startCh + 1;
1576
+ const endCandidate = typeof state.errorEndPos === "number" ? state.errorEndPos : fallbackEnd;
1577
+ const endCh = Math.max(startCh + 1, Math.min(lineLength, endCandidate));
1578
+ if (endCh > startCh) {
1579
+ this.setSyntaxErrorHighlight({ line: l, ch: startCh }, { line: l, ch: endCh });
1580
+ }
1533
1581
  const errorEl = document.createElement("i");
1534
1582
  errorEl.className = "fas fa-exclamation-circle parseErrorIcon";
1535
1583
  if (state.errorMsg) {
@@ -1672,17 +1720,57 @@ export class Yasqe extends CodeMirror {
1672
1720
  autocomplete(fromAutoShow = false) {
1673
1721
  if (this.getDoc().somethingSelected())
1674
1722
  return;
1675
- for (let i in this.config.autocompleters) {
1676
- const autocompleter = this.autocompleters[this.config.autocompleters[i]];
1677
- if (!autocompleter || !autocompleter.autocomplete(fromAutoShow))
1723
+ const hintFn = this.buildHintFn(fromAutoShow);
1724
+ if (!hintFn)
1725
+ return;
1726
+ this.pendingHintFn = hintFn;
1727
+ openCompletion(this.view);
1728
+ }
1729
+ buildHintFn(fromAutoShow) {
1730
+ const hintFns = [];
1731
+ for (const name of this.config.autocompleters) {
1732
+ const autocompleter = this.autocompleters[name];
1733
+ if (!autocompleter)
1678
1734
  continue;
1735
+ const hintFn = autocompleter.autocomplete(fromAutoShow);
1736
+ if (hintFn)
1737
+ hintFns.push(hintFn);
1679
1738
  }
1739
+ if (hintFns.length === 0)
1740
+ return undefined;
1741
+ return () => __awaiter(this, void 0, void 0, function* () {
1742
+ const results = yield Promise.all(hintFns.map((fn) => fn()));
1743
+ let aggregated;
1744
+ for (const result of results) {
1745
+ if (!result || !result.list || result.list.length === 0)
1746
+ continue;
1747
+ if (!aggregated) {
1748
+ aggregated = { list: [...result.list], from: result.from, to: result.to };
1749
+ }
1750
+ else {
1751
+ aggregated.list.push(...result.list);
1752
+ }
1753
+ }
1754
+ return aggregated;
1755
+ });
1756
+ }
1757
+ isAutocompletionActive() {
1758
+ return isCompletionActive(this.view.state);
1759
+ }
1760
+ hideAutocompletion() {
1761
+ hideCompletion(this.view);
1680
1762
  }
1681
1763
  collapsePrefixes(collapse = true) {
1682
- const firstPrefixLine = findFirstPrefixLine(this);
1764
+ const firstPrefixLine = findFirstPrefixLineInDoc(this.runner, this.view.state.doc);
1683
1765
  if (firstPrefixLine === undefined)
1684
1766
  return;
1685
- this.foldCode(firstPrefixLine, CodeMirror.fold.prefix, collapse ? "fold" : "unfold");
1767
+ const offset = this.view.state.doc.line(firstPrefixLine + 1).from;
1768
+ if (collapse) {
1769
+ foldAt(this.view, offset);
1770
+ }
1771
+ else {
1772
+ unfoldAt(this.view, offset);
1773
+ }
1686
1774
  }
1687
1775
  getPrefixesFromQuery() {
1688
1776
  return getPrefixesFromQuery(this);
@@ -1694,12 +1782,6 @@ export class Yasqe extends CodeMirror {
1694
1782
  return removePrefixes(this, prefixes);
1695
1783
  }
1696
1784
  updateWidget() {
1697
- if (this.cursorCoords &&
1698
- this.state.completionActive &&
1699
- this.state.completionActive.widget) {
1700
- const newTop = this.cursorCoords(null).bottom;
1701
- this.state.completionActive.widget.hints.style.top = newTop + "px";
1702
- }
1703
1785
  }
1704
1786
  query(config) {
1705
1787
  var _a;
@@ -1754,9 +1836,6 @@ export class Yasqe extends CodeMirror {
1754
1836
  this.emit("queryAbort", this, this.req);
1755
1837
  }
1756
1838
  }
1757
- expandEditor() {
1758
- this.setSize(null, "100%");
1759
- }
1760
1839
  destroy() {
1761
1840
  var _a, _b, _c;
1762
1841
  this.abortQuery();
@@ -1772,6 +1851,7 @@ export class Yasqe extends CodeMirror {
1772
1851
  this.disableCompleter(autocompleter);
1773
1852
  }
1774
1853
  window.removeEventListener("hashchange", this.handleHashChange);
1854
+ this.destroyEditor();
1775
1855
  this.rootEl.remove();
1776
1856
  }
1777
1857
  static clearStorage() {
@@ -1798,10 +1878,9 @@ export class Yasqe extends CodeMirror {
1798
1878
  }
1799
1879
  Yasqe.storageNamespace = "triply";
1800
1880
  Yasqe.Sparql = Sparql;
1801
- Yasqe.runMode = CodeMirror.runMode;
1881
+ Yasqe.runMode = (text, _mode, callback) => runTokenizer(text, callback);
1802
1882
  Yasqe.Autocompleters = {};
1803
1883
  Yasqe.defaults = getDefaults();
1804
- Object.assign(CodeMirror.prototype, Yasqe.prototype);
1805
1884
  Autocompleter.completers.forEach((c) => {
1806
1885
  Yasqe.registerAutocompleter(c);
1807
1886
  });