chrome-devtools-frontend 1.0.930109 → 1.0.930993
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.
- package/config/gni/devtools_grd_files.gni +2 -1
- package/front_end/core/host/InspectorFrontendHost.ts +8 -1
- package/front_end/core/host/InspectorFrontendHostAPI.ts +12 -0
- package/front_end/core/i18n/locales/en-US.json +3 -0
- package/front_end/core/i18n/locales/en-XL.json +3 -0
- package/front_end/core/protocol_client/InspectorBackend.ts +71 -71
- package/front_end/core/sdk/NetworkManager.ts +6 -2
- package/front_end/devtools_compatibility.js +8 -0
- package/front_end/legacy_test_runner/sources_test_runner/DebuggerTestRunner.js +2 -2
- package/front_end/legacy_test_runner/test_runner/TestRunner.js +2 -3
- package/front_end/models/bindings/BreakpointManager.ts +158 -154
- package/front_end/models/bindings/CSSWorkspaceBinding.ts +64 -56
- package/front_end/models/bindings/CompilerScriptMapping.ts +70 -70
- package/front_end/models/bindings/ContentProviderBasedProject.ts +20 -20
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +132 -132
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +73 -72
- package/front_end/models/bindings/DefaultScriptMapping.ts +22 -22
- package/front_end/models/bindings/FileUtils.ts +81 -81
- package/front_end/models/bindings/IgnoreListManager.ts +17 -17
- package/front_end/models/bindings/LiveLocation.ts +21 -21
- package/front_end/models/bindings/PresentationConsoleMessageHelper.ts +28 -28
- package/front_end/models/bindings/ResourceMapping.ts +50 -50
- package/front_end/models/bindings/ResourceScriptMapping.ts +71 -71
- package/front_end/models/bindings/SASSSourceMapping.ts +32 -32
- package/front_end/models/bindings/StylesSourceMapping.ts +57 -57
- package/front_end/models/bindings/TempFile.ts +34 -34
- package/front_end/models/emulation/DeviceModeModel.ts +208 -203
- package/front_end/models/emulation/EmulatedDevices.ts +34 -34
- package/front_end/panels/console/ConsoleView.ts +2 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +3 -3
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +133 -133
- package/front_end/panels/css_overview/CSSOverviewModel.ts +16 -16
- package/front_end/panels/css_overview/CSSOverviewPanel.ts +77 -77
- package/front_end/panels/css_overview/CSSOverviewProcessingView.ts +5 -5
- package/front_end/panels/css_overview/components/CSSOverviewStartView.ts +4 -4
- package/front_end/panels/elements/ElementsTreeElement.ts +6 -10
- package/front_end/panels/elements/ElementsTreeOutline.ts +3 -1
- package/front_end/panels/elements/components/LayoutPane.ts +6 -0
- package/front_end/panels/elements/elementsPanel.css +0 -1
- package/front_end/panels/elements/elementsTreeOutline.css +0 -4
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +7 -2
- package/front_end/panels/network/BlockedURLsPane.ts +8 -5
- package/front_end/panels/network/blockedURLsPane.css +0 -1
- package/front_end/panels/search/SearchView.ts +0 -2
- package/front_end/panels/sources/BreakpointEditDialog.ts +98 -81
- package/front_end/panels/sources/DebuggerPlugin.ts +15 -14
- package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +18 -2
- package/front_end/ui/components/text_editor/config.ts +6 -0
- package/front_end/ui/components/text_editor/cursor_tooltip.ts +70 -0
- package/front_end/ui/components/text_editor/javascript.ts +590 -0
- package/front_end/ui/components/text_editor/text_editor.ts +1 -0
- package/front_end/ui/components/text_editor/theme.ts +11 -0
- package/front_end/ui/components/tree_outline/TreeOutline.ts +3 -1
- package/front_end/ui/legacy/ARIAUtils.ts +24 -8
- package/front_end/ui/legacy/components/text_editor/cmdevtools.css +1 -0
- package/front_end/ui/legacy/components/text_editor/text_editor-legacy.ts +0 -3
- package/front_end/ui/legacy/components/text_editor/text_editor.ts +0 -2
- package/package.json +1 -1
- package/scripts/migration/class-fields/migrate.js +15 -2
- package/scripts/migration/class-fields/migrate.sh +10 -0
- package/front_end/ui/legacy/components/text_editor/SyntaxHighlighter.ts +0 -62
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
6
|
+
import type * as TextEditor from '../../ui/components/text_editor/text_editor.js';
|
|
7
|
+
import type * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
|
|
8
8
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
9
9
|
|
|
10
10
|
import breakpointEditDialogStyles from './breakpointEditDialog.css.js';
|
|
@@ -48,25 +48,51 @@ const UIStrings = {
|
|
|
48
48
|
};
|
|
49
49
|
const str_ = i18n.i18n.registerUIStrings('panels/sources/BreakpointEditDialog.ts', UIStrings);
|
|
50
50
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
51
|
+
|
|
51
52
|
export class BreakpointEditDialog extends UI.Widget.Widget {
|
|
52
53
|
private readonly onFinish: (arg0: {
|
|
53
54
|
committed: boolean,
|
|
54
55
|
condition: string,
|
|
55
56
|
}) => Promise<void>;
|
|
56
57
|
private finished: boolean;
|
|
57
|
-
private editor: TextEditor.
|
|
58
|
+
private editor: TextEditor.TextEditor.TextEditor;
|
|
58
59
|
private isLogpoint: boolean;
|
|
59
60
|
private readonly typeSelector: UI.Toolbar.ToolbarComboBox;
|
|
61
|
+
private placeholderCompartment: CodeMirror.Compartment;
|
|
62
|
+
|
|
63
|
+
static async create(
|
|
64
|
+
editorLineNumber: number,
|
|
65
|
+
oldCondition: string,
|
|
66
|
+
preferLogpoint: boolean,
|
|
67
|
+
onFinish: (arg0: {committed: boolean, condition: string}) => Promise<void>,
|
|
68
|
+
): Promise<BreakpointEditDialog> {
|
|
69
|
+
const TextEditor = await import('../../ui/components/text_editor/text_editor.js');
|
|
70
|
+
const CodeMirror = await import('../../third_party/codemirror.next/codemirror.next.js');
|
|
71
|
+
const editorConfig = [
|
|
72
|
+
(await CodeMirror.javascript()).javascriptLanguage,
|
|
73
|
+
TextEditor.Config.baseConfiguration(oldCondition || ''),
|
|
74
|
+
CodeMirror.EditorView.lineWrapping,
|
|
75
|
+
TextEditor.Config.showCompletionHint,
|
|
76
|
+
await TextEditor.JavaScript.completion(),
|
|
77
|
+
TextEditor.JavaScript.argumentHints(),
|
|
78
|
+
];
|
|
79
|
+
return new BreakpointEditDialog(
|
|
80
|
+
editorLineNumber, oldCondition, preferLogpoint, onFinish, TextEditor, CodeMirror, editorConfig);
|
|
81
|
+
}
|
|
60
82
|
|
|
61
|
-
constructor(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
constructor(
|
|
84
|
+
editorLineNumber: number,
|
|
85
|
+
oldCondition: string,
|
|
86
|
+
preferLogpoint: boolean,
|
|
87
|
+
onFinish: (arg0: {committed: boolean, condition: string}) => Promise<void>,
|
|
88
|
+
modTextEditor: typeof TextEditor,
|
|
89
|
+
readonly modCodeMirror: typeof CodeMirror,
|
|
90
|
+
editorConfig: CodeMirror.Extension,
|
|
91
|
+
) {
|
|
65
92
|
super(true);
|
|
66
93
|
|
|
67
94
|
this.onFinish = onFinish;
|
|
68
95
|
this.finished = false;
|
|
69
|
-
this.editor = null;
|
|
70
96
|
this.element.tabIndex = -1;
|
|
71
97
|
|
|
72
98
|
const logpointPrefix = LogpointPrefix;
|
|
@@ -90,113 +116,104 @@ export class BreakpointEditDialog extends UI.Widget.Widget {
|
|
|
90
116
|
this.typeSelector.select(this.isLogpoint ? logpointOption : conditionalOption);
|
|
91
117
|
toolbar.appendToolbarItem(this.typeSelector);
|
|
92
118
|
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.editor.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
const content = oldCondition || '';
|
|
120
|
+
const keymap = [
|
|
121
|
+
{
|
|
122
|
+
key: 'Mod-Enter',
|
|
123
|
+
run: (view: CodeMirror.EditorView): boolean => {
|
|
124
|
+
if (modTextEditor.JavaScript.isExpressionComplete(view.state)) {
|
|
125
|
+
this.finishEditing(true, this.editor.state.doc.toString());
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
key: 'Escape',
|
|
133
|
+
run: (): boolean => {
|
|
134
|
+
this.finishEditing(false, '');
|
|
135
|
+
return true;
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
this.placeholderCompartment = new modCodeMirror.Compartment();
|
|
141
|
+
|
|
142
|
+
this.editor = new modTextEditor.TextEditor.TextEditor(modCodeMirror.EditorState.create({
|
|
143
|
+
doc: content,
|
|
144
|
+
selection: {anchor: 0, head: content.length},
|
|
145
|
+
extensions: [
|
|
146
|
+
this.placeholderCompartment.of(this.getPlaceholder()),
|
|
147
|
+
modCodeMirror.keymap.of(keymap),
|
|
148
|
+
editorConfig,
|
|
149
|
+
],
|
|
150
|
+
}));
|
|
151
|
+
this.editor.classList.add('condition-editor');
|
|
152
|
+
|
|
153
|
+
this.updateTooltip();
|
|
154
|
+
this.contentElement.appendChild(this.editor);
|
|
119
155
|
this.element.addEventListener('blur', event => {
|
|
120
156
|
if (!event.relatedTarget ||
|
|
121
157
|
(event.relatedTarget && !(event.relatedTarget as Node).isSelfOrDescendant(this.element))) {
|
|
122
|
-
this.finishEditing(true);
|
|
158
|
+
this.finishEditing(true, this.editor.state.doc.toString());
|
|
123
159
|
}
|
|
124
160
|
}, true);
|
|
125
161
|
}
|
|
126
162
|
|
|
127
163
|
focusEditor(): void {
|
|
128
|
-
|
|
129
|
-
this.editor.widget().focus();
|
|
130
|
-
}
|
|
164
|
+
this.editor.editor.focus();
|
|
131
165
|
}
|
|
132
166
|
private static conditionForLogpoint(condition: string): string {
|
|
133
167
|
return `${LogpointPrefix}${condition}${LogpointSuffix}`;
|
|
134
168
|
}
|
|
135
169
|
|
|
136
170
|
private onTypeChanged(): void {
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
this.updatePlaceholder();
|
|
144
|
-
if (value === BreakpointType.Breakpoint) {
|
|
145
|
-
this.editor.setText('');
|
|
146
|
-
this.finishEditing(true);
|
|
171
|
+
const type = this.breakpointType;
|
|
172
|
+
if (type === BreakpointType.Breakpoint) {
|
|
173
|
+
this.finishEditing(true, '');
|
|
174
|
+
} else {
|
|
175
|
+
this.editor.editor.dispatch({effects: this.placeholderCompartment.reconfigure(this.getPlaceholder())});
|
|
176
|
+
this.updateTooltip();
|
|
147
177
|
}
|
|
148
178
|
}
|
|
149
179
|
|
|
150
|
-
private
|
|
180
|
+
private get breakpointType(): string|null {
|
|
151
181
|
const option = this.typeSelector.selectedOption();
|
|
152
|
-
|
|
153
|
-
|
|
182
|
+
return option ? option.value : null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private getPlaceholder(): CodeMirror.Extension {
|
|
186
|
+
const type = this.breakpointType;
|
|
187
|
+
if (type === BreakpointType.Conditional) {
|
|
188
|
+
return this.modCodeMirror.placeholder(i18nString(UIStrings.expressionToCheckBeforePausingEg));
|
|
189
|
+
}
|
|
190
|
+
if (type === BreakpointType.Logpoint) {
|
|
191
|
+
return this.modCodeMirror.placeholder(i18nString(UIStrings.logMessageEgXIsX));
|
|
154
192
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private updateTooltip(): void {
|
|
197
|
+
const type = this.breakpointType;
|
|
198
|
+
if (type === BreakpointType.Conditional) {
|
|
158
199
|
UI.Tooltip.Tooltip.install((this.typeSelector.element), i18nString(UIStrings.pauseOnlyWhenTheConditionIsTrue));
|
|
159
|
-
} else if (
|
|
160
|
-
this.editor.setPlaceholder(i18nString(UIStrings.logMessageEgXIsX));
|
|
200
|
+
} else if (type === BreakpointType.Logpoint) {
|
|
161
201
|
UI.Tooltip.Tooltip.install((this.typeSelector.element), i18nString(UIStrings.logAMessageToConsoleDoNotBreak));
|
|
162
202
|
}
|
|
163
203
|
}
|
|
164
204
|
|
|
165
|
-
private finishEditing(committed: boolean): void {
|
|
205
|
+
private finishEditing(committed: boolean, condition: string): void {
|
|
166
206
|
if (this.finished) {
|
|
167
207
|
return;
|
|
168
208
|
}
|
|
169
209
|
this.finished = true;
|
|
170
|
-
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
this.editor.widget().detach();
|
|
174
|
-
let condition = this.editor.text();
|
|
210
|
+
this.editor.remove();
|
|
175
211
|
if (this.isLogpoint) {
|
|
176
212
|
condition = BreakpointEditDialog.conditionForLogpoint(condition);
|
|
177
213
|
}
|
|
178
214
|
this.onFinish({committed, condition});
|
|
179
215
|
}
|
|
180
216
|
|
|
181
|
-
private async onKeyDown(event: Event): Promise<void> {
|
|
182
|
-
if (!(event instanceof KeyboardEvent) || !this.editor) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
|
186
|
-
event.consume(true);
|
|
187
|
-
const expression = this.editor.text();
|
|
188
|
-
if (event.ctrlKey ||
|
|
189
|
-
await ObjectUI.JavaScriptAutocomplete.JavaScriptAutocomplete.isExpressionComplete(expression)) {
|
|
190
|
-
this.finishEditing(true);
|
|
191
|
-
} else {
|
|
192
|
-
this.editor.newlineAndIndent();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
if (isEscKey(event)) {
|
|
196
|
-
this.finishEditing(false);
|
|
197
|
-
event.stopImmediatePropagation();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
217
|
wasShown(): void {
|
|
201
218
|
super.wasShown();
|
|
202
219
|
this.registerCSSFiles([breakpointEditDialogStyles]);
|
|
@@ -899,20 +899,21 @@ export class DebuggerPlugin extends Plugin {
|
|
|
899
899
|
preferLogpoint?: boolean): Promise<void> {
|
|
900
900
|
const oldCondition = breakpoint ? breakpoint.condition() : '';
|
|
901
901
|
const decorationElement = document.createElement('div');
|
|
902
|
-
const dialog =
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
902
|
+
const dialog =
|
|
903
|
+
await BreakpointEditDialog.create(editorLineNumber, oldCondition, Boolean(preferLogpoint), async result => {
|
|
904
|
+
dialog.detach();
|
|
905
|
+
this.textEditor.removeDecoration(decorationElement, editorLineNumber);
|
|
906
|
+
if (!result.committed) {
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
if (breakpoint) {
|
|
910
|
+
breakpoint.setCondition(result.condition);
|
|
911
|
+
} else if (location) {
|
|
912
|
+
await this.setBreakpoint(location.lineNumber, location.columnNumber, result.condition, true);
|
|
913
|
+
} else {
|
|
914
|
+
await this.createNewBreakpoint(editorLineNumber, result.condition, true);
|
|
915
|
+
}
|
|
916
|
+
});
|
|
916
917
|
this.textEditor.addDecoration(decorationElement, editorLineNumber);
|
|
917
918
|
dialog.markAsExternallyManaged();
|
|
918
919
|
dialog.show(decorationElement);
|
|
@@ -37,8 +37,8 @@ export function getHighlightStyle(modCM: typeof CodeMirror): CodeMirror.Highligh
|
|
|
37
37
|
|
|
38
38
|
{tag: t.inserted, class: 'token-inserted'},
|
|
39
39
|
{tag: t.deleted, class: 'token-deleted'},
|
|
40
|
-
{tag: t.heading, class: 'token-
|
|
41
|
-
{tag: t.link, class: 'token-
|
|
40
|
+
{tag: t.heading, class: 'token-heading'},
|
|
41
|
+
{tag: t.link, class: 'token-link'},
|
|
42
42
|
{tag: t.strikethrough, class: 'token-strikethrough'},
|
|
43
43
|
{tag: t.strong, class: 'token-strong'},
|
|
44
44
|
{tag: t.emphasis, class: 'token-emphasis'},
|
|
@@ -54,6 +54,22 @@ export async function create(code: string, mimeType: string): Promise<CodeHighli
|
|
|
54
54
|
return new CodeHighlighter(code, tree, CM);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
export async function highlightNode(node: Element, mimeType: string): Promise<void> {
|
|
58
|
+
const code = node.textContent || '';
|
|
59
|
+
const highlighter = await create(code, mimeType);
|
|
60
|
+
node.removeChildren();
|
|
61
|
+
highlighter.highlight((text, style) => {
|
|
62
|
+
let token: Node = document.createTextNode(text);
|
|
63
|
+
if (style) {
|
|
64
|
+
const span = document.createElement('span');
|
|
65
|
+
span.className = style;
|
|
66
|
+
span.appendChild(token);
|
|
67
|
+
token = span;
|
|
68
|
+
}
|
|
69
|
+
node.appendChild(token);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
57
73
|
export async function languageFromMIME(mimeType: string): Promise<CodeMirror.LanguageSupport|null> {
|
|
58
74
|
const CM = await importCM();
|
|
59
75
|
|
|
@@ -57,8 +57,12 @@ export const tabMovesFocus = DynamicSetting.bool('textEditorTabMovesFocus', CM.k
|
|
|
57
57
|
shift: (view: CM.EditorView): boolean => view.state.doc.length ? CM.indentLess(view) : false,
|
|
58
58
|
}]));
|
|
59
59
|
|
|
60
|
+
export const autocompletion = DynamicSetting.bool('textEditorAutocompletion', CM.autocompletion());
|
|
61
|
+
|
|
60
62
|
export const bracketMatching = DynamicSetting.bool('textEditorBracketMatching', CM.bracketMatching());
|
|
61
63
|
|
|
64
|
+
export const codeFolding = DynamicSetting.bool('textEditorCodeFolding', [CM.foldGutter(), CM.keymap.of(CM.foldKeymap)]);
|
|
65
|
+
|
|
62
66
|
export function guessIndent(doc: CM.Text): string {
|
|
63
67
|
const values: {[indent: string]: number} = Object.create(null);
|
|
64
68
|
let scanned = 0;
|
|
@@ -160,6 +164,7 @@ function detectLineSeparator(text: string): CM.Extension {
|
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
const baseKeymap = CM.keymap.of([
|
|
167
|
+
{key: 'Tab', run: CM.acceptCompletion},
|
|
163
168
|
{key: 'Ctrl-m', run: CM.cursorMatchingBracket, shift: CM.selectMatchingBracket},
|
|
164
169
|
{key: 'Mod-/', run: CM.toggleComment},
|
|
165
170
|
{key: 'Mod-d', run: CM.selectNextOccurrence},
|
|
@@ -194,6 +199,7 @@ export function baseConfiguration(text: string): CM.Extension {
|
|
|
194
199
|
indentUnit,
|
|
195
200
|
CM.Prec.fallback(CM.EditorView.contentAttributes.of({'aria-label': i18nString(UIStrings.codeEditor)})),
|
|
196
201
|
detectLineSeparator(text),
|
|
202
|
+
autocompletion,
|
|
197
203
|
CM.tooltips({position: 'absolute'}),
|
|
198
204
|
];
|
|
199
205
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright 2021 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import * as CodeMirror from '../../../third_party/codemirror.next/codemirror.next.js';
|
|
6
|
+
|
|
7
|
+
export function cursorTooltip(
|
|
8
|
+
source: (state: CodeMirror.EditorState, pos: number) => Promise<(() => CodeMirror.TooltipView)|null>,
|
|
9
|
+
): CodeMirror.Extension {
|
|
10
|
+
const openTooltip = CodeMirror.StateEffect.define<() => CodeMirror.TooltipView>();
|
|
11
|
+
|
|
12
|
+
const state = CodeMirror.StateField.define<null|CodeMirror.Tooltip>({
|
|
13
|
+
create() {
|
|
14
|
+
return null;
|
|
15
|
+
},
|
|
16
|
+
update(val, tr) {
|
|
17
|
+
if (tr.selection) {
|
|
18
|
+
val = null;
|
|
19
|
+
}
|
|
20
|
+
if (val && !tr.changes.empty) {
|
|
21
|
+
val = {pos: tr.changes.mapPos(val.pos), create: val.create, above: true};
|
|
22
|
+
}
|
|
23
|
+
for (const effect of tr.effects) {
|
|
24
|
+
if (effect.is(openTooltip)) {
|
|
25
|
+
val = {pos: tr.state.selection.main.from, create: effect.value, above: true};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return val;
|
|
29
|
+
},
|
|
30
|
+
provide: field => CodeMirror.showTooltip.from(field),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const plugin = CodeMirror.ViewPlugin.fromClass(class {
|
|
34
|
+
pending = -1;
|
|
35
|
+
updateID = 0;
|
|
36
|
+
|
|
37
|
+
update(update: CodeMirror.ViewUpdate): void {
|
|
38
|
+
this.updateID++;
|
|
39
|
+
if (update.transactions.some(tr => tr.selection) && update.state.selection.main.empty) {
|
|
40
|
+
this.scheduleUpdate(update.view);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
scheduleUpdate(view: CodeMirror.EditorView): void {
|
|
45
|
+
if (this.pending > -1) {
|
|
46
|
+
clearTimeout(this.pending);
|
|
47
|
+
}
|
|
48
|
+
this.pending = setTimeout(() => this.startUpdate(view), 50) as unknown as number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
startUpdate(view: CodeMirror.EditorView): void {
|
|
52
|
+
this.pending = -1;
|
|
53
|
+
const {main} = view.state.selection;
|
|
54
|
+
if (main.empty) {
|
|
55
|
+
const {updateID} = this;
|
|
56
|
+
source(view.state, main.from).then(tooltip => {
|
|
57
|
+
if (this.updateID !== updateID) {
|
|
58
|
+
if (this.pending < 0) {
|
|
59
|
+
this.scheduleUpdate(view);
|
|
60
|
+
}
|
|
61
|
+
} else if (tooltip) {
|
|
62
|
+
view.dispatch({effects: openTooltip.of(tooltip)});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return [state, plugin];
|
|
70
|
+
}
|