Merge branch 'error-line'
This commit is contained in:
commit
044f24efb6
13 changed files with 226 additions and 130 deletions
|
@ -18,6 +18,6 @@
|
||||||
"sessions"
|
"sessions"
|
||||||
],
|
],
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"build/command-line.html"
|
"build/console.html"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<!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>
|
|
|
@ -1,64 +0,0 @@
|
||||||
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();
|
|
||||||
});
|
|
44
src/console/console-frame.js
Normal file
44
src/console/console-frame.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import './console-frame.scss';
|
||||||
|
import * as messages from '../shared/messages';
|
||||||
|
|
||||||
|
export default class ConsoleFrame {
|
||||||
|
constructor(win) {
|
||||||
|
let element = window.document.createElement('iframe');
|
||||||
|
element.src = browser.runtime.getURL('build/console.html');
|
||||||
|
element.className = 'vimvixen-console-frame';
|
||||||
|
win.document.body.append(element);
|
||||||
|
|
||||||
|
this.element = element;
|
||||||
|
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
showCommand(text) {
|
||||||
|
this.showFrame();
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
type: 'vimvixen.console.show.command',
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
messages.send(this.element.contentWindow, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
showError(text) {
|
||||||
|
this.showFrame();
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
type: 'vimvixen.console.show.error',
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
messages.send(this.element.contentWindow, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
showFrame() {
|
||||||
|
this.element.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.element.style.display = 'none';
|
||||||
|
this.element.blur();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.vimvixen-command-line-frame {
|
.vimvixen-console-frame {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -8,4 +8,5 @@
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
border: none;
|
border: none;
|
||||||
|
pointer-events:none;
|
||||||
}
|
}
|
20
src/console/console.html
Normal file
20
src/console/console.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8 />
|
||||||
|
<title>VimVixen console</title>
|
||||||
|
<script src='console.js'></script>
|
||||||
|
</head>
|
||||||
|
<body class='vimvixen-console'>
|
||||||
|
<p id='vimvixen-console-error'
|
||||||
|
class='vimvixen-console-error'></p>
|
||||||
|
<div id='vimvixen-console-command'>
|
||||||
|
<p class='vimvixen-console-title'></p>
|
||||||
|
<div class='vimvixen-console-command'>
|
||||||
|
<i class='vimvixen-console-command-prompt'></i><input
|
||||||
|
id='vimvixen-console-command-input'
|
||||||
|
class='vimvixen-console-command-input'></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
89
src/console/console.js
Normal file
89
src/console/console.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import './console.scss';
|
||||||
|
import * as messages from '../shared/messages';
|
||||||
|
|
||||||
|
const parent = window.parent;
|
||||||
|
|
||||||
|
// TODO consider object-oriented
|
||||||
|
var prevValue = "";
|
||||||
|
|
||||||
|
const blurMessage = () => {
|
||||||
|
return {
|
||||||
|
type: 'vimvixen.commandline.blur'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const keydownMessage = (input) => {
|
||||||
|
return {
|
||||||
|
type: 'vimvixen.commandline.enter',
|
||||||
|
value: input.value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyupMessage = (input) => {
|
||||||
|
return {
|
||||||
|
type: 'vimvixen.commandline.change',
|
||||||
|
value: input.value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
messages.send(parent, blurMessage());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeydown = (e) => {
|
||||||
|
switch(e.keyCode) {
|
||||||
|
case KeyboardEvent.DOM_VK_ESCAPE:
|
||||||
|
messages.send(parent, blurMessage());
|
||||||
|
break;
|
||||||
|
case KeyboardEvent.DOM_VK_RETURN:
|
||||||
|
messages.send(parent, keydownMessage(e.target));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyup = (e) => {
|
||||||
|
if (e.target.value === prevValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messages.send(parent, keyupMessage(e.target));
|
||||||
|
prevValue = e.target.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||||
|
input.addEventListener('blur', handleBlur);
|
||||||
|
input.addEventListener('keydown', handleKeydown);
|
||||||
|
input.addEventListener('keyup', handleKeyup);
|
||||||
|
});
|
||||||
|
|
||||||
|
const showCommand = (text) => {
|
||||||
|
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||||
|
input.value = text;
|
||||||
|
input.focus();
|
||||||
|
|
||||||
|
let command = window.document.querySelector('#vimvixen-console-command');
|
||||||
|
command.style.display = 'block';
|
||||||
|
|
||||||
|
let error = window.document.querySelector('#vimvixen-console-error');
|
||||||
|
error.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
const showError = (text) => {
|
||||||
|
let error = window.document.querySelector('#vimvixen-console-error');
|
||||||
|
error.textContent = text;
|
||||||
|
error.style.display = 'block';
|
||||||
|
|
||||||
|
let command = window.document.querySelector('#vimvixen-console-command');
|
||||||
|
command.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
messages.receive(window, (message) => {
|
||||||
|
switch (message.type) {
|
||||||
|
case 'vimvixen.console.show.command':
|
||||||
|
showCommand(message.text);
|
||||||
|
break;
|
||||||
|
case 'vimvixen.console.show.error':
|
||||||
|
showError(message.text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
|
@ -10,16 +10,25 @@ body {
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vimvixen-command-line {
|
.vimvixen-console {
|
||||||
border-top: 1px solid gray;
|
border-top: 1px solid gray;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
@mixin input-style {
|
@mixin consoole-font {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-error {
|
||||||
|
background-color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
@include consoole-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,24 +38,24 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
@include input-style;
|
@include consoole-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-line {
|
&-command {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&-prompt:before {
|
&-prompt:before {
|
||||||
content: ':';
|
content: ':';
|
||||||
|
|
||||||
@include input-style;
|
@include consoole-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-input {
|
&-input {
|
||||||
border: none;
|
border: none;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
@include input-style;
|
@include consoole-font;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
import * as scrolls from './scrolls';
|
import * as scrolls from './scrolls';
|
||||||
import * as histories from './histories';
|
import * as histories from './histories';
|
||||||
import * as actions from '../shared/actions';
|
import * as actions from '../shared/actions';
|
||||||
import CommandLineFrame from '../command-line/command-line-frame';
|
import * as messages from '../shared/messages';
|
||||||
|
import ConsoleFrame from '../console/console-frame';
|
||||||
import Follow from './follow';
|
import Follow from './follow';
|
||||||
|
|
||||||
let cmd = null;
|
let vvConsole = new ConsoleFrame(window);
|
||||||
|
|
||||||
const invokeEvent = (action) => {
|
const invokeEvent = (action) => {
|
||||||
if (typeof action === 'undefined' || action === null) {
|
if (typeof action === 'undefined' || action === null) {
|
||||||
|
@ -13,14 +14,14 @@ const invokeEvent = (action) => {
|
||||||
|
|
||||||
switch (action[0]) {
|
switch (action[0]) {
|
||||||
case actions.CMD_OPEN:
|
case actions.CMD_OPEN:
|
||||||
cmd = new CommandLineFrame(window);
|
vvConsole.showCommand('');
|
||||||
break;
|
break;
|
||||||
case actions.CMD_TABS_OPEN:
|
case actions.CMD_TABS_OPEN:
|
||||||
if (action[1] || false) {
|
if (action[1] || false) {
|
||||||
// alter url
|
// alter url
|
||||||
cmd = new CommandLineFrame(window, 'open ' + window.location.href);
|
vvConsole.showCommand('open ' + window.location.href);
|
||||||
} else {
|
} else {
|
||||||
cmd = new CommandLineFrame(window, 'open ');
|
vvConsole.showCommand('open ');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case actions.SCROLL_LINES:
|
case actions.SCROLL_LINES:
|
||||||
|
@ -71,21 +72,10 @@ window.addEventListener("keypress", (e) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('message', (e) => {
|
messages.receive(window, (message) => {
|
||||||
let message;
|
|
||||||
try {
|
|
||||||
message = JSON.parse(e.data);
|
|
||||||
} catch (e) {
|
|
||||||
// ignore message posted by author of web page
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case 'vimvixen.commandline.blur':
|
case 'vimvixen.commandline.blur':
|
||||||
if (cmd) {
|
vvConsole.hide();
|
||||||
cmd.remove();
|
|
||||||
cmd = null;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'vimvixen.commandline.enter':
|
case 'vimvixen.commandline.enter':
|
||||||
browser.runtime.sendMessage({
|
browser.runtime.sendMessage({
|
||||||
|
|
19
src/shared/messages.js
Normal file
19
src/shared/messages.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const receive = (win, callback) => {
|
||||||
|
win.addEventListener('message', (e) => {
|
||||||
|
let message;
|
||||||
|
try {
|
||||||
|
message = JSON.parse(e.data);
|
||||||
|
} catch (e) {
|
||||||
|
// ignore message posted by author of web page
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(message);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const send = (win, message) => {
|
||||||
|
win.postMessage(JSON.stringify(message), '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
export { receive, send };
|
25
test/shared/messages.test.js
Normal file
25
test/shared/messages.test.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { expect } from "chai";
|
||||||
|
import * as messages from '../../src/shared/messages';
|
||||||
|
|
||||||
|
describe('messages', () => {
|
||||||
|
describe('#receive', () => {
|
||||||
|
it('received a message', (done) => {
|
||||||
|
messages.receive(window, (message) => {
|
||||||
|
expect(message).to.deep.equal({ type: 'vimvixen.test' });
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
window.postMessage(JSON.stringify({ type: 'vimvixen.test' }), '*');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#send', () => {
|
||||||
|
it('sends a message', (done) => {
|
||||||
|
window.addEventListener('message', (e) => {
|
||||||
|
let json = JSON.parse(e.data);
|
||||||
|
expect(json).to.deep.equal({ type: 'vimvixen.test' });
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
messages.send(window, { type: 'vimvixen.test' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -8,7 +8,7 @@ module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
index: path.join(src, 'content'),
|
index: path.join(src, 'content'),
|
||||||
background: path.join(src, 'background'),
|
background: path.join(src, 'background'),
|
||||||
'command-line': path.join(src, 'command-line', 'command-line.js')
|
console: path.join(src, 'console', 'console.js')
|
||||||
},
|
},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
|
@ -43,8 +43,8 @@ module.exports = {
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: path.join(src, 'command-line', 'command-line.html'),
|
template: path.join(src, 'console', 'console.html'),
|
||||||
filename: path.join(dist, 'command-line.html'),
|
filename: path.join(dist, 'console.html'),
|
||||||
inject: false
|
inject: false
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
Reference in a new issue