Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1426086
codemirror.gotoLine.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
codemirror.gotoLine.js
View Options
const
{
EditorSelection
,
EditorView
,
Prec
,
StateEffect
,
StateEffectType
,
StateField
,
keymap
,
showPanel
}
=
require
(
'ext.CodeMirror.v6.lib'
);
const
CodeMirrorPanel
=
require
(
'./codemirror.panel.js'
);
/**
* Custom goto line panel for CodeMirror using CSS-only Codex components.
*
* Using the Alt-g keybinding, this shows a panel asking the user for a line number,
* when a valid position is provided, moves the cursor to that line.
*
* This feature supports line numbers, relative line offsets prefixed with `+` or `-`,
* document percentages suffixed with `%`, and an optional column position by adding `:`
* and a second number after the line number.
*
* Based on the CodeMirror implementation (MIT).
*
* @see https://github.com/codemirror/search/blob/0d8af3e4cc/src/goto-line.ts
* @extends CodeMirrorPanel
*/
class
CodeMirrorGotoLine
extends
CodeMirrorPanel
{
constructor
()
{
super
();
/**
* @type {StateEffectType}
*/
this
.
toggleEffect
=
StateEffect
.
define
();
/**
* @type {StateField}
*/
this
.
panelStateField
=
StateField
.
define
(
{
create
:
()
=>
true
,
update
:
(
value
,
transaction
)
=>
{
for
(
const
e
of
transaction
.
effects
)
{
if
(
e
.
is
(
this
.
toggleEffect
)
)
{
value
=
e
.
value
;
}
}
return
value
;
},
// eslint-disable-next-line arrow-body-style
provide
:
(
stateField
)
=>
{
// eslint-disable-next-line arrow-body-style
return
showPanel
.
from
(
stateField
,
(
on
)
=>
{
return
on
?
()
=>
this
.
panel
:
null
;
}
);
}
}
);
/**
* @type {HTMLInputElement}
*/
this
.
input
=
undefined
;
}
/**
* @inheritDoc
*/
get
extension
()
{
// Use Prec.highest to ensure that this keymap is used before the default searchKeymap.
return
Prec
.
highest
(
keymap
.
of
(
{
key
:
'Mod-Alt-g'
,
run
:
(
view
)
=>
{
this
.
view
=
view
;
const
effects
=
[
this
.
toggleEffect
.
of
(
true
)
];
if
(
!
this
.
view
.
state
.
field
(
this
.
panelStateField
,
false
)
)
{
effects
.
push
(
StateEffect
.
appendConfig
.
of
(
[
this
.
panelStateField
]
)
);
}
this
.
view
.
dispatch
(
{
effects
}
);
return
true
;
}
}
)
);
}
/**
* @inheritDoc
*/
get
panel
()
{
const
container
=
document
.
createElement
(
'div'
);
container
.
className
=
'cm-mw-goto-line-panel cm-mw-panel cm-mw-panel--row'
;
container
.
addEventListener
(
'keydown'
,
this
.
onKeydown
.
bind
(
this
)
);
// Line input.
const
[
inputWrapper
,
input
]
=
this
.
getTextInput
(
'line'
,
this
.
line
);
this
.
input
=
input
;
container
.
appendChild
(
inputWrapper
);
// Go button.
const
button
=
this
.
getButton
(
'codemirror-goto-line-go'
);
button
.
addEventListener
(
'click'
,
this
.
go
.
bind
(
this
)
);
container
.
appendChild
(
button
);
return
{
dom
:
container
,
top
:
true
,
mount
:
()
=>
{
this
.
input
.
value
=
String
(
this
.
view
.
state
.
doc
.
lineAt
(
this
.
view
.
state
.
selection
.
main
.
head
).
number
);
this
.
input
.
focus
();
this
.
input
.
select
();
}
};
}
/**
* Respond to keydown events.
*
* @param {KeyboardEvent} event
*/
onKeydown
(
event
)
{
if
(
event
.
key
===
'Escape'
)
{
event
.
preventDefault
();
this
.
view
.
dispatch
(
{
effects
:
this
.
toggleEffect
.
of
(
false
)
}
);
this
.
view
.
focus
();
}
else
if
(
event
.
key
===
'Enter'
)
{
event
.
preventDefault
();
this
.
go
();
}
}
/**
* Go to the specified line.
*/
go
()
{
const
match
=
/^([+-])?(\d+)?(:\d+)?(%)?$/
.
exec
(
this
.
input
.
value
);
if
(
!
match
)
{
return
;
}
const
{
state
}
=
this
.
view
;
const
startLine
=
state
.
doc
.
lineAt
(
state
.
selection
.
main
.
head
);
const
[
,
sign
,
ln
,
cl
,
percent
]
=
match
;
const
col
=
cl
?
+
cl
.
slice
(
1
)
:
0
;
let
line
=
ln
?
+
ln
:
startLine
.
number
;
if
(
ln
&&
percent
)
{
let
pc
=
line
/
100
;
if
(
sign
)
{
pc
=
pc
*
(
sign
===
'-'
?
-
1
:
1
)
+
(
startLine
.
number
/
state
.
doc
.
lines
);
}
line
=
Math
.
round
(
state
.
doc
.
lines
*
pc
);
}
else
if
(
ln
&&
sign
)
{
line
=
line
*
(
sign
===
'-'
?
-
1
:
1
)
+
startLine
.
number
;
}
const
docLine
=
state
.
doc
.
line
(
Math
.
max
(
1
,
Math
.
min
(
state
.
doc
.
lines
,
line
)
)
);
const
selection
=
EditorSelection
.
cursor
(
docLine
.
from
+
Math
.
max
(
0
,
Math
.
min
(
col
,
docLine
.
length
)
)
);
this
.
view
.
dispatch
(
{
effects
:
[
this
.
toggleEffect
.
of
(
false
),
EditorView
.
scrollIntoView
(
selection
.
from
,
{
y
:
'center'
}
)
],
selection
}
);
this
.
view
.
focus
();
}
}
module
.
exports
=
CodeMirrorGotoLine
;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 16, 12:32 (15 h, 19 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9e/cd/1ef7c2fb78c7446ff1f2b10fb55f
Default Alt Text
codemirror.gotoLine.js (4 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment