Skip to content

Commit 46abded

Browse files
committed
Display lint context menu
1 parent 519f483 commit 46abded

3 files changed

Lines changed: 93 additions & 8 deletions

File tree

addon/hint/show-hint.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
cursor: pointer;
3131
}
3232

33+
.CodeMirror-hint:hover {
34+
background: #08f;
35+
color: white;
36+
}
37+
3338
li.CodeMirror-hint-active {
3439
background: #08f;
3540
color: white;

addon/lint/lint.js

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,58 @@
6969

7070
CodeMirror.on(node, "mouseout", hide);
7171
}
72+
73+
function showMenu (cm, annotations, e) {
74+
var target = e.target || e.srcElement;
75+
var state = cm.state.lint
76+
77+
if (!(state.options.menus && state.options.menus.length > 0)) {
78+
return
79+
}
80+
81+
/** @type {Array<{ content: string, html: string, onClick: any }>} */
82+
const menus = state.options.menus
83+
84+
// build menu
85+
var hints = document.createElement("ul");
86+
var theme = cm.options.theme;
87+
hints.className = "CodeMirror-hints " + theme;
88+
hints.style.position = 'fixed'
89+
hints.style.zIndex = '999'
90+
91+
for (let item of menus) {
92+
const elt = hints.appendChild(document.createElement('li'))
93+
elt.className = 'CodeMirror-hint'
94+
if (item.content) {
95+
elt.textContent = item.content
96+
} else {
97+
elt.innerHTML = item.html
98+
}
99+
const onClick = item.onClick
100+
elt.addEventListener('click', (e) => {
101+
onClick(e, annotations)
102+
remove()
103+
})
104+
}
105+
106+
function remove () {
107+
if (hints.parentNode) {
108+
hints.parentNode.removeChild(hints)
109+
}
110+
state.hints = null
111+
}
112+
113+
if (state.hints) {
114+
remove()
115+
}
116+
117+
state.hints = hints
118+
document.body.appendChild(hints)
119+
const { left, top } = target.getBoundingClientRect()
120+
121+
hints.style.top = top + 5 + 'px'
122+
hints.style.left = left + 20 + 'px'
123+
}
72124

73125
function LintState(cm, options, hasGutter) {
74126
this.marked = [];
@@ -94,7 +146,7 @@
94146
state.marked.length = 0;
95147
}
96148

97-
function makeMarker(cm, labels, severity, multiple, tooltips) {
149+
function makeMarker(cm, labels, severity, multiple, tooltips, annotations) {
98150
var marker = document.createElement("div"), inner = marker;
99151
marker.className = "CodeMirror-lint-marker-" + severity;
100152
if (multiple) {
@@ -106,6 +158,15 @@
106158
showTooltipFor(cm, e, labels, inner);
107159
});
108160

161+
if (cm.state.lint.options.contextmenu) {
162+
marker.addEventListener('click', function (e) {
163+
if (typeof cm.state.lint.options.onClick === 'function') {
164+
cm.state.lint.options.onClick(cm, e)
165+
}
166+
showMenu(cm, annotations, e)
167+
})
168+
}
169+
109170
return marker;
110171
}
111172

@@ -203,7 +264,7 @@
203264

204265
if (state.hasGutter)
205266
cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, anns.length > 1,
206-
state.options.tooltips));
267+
state.options.tooltips, anns));
207268
}
208269
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
209270
}
@@ -224,8 +285,8 @@
224285
}
225286
showTooltipFor(cm, e, tooltip, target);
226287
}
227-
228-
function onMouseOver(cm, e) {
288+
289+
function handleMarkerAction (cm, e, cb) {
229290
var target = e.target || e.srcElement;
230291
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
231292
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
@@ -245,9 +306,10 @@
245306
}
246307

247308
function onClick (cm, e) {
248-
handleMarkerAction(cm, e, function popupContextMenu (cm, annotations, e) {
249-
console.log(`WIP: click action, ${JSON.stringify(annotations)}`)
250-
})
309+
if (typeof cm.state.lint.options.onClick === 'function') {
310+
cm.state.lint.options.onClick(cm, e)
311+
}
312+
handleMarkerAction(cm, e, showMenu)
251313
}
252314

253315
CodeMirror.defineOption("lint", false, function(cm, val, old) {

demo/lint.html

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<link rel="stylesheet" href="../lib/codemirror.css">
88
<link rel="stylesheet" href="../addon/lint/lint.css">
9+
<link rel="stylesheet" href="../addon/hint/show-hint.css">
910
<script src="../lib/codemirror.js"></script>
1011
<script src="../mode/javascript/javascript.js"></script>
1112
<script src="../mode/css/css.js"></script>
@@ -164,7 +165,24 @@ <h2>Linter Demo</h2>
164165
lineNumbers: true,
165166
mode: "css",
166167
gutters: ["CodeMirror-lint-markers"],
167-
lint: true
168+
lint: {
169+
fixedTooltip: true,
170+
contextmenu: true,
171+
menus: [
172+
{
173+
content: 'Fix me',
174+
onClick (e, annotations) {
175+
console.log(annotations)
176+
}
177+
},
178+
{
179+
content: 'Another fixed me',
180+
onClick (e, annotations) {
181+
console.log(annotations)
182+
}
183+
}
184+
]
185+
}
168186
});
169187
</script>
170188

0 commit comments

Comments
 (0)