Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F2751530
codemirror.textSelection.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
codemirror.textSelection.js
View Options
const
{
EditorSelection
,
EditorView
}
=
require
(
'ext.CodeMirror.v6.lib'
);
/**
* [jQuery.textSelection]{@link jQuery.fn.textSelection} implementation for CodeMirror.
* This is registered to both the textarea and the `.cm-editor` element.
*
* @see jQuery.fn.textSelection
*/
class
CodeMirrorTextSelection
{
/**
* @constructor
* @param {EditorView} view
*/
constructor
(
view
)
{
/**
* The CodeMirror view.
*
* @type {EditorView}
*/
this
.
view
=
view
;
/**
* The CodeMirror DOM.
*
* @type {jQuery}
*/
this
.
$cmDom
=
$
(
view
.
dom
);
}
/**
* Get the contents of the editor.
*
* @return {string}
* @stable to call
*/
getContents
()
{
return
this
.
view
.
state
.
doc
.
toString
();
}
/**
* Set the contents of the editor.
*
* @param {string} content
* @return {jQuery}
* @stable to call
*/
setContents
(
content
)
{
this
.
view
.
dispatch
(
{
changes
:
{
from
:
0
,
to
:
this
.
view
.
state
.
doc
.
length
,
insert
:
content
}
}
);
return
this
.
$cmDom
;
}
/**
* Get the current caret position.
*
* @param {Object} [options]
* @param {boolean} [options.startAndEnd] Whether to return the start and end of the selection
* instead of the caret position.
* @return {number[]|number}
* @stable to call
*/
getCaretPosition
(
options
)
{
if
(
!
options
.
startAndEnd
)
{
return
this
.
view
.
state
.
selection
.
main
.
head
;
}
return
[
this
.
view
.
state
.
selection
.
main
.
from
,
this
.
view
.
state
.
selection
.
main
.
to
];
}
/**
* Scroll the editor to the current caret position.
*
* @return {jQuery}
* @stable to call
*/
scrollToCaretPosition
()
{
const
scrollEffect
=
EditorView
.
scrollIntoView
(
this
.
view
.
state
.
selection
.
main
.
head
);
scrollEffect
.
value
.
isSnapshot
=
true
;
this
.
view
.
dispatch
(
{
effects
:
scrollEffect
}
);
return
this
.
$cmDom
;
}
/**
* Get the selected text.
*
* @return {string}
* @stable to call
*/
getSelection
()
{
return
this
.
view
.
state
.
sliceDoc
(
this
.
view
.
state
.
selection
.
main
.
from
,
this
.
view
.
state
.
selection
.
main
.
to
);
}
/**
* Set the selected text.
*
* @param {Object} options
* @param {number} options.start The start of the selection.
* @param {number} [options.end=options.start] The end of the selection.
* @return {jQuery}
* @stable to call
*/
setSelection
(
options
)
{
this
.
view
.
dispatch
(
{
selection
:
{
anchor
:
options
.
start
,
head
:
(
options
.
end
||
options
.
start
)
}
}
);
this
.
view
.
focus
();
return
this
.
$cmDom
;
}
/**
* Replace the selected text with the given value.
*
* @param {string} value
* @return {jQuery}
* @stable to call
*/
replaceSelection
(
value
)
{
this
.
view
.
dispatch
(
this
.
view
.
state
.
replaceSelection
(
value
)
);
return
this
.
$cmDom
;
}
/**
* Encapsulate the selected text with the given values.
*
* This is intentionally a near-identical implementation to jQuery.textSelection,
* except it uses CodeMirror's
* [EditorState.changeByRange](https://codemirror.net/docs/ref/#state.EditorState.changeByRange)
* when there are multiple selections.
*
* @todo Add support for 'ownline' and 'splitlines' options.
*
* @param {Object} options
* @param {string} [options.pre] The text to insert before the cursor/selection.
* @param {string} [options.post] The text to insert after the cursor/selection.
* @param {string} [options.peri] Text to insert between pre and post and select afterwards.
* @param {boolean} [options.replace=false] If there is a selection, replace it with peri
* instead of leaving it alone.
* @param {boolean} [options.selectPeri=true] Select the peri text if it was inserted.
* @param {number} [options.selectionStart] Position to start selection at.
* @param {number} [options.selectionEnd=options.selectionStart] Position to end selection at.
* @return {jQuery}
* @stable to call
*/
encapsulateSelection
(
options
)
{
let
selectedText
,
isSample
=
false
;
const
checkSelectedText
=
()
=>
{
if
(
!
selectedText
)
{
selectedText
=
options
.
peri
;
isSample
=
true
;
}
else
if
(
options
.
replace
)
{
selectedText
=
options
.
peri
;
}
else
{
while
(
selectedText
.
charAt
(
selectedText
.
length
-
1
)
===
' '
)
{
// Exclude ending space char
selectedText
=
selectedText
.
slice
(
0
,
-
1
);
options
.
post
+=
' '
;
}
while
(
selectedText
.
charAt
(
0
)
===
' '
)
{
// Exclude prepending space char
selectedText
=
selectedText
.
slice
(
1
);
options
.
pre
=
' '
+
options
.
pre
;
}
}
};
this
.
view
.
focus
();
// Set the selection, if applicable.
if
(
options
.
selectionStart
!==
undefined
)
{
this
.
setSelection
(
{
start
:
options
.
selectionStart
,
end
:
options
.
selectionEnd
||
options
.
selectionStart
}
);
}
selectedText
=
this
.
getSelection
();
const
[
startPos
]
=
this
.
getCaretPosition
(
{
startAndEnd
:
true
}
);
checkSelectedText
();
const
insertText
=
options
.
pre
+
selectedText
+
options
.
post
;
/**
* Use CodeMirror's API when there are multiple selections.
*
* @see https://codemirror.net/examples/change/
*/
if
(
this
.
view
.
state
.
selection
.
ranges
.
length
>
1
)
{
this
.
view
.
dispatch
(
this
.
view
.
state
.
changeByRange
(
(
range
)
=>
(
{
changes
:
[
{
from
:
range
.
from
,
insert
:
options
.
pre
},
{
from
:
range
.
to
,
insert
:
options
.
post
}
],
range
:
EditorSelection
.
range
(
range
.
to
+
options
.
pre
.
length
+
options
.
post
.
length
,
range
.
to
+
options
.
pre
.
length
+
options
.
post
.
length
)
}
)
)
);
return
this
.
$cmDom
;
}
this
.
replaceSelection
(
insertText
);
if
(
isSample
&&
options
.
selectPeri
)
{
this
.
setSelection
(
{
start
:
startPos
+
options
.
pre
.
length
,
end
:
startPos
+
options
.
pre
.
length
+
selectedText
.
length
}
);
}
else
{
this
.
setSelection
(
{
start
:
startPos
+
insertText
.
length
}
);
}
return
this
.
$cmDom
;
}
}
module
.
exports
=
CodeMirrorTextSelection
;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 3, 18:45 (1 d, 16 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4c/f1/ec75bd88163a57aa71fbe2a09965
Default Alt Text
codemirror.textSelection.js (5 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment