diff --git a/manifest.json b/manifest.json index b687363..4922bd8 100644 --- a/manifest.json +++ b/manifest.json @@ -18,6 +18,6 @@ "sessions" ], "web_accessible_resources": [ - "build/command-line.html" + "build/console.html" ] } diff --git a/src/command-line/command-line-frame.js b/src/command-line/command-line-frame.js deleted file mode 100644 index 3f1dda4..0000000 --- a/src/command-line/command-line-frame.js +++ /dev/null @@ -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(); - } -} diff --git a/src/command-line/command-line.html b/src/command-line/command-line.html deleted file mode 100644 index bad0b66..0000000 --- a/src/command-line/command-line.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - VimVixen command-line - - - -
-

-
- -
-
- - diff --git a/src/command-line/command-line.js b/src/command-line/command-line.js deleted file mode 100644 index 34f3f35..0000000 --- a/src/command-line/command-line.js +++ /dev/null @@ -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(); -}); diff --git a/src/console/console-frame.js b/src/console/console-frame.js new file mode 100644 index 0000000..aabb96a --- /dev/null +++ b/src/console/console-frame.js @@ -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(); + } +} diff --git a/src/command-line/command-line-frame.scss b/src/console/console-frame.scss similarity index 73% rename from src/command-line/command-line-frame.scss rename to src/console/console-frame.scss index 88772d9..33bfff3 100644 --- a/src/command-line/command-line-frame.scss +++ b/src/console/console-frame.scss @@ -1,4 +1,4 @@ -.vimvixen-command-line-frame { +.vimvixen-console-frame { margin: 0; padding: 0; bottom: 0; @@ -8,4 +8,5 @@ position: fixed; z-index: 10000; border: none; + pointer-events:none; } diff --git a/src/console/console.html b/src/console/console.html new file mode 100644 index 0000000..2eb445d --- /dev/null +++ b/src/console/console.html @@ -0,0 +1,20 @@ + + + + + VimVixen console + + + +

+
+

+
+ +
+
+ + diff --git a/src/console/console.js b/src/console/console.js new file mode 100644 index 0000000..a171ecc --- /dev/null +++ b/src/console/console.js @@ -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; + } +}); diff --git a/src/command-line/command-line.scss b/src/console/console.scss similarity index 65% rename from src/command-line/command-line.scss rename to src/console/console.scss index 68a0a03..0de873d 100644 --- a/src/command-line/command-line.scss +++ b/src/console/console.scss @@ -10,16 +10,25 @@ body { right: 0; } -.vimvixen-command-line { +.vimvixen-console { border-top: 1px solid gray; bottom: 0; margin: 0; padding: 0; - @mixin input-style { + @mixin consoole-font { font-style: normal; font-family: monospace; 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; padding: 0; - @include input-style; + @include consoole-font; } - &-line { + &-command { background-color: white; display: flex; &-prompt:before { content: ':'; - @include input-style; + @include consoole-font; } &-input { border: none; flex-grow: 1; - @include input-style; + @include consoole-font; } } } diff --git a/src/content/index.js b/src/content/index.js index 9bd4e15..66b1121 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -1,10 +1,11 @@ import * as scrolls from './scrolls'; import * as histories from './histories'; 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'; -let cmd = null; +let vvConsole = new ConsoleFrame(window); const invokeEvent = (action) => { if (typeof action === 'undefined' || action === null) { @@ -13,14 +14,14 @@ const invokeEvent = (action) => { switch (action[0]) { case actions.CMD_OPEN: - cmd = new CommandLineFrame(window); + vvConsole.showCommand(''); break; case actions.CMD_TABS_OPEN: if (action[1] || false) { // alter url - cmd = new CommandLineFrame(window, 'open ' + window.location.href); + vvConsole.showCommand('open ' + window.location.href); } else { - cmd = new CommandLineFrame(window, 'open '); + vvConsole.showCommand('open '); } break; case actions.SCROLL_LINES: @@ -71,21 +72,10 @@ window.addEventListener("keypress", (e) => { }); }); -window.addEventListener('message', (e) => { - let message; - try { - message = JSON.parse(e.data); - } catch (e) { - // ignore message posted by author of web page - return; - } - +messages.receive(window, (message) => { switch (message.type) { case 'vimvixen.commandline.blur': - if (cmd) { - cmd.remove(); - cmd = null; - } + vvConsole.hide(); break; case 'vimvixen.commandline.enter': browser.runtime.sendMessage({ diff --git a/src/shared/messages.js b/src/shared/messages.js new file mode 100644 index 0000000..517fc4c --- /dev/null +++ b/src/shared/messages.js @@ -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 }; diff --git a/test/shared/messages.test.js b/test/shared/messages.test.js new file mode 100644 index 0000000..0ebaf1a --- /dev/null +++ b/test/shared/messages.test.js @@ -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' }); + }); + }); +}); diff --git a/webpack.config.js b/webpack.config.js index f34d203..ba08975 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,7 +8,7 @@ module.exports = { entry: { index: path.join(src, 'content'), background: path.join(src, 'background'), - 'command-line': path.join(src, 'command-line', 'command-line.js') + console: path.join(src, 'console', 'console.js') }, output: { @@ -43,8 +43,8 @@ module.exports = { plugins: [ new HtmlWebpackPlugin({ - template: path.join(src, 'command-line', 'command-line.html'), - filename: path.join(dist, 'command-line.html'), + template: path.join(src, 'console', 'console.html'), + filename: path.join(dist, 'console.html'), inject: false }) ]