Merge branch 'error-line'

jh-changes
Shin'ya Ueoka 7 years ago
commit 044f24efb6
  1. 2
      manifest.json
  2. 19
      src/command-line/command-line-frame.js
  3. 18
      src/command-line/command-line.html
  4. 64
      src/command-line/command-line.js
  5. 44
      src/console/console-frame.js
  6. 3
      src/console/console-frame.scss
  7. 20
      src/console/console.html
  8. 89
      src/console/console.js
  9. 21
      src/console/console.scss
  10. 26
      src/content/index.js
  11. 19
      src/shared/messages.js
  12. 25
      test/shared/messages.test.js
  13. 6
      webpack.config.js

@ -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();
});

@ -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;
} }

@ -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>

@ -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({

@ -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 };

@ -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
}) })
] ]