commit
f1b9c6ba9d
12 changed files with 1713 additions and 156 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@ |
|||||||
|
import './command-line-frame.scss'; |
||||||
|
|
||||||
|
export default class CommandLineFrame { |
||||||
|
constructor(win, initial = '') { |
||||||
|
let url = browser.runtime.getURL('build/command-line.html') + |
||||||
|
'#' + encodeURIComponent(initial); |
||||||
|
|
||||||
|
let element = window.document.createElement('iframe'); |
||||||
|
element.src = url; |
||||||
|
element.className = 'vimvixen-command-line-frame'; |
||||||
|
win.document.body.append(element); |
||||||
|
|
||||||
|
this.element = element; |
||||||
|
} |
||||||
|
|
||||||
|
remove() { |
||||||
|
this.element.remove(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
.vimvixen-command-line-frame { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
position: fixed; |
||||||
|
z-index: 10000; |
||||||
|
border: none; |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset=utf-8 /> |
||||||
|
<title>VimVixen command-line</title> |
||||||
|
<script src='command-line.js'></script> |
||||||
|
</head> |
||||||
|
<body class='vimvixen-command-line'> |
||||||
|
<div> |
||||||
|
<p class='vimvixen-command-line-title'></p> |
||||||
|
<div class='vimvixen-command-line-line'> |
||||||
|
<i class='vimvixen-command-line-line-prompt'></i><input |
||||||
|
id='vimvixen-command-line-line-input' |
||||||
|
class='vimvixen-command-line-line-input'></input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,64 @@ |
|||||||
|
import './command-line.scss'; |
||||||
|
|
||||||
|
const parent = window.parent; |
||||||
|
|
||||||
|
// TODO consider object-oriented
|
||||||
|
var prevValue = ""; |
||||||
|
|
||||||
|
const blurData = () => { |
||||||
|
return JSON.stringify({ |
||||||
|
type: 'vimvixen.commandline.blur' |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const keydownData = (input) => { |
||||||
|
return JSON.stringify({ |
||||||
|
type: 'vimvixen.commandline.enter', |
||||||
|
value: input.value |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const keyupData = (input) => { |
||||||
|
return JSON.stringify({ |
||||||
|
type: 'vimvixen.commandline.change', |
||||||
|
value: input.value |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const handleBlur = () => { |
||||||
|
parent.postMessage(blurData(), '*'); |
||||||
|
}; |
||||||
|
|
||||||
|
const handleKeydown = (e) => { |
||||||
|
switch(e.keyCode) { |
||||||
|
case KeyboardEvent.DOM_VK_ESCAPE: |
||||||
|
parent.postMessage(blurData(), '*'); |
||||||
|
break; |
||||||
|
case KeyboardEvent.DOM_VK_RETURN: |
||||||
|
parent.postMessage(keydownData(e.target), '*'); |
||||||
|
break; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const handleKeyup = (e) => { |
||||||
|
if (e.target.value === prevValue) { |
||||||
|
return; |
||||||
|
} |
||||||
|
parent.postMessage(keyupData(e.target), '*'); |
||||||
|
prevValue = e.target.value; |
||||||
|
}; |
||||||
|
|
||||||
|
window.addEventListener('load', () => { |
||||||
|
let hash = window.location.hash; |
||||||
|
let initial = ''; |
||||||
|
if (hash.length > 0) { |
||||||
|
initial = decodeURIComponent(hash.substring(1)); |
||||||
|
} |
||||||
|
|
||||||
|
let input = window.document.querySelector('#vimvixen-command-line-line-input'); |
||||||
|
input.addEventListener('blur', handleBlur); |
||||||
|
input.addEventListener('keydown', handleKeydown); |
||||||
|
input.addEventListener('keyup', handleKeyup); |
||||||
|
input.value = initial; |
||||||
|
input.focus(); |
||||||
|
}); |
@ -0,0 +1,52 @@ |
|||||||
|
html, body, * { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.vimvixen-command-line { |
||||||
|
border-top: 1px solid gray; |
||||||
|
bottom: 0; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
|
||||||
|
@mixin input-style { |
||||||
|
font-style: normal; |
||||||
|
font-family: monospace; |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
&-title { |
||||||
|
background-color: lightgray; |
||||||
|
font-weight: bold; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
|
||||||
|
@include input-style; |
||||||
|
} |
||||||
|
|
||||||
|
&-line { |
||||||
|
background-color: white; |
||||||
|
display: flex; |
||||||
|
|
||||||
|
&-prompt:before { |
||||||
|
content: ':'; |
||||||
|
|
||||||
|
@include input-style; |
||||||
|
} |
||||||
|
|
||||||
|
&-input { |
||||||
|
border: none; |
||||||
|
flex-grow: 1; |
||||||
|
|
||||||
|
@include input-style; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,46 +0,0 @@ |
|||||||
.vimvixen-footerline { |
|
||||||
border-top: 1px solid gray; |
|
||||||
bottom: 0; |
|
||||||
box-sizing: border-box; |
|
||||||
font-family: monospace; |
|
||||||
font-size: 12px; |
|
||||||
left: 0; |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
position: fixed; |
|
||||||
right: 0; |
|
||||||
z-index: 10000; |
|
||||||
} |
|
||||||
|
|
||||||
.vimvixen-footerline-title { |
|
||||||
background-color: lightgray; |
|
||||||
font-weight: bold; |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
} |
|
||||||
|
|
||||||
.vimvixen-footerline-container-outer { |
|
||||||
background-color: white; |
|
||||||
position: relative; |
|
||||||
} |
|
||||||
|
|
||||||
.vimvixen-footerline-container-outer:before { |
|
||||||
content: ':'; |
|
||||||
background-color: white; |
|
||||||
float: left; |
|
||||||
text-align: right; |
|
||||||
width: 12px; |
|
||||||
} |
|
||||||
|
|
||||||
.vimvixen-footerline-container-inner { |
|
||||||
position: absolute; |
|
||||||
left: 12px; |
|
||||||
right: 0; |
|
||||||
} |
|
||||||
|
|
||||||
.vimvixen-footerline-input { |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
width: 100%; |
|
||||||
border: none; |
|
||||||
} |
|
@ -1,78 +0,0 @@ |
|||||||
import './footer-line.css'; |
|
||||||
|
|
||||||
export default class FooterLine { |
|
||||||
constructor(doc, initial = '') { |
|
||||||
this.initUi(doc); |
|
||||||
|
|
||||||
this.enteredCallback = () => {} |
|
||||||
this.promptChangeCallback = () => {} |
|
||||||
|
|
||||||
this.input.addEventListener('blur', this.handleBlur.bind(this)); |
|
||||||
this.input.addEventListener('keydown', this.handleKeydown.bind(this)); |
|
||||||
this.input.addEventListener('keyup', this.handleKeyup.bind(this)); |
|
||||||
this.input.value = initial; |
|
||||||
} |
|
||||||
|
|
||||||
initUi(doc) { |
|
||||||
this.title = doc.createElement('p'); |
|
||||||
this.title.className = 'vimvixen-footerline-title'; |
|
||||||
|
|
||||||
let containerInner = doc.createElement('div'); |
|
||||||
containerInner.className = 'vimvixen-footerline-container-inner'; |
|
||||||
|
|
||||||
let containerOuter = doc.createElement('div'); |
|
||||||
containerOuter.className = 'vimvixen-footerline-container-outer'; |
|
||||||
|
|
||||||
this.input = doc.createElement('input'); |
|
||||||
this.input.className = 'vimvixen-footerline-input'; |
|
||||||
|
|
||||||
this.wrapper = doc.createElement('div'); |
|
||||||
this.wrapper.className = 'vimvixen-footerline'; |
|
||||||
|
|
||||||
containerOuter.append(containerInner); |
|
||||||
containerInner.append(this.input); |
|
||||||
this.wrapper.append(this.title); |
|
||||||
this.wrapper.append(containerOuter); |
|
||||||
doc.body.append(this.wrapper) |
|
||||||
} |
|
||||||
|
|
||||||
focus() { |
|
||||||
this.input.focus(); |
|
||||||
} |
|
||||||
|
|
||||||
remove() { |
|
||||||
this.wrapper.remove(); |
|
||||||
} |
|
||||||
|
|
||||||
onPromptChange(callback) { |
|
||||||
this.promptChangeCallback = callback; |
|
||||||
} |
|
||||||
|
|
||||||
onEntered(callback) { |
|
||||||
this.enteredCallback = callback; |
|
||||||
} |
|
||||||
|
|
||||||
handleBlur() { |
|
||||||
this.remove(); |
|
||||||
} |
|
||||||
|
|
||||||
handleKeydown(e) { |
|
||||||
this.prevValue = e.target.value; |
|
||||||
switch(e.keyCode) { |
|
||||||
case KeyboardEvent.DOM_VK_ESCAPE: |
|
||||||
this.remove(); |
|
||||||
break; |
|
||||||
case KeyboardEvent.DOM_VK_RETURN: |
|
||||||
this.enteredCallback(e); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleKeyup(e) { |
|
||||||
if (e.target.value === this.prevValue) { |
|
||||||
return; |
|
||||||
} |
|
||||||
this.promptChangeCallback(e); |
|
||||||
this.prevValue = e.target.value; |
|
||||||
} |
|
||||||
} |
|
Reference in new issue