aboutsummaryrefslogtreecommitdiff
path: root/xP/public/xP.js
diff options
context:
space:
mode:
Diffstat (limited to 'xP/public/xP.js')
-rw-r--r--xP/public/xP.js82
1 files changed, 58 insertions, 24 deletions
diff --git a/xP/public/xP.js b/xP/public/xP.js
index ae6dd28..3266063 100644
--- a/xP/public/xP.js
+++ b/xP/public/xP.js
@@ -687,34 +687,25 @@ let BufferContainer = {
}
let Toolbar = {
- insert: formatting => {
+ format: formatting => {
let textarea = document.getElementById('input')
- if (textarea === null)
- return
-
- const [start, end] = [textarea.selectionStart, textarea.selectionEnd]
- if (start === end) {
- textarea.setRangeText(formatting)
- textarea.setSelectionRange(
- start + formatting.length, end + formatting.length)
- } else {
- textarea.setRangeText(
- formatting + textarea.value.substr(start, end) + formatting)
- }
- textarea.focus()
+ if (textarea !== null)
+ Input.format(textarea, formatting)
},
view: vnode => {
- let indicator = undefined
+ let indicators = []
if (bufferLog === undefined && !bufferAutoscroll)
- indicator = m('.indicator', {}, '⇩')
+ indicators.push(m('.indicator', {}, '⇩'))
+ if (Input.formatting)
+ indicators.push(m('.indicator', {}, '#'))
return m('.toolbar', {}, [
- indicator,
- m('button', {onclick: event => Toolbar.insert('\u0002')},
+ indicators,
+ m('button', {onclick: event => Toolbar.format('\u0002')},
m('b', {}, 'B')),
- m('button', {onclick: event => Toolbar.insert('\u001D')},
+ m('button', {onclick: event => Toolbar.format('\u001D')},
m('i', {}, 'I')),
- m('button', {onclick: event => Toolbar.insert('\u001F')},
+ m('button', {onclick: event => Toolbar.format('\u001F')},
m('u', {}, 'U')),
m('button', {onclick: event => bufferToggleLog()},
bufferLog === undefined ? 'Log' : 'Hide log'),
@@ -924,6 +915,21 @@ let Input = {
return true
},
+ formatting: false,
+
+ format: (textarea, formatting) => {
+ const [start, end] = [textarea.selectionStart, textarea.selectionEnd]
+ if (start === end) {
+ textarea.setRangeText(formatting)
+ textarea.setSelectionRange(
+ start + formatting.length, end + formatting.length)
+ } else {
+ textarea.setRangeText(
+ formatting + textarea.value.substr(start, end) + formatting)
+ }
+ textarea.focus()
+ },
+
onKeyDown: event => {
// TODO: And perhaps on other actions, too.
rpc.send({command: 'Active'})
@@ -935,7 +941,29 @@ let Input = {
let textarea = event.currentTarget
let handled = false
let success = true
- if (hasShortcutModifiers(event)) {
+ if (Input.formatting) {
+ Input.formatting = false
+
+ // Like process_formatting_escape() within xC.
+ handled = true
+ switch (event.key) {
+ case 'b': Input.format(textarea, '\u0002'); break
+ case 'c': Input.format(textarea, '\u0003'); break
+ case 'q':
+ case 'm': Input.format(textarea, '\u0011'); break
+ case 'v': Input.format(textarea, '\u0016'); break
+ case 'i':
+ case ']': Input.format(textarea, '\u001D'); break
+ case 's':
+ case 'x':
+ case '^': Input.format(textarea, '\u001E'); break
+ case 'u':
+ case '_': Input.format(textarea, '\u001F'); break
+ case 'r':
+ case 'o': Input.format(textarea, '\u000F'); break
+ default: success = false
+ }
+ } else if (hasShortcutModifiers(event)) {
handled = true
switch (event.key) {
case 'b': success = Input.backward(textarea); break
@@ -947,6 +975,7 @@ let Input = {
case '>': success = Input.last(b, textarea); break
case 'p': success = Input.previous(b, textarea); break
case 'n': success = Input.next(b, textarea); break
+ case 'm': success = Input.formatting = true; break
default: handled = false
}
} else if (!event.altKey && !event.ctrlKey && !event.metaKey &&
@@ -964,15 +993,20 @@ let Input = {
event.preventDefault()
},
+ onStateChange: event => {
+ Completions.reset()
+ Input.formatting = false
+ },
+
view: vnode => {
return m('textarea#input', {
rows: 1,
onkeydown: Input.onKeyDown,
- oninput: event => Completions.reset(),
+ oninput: Input.onStateChange,
// Sadly only supported in Firefox as of writing.
- onselectionchange: event => Completions.reset(),
+ onselectionchange: Input.onStateChange,
// The list of completions is scrollable without receiving focus.
- onblur: event => Completions.reset(),
+ onblur: Input.onStateChange,
})
},
}