Merge pull request #507 from ueokande/window-postmessage
Window postmessage
This commit is contained in:
commit
9c34b961c6
15 changed files with 298 additions and 307 deletions
|
@ -16,6 +16,8 @@ export default class ContentMessageListener {
|
||||||
this.linkController = new LinkController();
|
this.linkController = new LinkController();
|
||||||
this.backgroundOperationController = new OperationController();
|
this.backgroundOperationController = new OperationController();
|
||||||
this.markController = new MarkController();
|
this.markController = new MarkController();
|
||||||
|
|
||||||
|
this.consolePorts = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
|
@ -38,6 +40,7 @@ export default class ContentMessageListener {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
browser.runtime.onConnect.addListener(this.onConnected.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
onMessage(message, sender) {
|
onMessage(message, sender) {
|
||||||
|
@ -65,6 +68,8 @@ export default class ContentMessageListener {
|
||||||
return this.onMarkSetGlobal(message.key, message.x, message.y);
|
return this.onMarkSetGlobal(message.key, message.x, message.y);
|
||||||
case messages.MARK_JUMP_GLOBAL:
|
case messages.MARK_JUMP_GLOBAL:
|
||||||
return this.onMarkJumpGlobal(message.key);
|
return this.onMarkJumpGlobal(message.key);
|
||||||
|
case messages.CONSOLE_FRAME_MESSAGE:
|
||||||
|
return this.onConsoleFrameMessage(sender.tab.id, message.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,4 +121,21 @@ export default class ContentMessageListener {
|
||||||
onMarkJumpGlobal(key) {
|
onMarkJumpGlobal(key) {
|
||||||
return this.markController.jumpGlobal(key);
|
return this.markController.jumpGlobal(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onConsoleFrameMessage(tabId, message) {
|
||||||
|
let port = this.consolePorts[tabId];
|
||||||
|
if (!port) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
port.postMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
onConnected(port) {
|
||||||
|
if (port.name !== 'vimvixen-console') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = port.sender.tab.id;
|
||||||
|
this.consolePorts[id] = port;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
export default class Completion {
|
|
||||||
constructor(wrapper, store) {
|
|
||||||
this.wrapper = wrapper;
|
|
||||||
this.store = store;
|
|
||||||
this.prevState = {};
|
|
||||||
|
|
||||||
store.subscribe(() => {
|
|
||||||
this.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
let state = this.store.getState();
|
|
||||||
if (JSON.stringify(this.prevState) === JSON.stringify(state)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.wrapper.innerHTML = '';
|
|
||||||
|
|
||||||
for (let i = 0; i < state.completions.length; ++i) {
|
|
||||||
let group = state.completions[i];
|
|
||||||
let title = this.createCompletionTitle(group.name);
|
|
||||||
this.wrapper.append(title);
|
|
||||||
|
|
||||||
for (let j = 0; j < group.items.length; ++j) {
|
|
||||||
let item = group.items[j];
|
|
||||||
let li = this.createCompletionItem(item.icon, item.caption, item.url);
|
|
||||||
this.wrapper.append(li);
|
|
||||||
|
|
||||||
if (i === state.groupSelection && j === state.itemSelection) {
|
|
||||||
li.classList.add('vimvixen-completion-selected');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.prevState = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
createCompletionTitle(text) {
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let li = doc.createElement('li');
|
|
||||||
li.className = 'vimvixen-console-completion-title';
|
|
||||||
li.textContent = text;
|
|
||||||
return li;
|
|
||||||
}
|
|
||||||
|
|
||||||
createCompletionItem(icon, caption, url) {
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
|
|
||||||
let captionEle = doc.createElement('span');
|
|
||||||
captionEle.className = 'vimvixen-console-completion-item-caption';
|
|
||||||
captionEle.textContent = caption;
|
|
||||||
|
|
||||||
let urlEle = doc.createElement('span');
|
|
||||||
urlEle.className = 'vimvixen-console-completion-item-url';
|
|
||||||
urlEle.textContent = url;
|
|
||||||
|
|
||||||
let li = doc.createElement('li');
|
|
||||||
li.style.backgroundImage = 'url(' + icon + ')';
|
|
||||||
li.className = 'vimvixen-console-completion-item';
|
|
||||||
li.append(captionEle);
|
|
||||||
li.append(urlEle);
|
|
||||||
return li;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
import * as consoleActions from 'console/actions/console';
|
|
||||||
|
|
||||||
const inputShownMode = (state) => {
|
|
||||||
return ['command', 'find'].includes(state.mode);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class ConsoleComponent {
|
|
||||||
constructor(wrapper, store) {
|
|
||||||
this.wrapper = wrapper;
|
|
||||||
this.store = store;
|
|
||||||
this.prevMode = '';
|
|
||||||
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let input = doc.querySelector('#vimvixen-console-command-input');
|
|
||||||
|
|
||||||
input.addEventListener('blur', this.onBlur.bind(this));
|
|
||||||
input.addEventListener('keydown', this.onKeyDown.bind(this));
|
|
||||||
input.addEventListener('input', this.onInput.bind(this));
|
|
||||||
|
|
||||||
store.subscribe(() => {
|
|
||||||
this.update();
|
|
||||||
});
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
onBlur() {
|
|
||||||
let state = this.store.getState();
|
|
||||||
if (state.mode === 'command' || state.mode === 'find') {
|
|
||||||
return this.store.dispatch(consoleActions.hideCommand());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doEnter(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let state = this.store.getState();
|
|
||||||
let value = e.target.value;
|
|
||||||
if (state.mode === 'command') {
|
|
||||||
return this.store.dispatch(consoleActions.enterCommand(value));
|
|
||||||
} else if (state.mode === 'find') {
|
|
||||||
return this.store.dispatch(consoleActions.enterFind(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectNext(e) {
|
|
||||||
this.store.dispatch(consoleActions.completionNext());
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
selectPrev(e) {
|
|
||||||
this.store.dispatch(consoleActions.completionPrev());
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
onKeyDown(e) {
|
|
||||||
if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) {
|
|
||||||
this.store.dispatch(consoleActions.hideCommand());
|
|
||||||
}
|
|
||||||
switch (e.keyCode) {
|
|
||||||
case KeyboardEvent.DOM_VK_ESCAPE:
|
|
||||||
return this.store.dispatch(consoleActions.hideCommand());
|
|
||||||
case KeyboardEvent.DOM_VK_RETURN:
|
|
||||||
return this.doEnter(e);
|
|
||||||
case KeyboardEvent.DOM_VK_TAB:
|
|
||||||
if (e.shiftKey) {
|
|
||||||
this.store.dispatch(consoleActions.completionPrev());
|
|
||||||
} else {
|
|
||||||
this.store.dispatch(consoleActions.completionNext());
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case KeyboardEvent.DOM_VK_OPEN_BRACKET:
|
|
||||||
if (e.ctrlKey) {
|
|
||||||
return this.store.dispatch(consoleActions.hideCommand());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeyboardEvent.DOM_VK_M:
|
|
||||||
if (e.ctrlKey) {
|
|
||||||
return this.doEnter(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeyboardEvent.DOM_VK_N:
|
|
||||||
if (e.ctrlKey) {
|
|
||||||
this.selectNext(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeyboardEvent.DOM_VK_P:
|
|
||||||
if (e.ctrlKey) {
|
|
||||||
this.selectPrev(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onInput(e) {
|
|
||||||
let state = this.store.getState();
|
|
||||||
let text = e.target.value;
|
|
||||||
this.store.dispatch(consoleActions.setConsoleText(text));
|
|
||||||
if (state.mode === 'command') {
|
|
||||||
this.store.dispatch(consoleActions.getCompletions(text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onInputShown(state) {
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let input = doc.querySelector('#vimvixen-console-command-input');
|
|
||||||
|
|
||||||
input.focus();
|
|
||||||
window.focus();
|
|
||||||
|
|
||||||
if (state.mode === 'command') {
|
|
||||||
let text = state.consoleText;
|
|
||||||
input.value = text;
|
|
||||||
this.store.dispatch(consoleActions.getCompletions(text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
let state = this.store.getState();
|
|
||||||
|
|
||||||
this.updateMessage(state);
|
|
||||||
this.updateCommand(state);
|
|
||||||
this.updatePrompt(state);
|
|
||||||
|
|
||||||
if (this.prevMode !== state.mode && inputShownMode(state)) {
|
|
||||||
this.onInputShown(state);
|
|
||||||
}
|
|
||||||
this.prevMode = state.mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateMessage(state) {
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let box = doc.querySelector('.vimvixen-console-message');
|
|
||||||
let display = 'none';
|
|
||||||
let classList = ['vimvixen-console-message'];
|
|
||||||
|
|
||||||
if (state.mode === 'error' || state.mode === 'info') {
|
|
||||||
display = 'block';
|
|
||||||
classList.push('vimvixen-console-' + state.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
box.className = classList.join(' ');
|
|
||||||
box.style.display = display;
|
|
||||||
box.textContent = state.messageText;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCommand(state) {
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let command = doc.querySelector('#vimvixen-console-command');
|
|
||||||
let input = doc.querySelector('#vimvixen-console-command-input');
|
|
||||||
|
|
||||||
let display = 'none';
|
|
||||||
if (inputShownMode(state)) {
|
|
||||||
display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
command.style.display = display;
|
|
||||||
input.value = state.consoleText;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePrompt(state) {
|
|
||||||
let classList = ['vimvixen-console-command-prompt'];
|
|
||||||
if (inputShownMode(state)) {
|
|
||||||
classList.push('prompt-' + state.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
let doc = this.wrapper.ownerDocument;
|
|
||||||
let ele = doc.querySelector('.vimvixen-console-command-prompt');
|
|
||||||
ele.className = classList.join(' ');
|
|
||||||
}
|
|
||||||
}
|
|
133
src/console/components/console.jsx
Normal file
133
src/console/components/console.jsx
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import './console.scss';
|
||||||
|
import { connect } from 'preact-redux';
|
||||||
|
import { Component, h } from 'preact';
|
||||||
|
import Input from './console/input';
|
||||||
|
import Completion from './console/completion';
|
||||||
|
import Message from './console/message';
|
||||||
|
import * as consoleActions from '../../console/actions/console';
|
||||||
|
|
||||||
|
class ConsoleComponent extends Component {
|
||||||
|
onBlur() {
|
||||||
|
if (this.props.mode === 'command' || this.props.mode === 'find') {
|
||||||
|
return this.context.store.dispatch(consoleActions.hideCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doEnter(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let value = e.target.value;
|
||||||
|
if (this.props.mode === 'command') {
|
||||||
|
return this.context.store.dispatch(consoleActions.enterCommand(value));
|
||||||
|
} else if (this.props.mode === 'find') {
|
||||||
|
return this.context.store.dispatch(consoleActions.enterFind(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectNext(e) {
|
||||||
|
this.context.store.dispatch(consoleActions.completionNext());
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPrev(e) {
|
||||||
|
this.context.store.dispatch(consoleActions.completionPrev());
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown(e) {
|
||||||
|
if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) {
|
||||||
|
this.context.store.dispatch(consoleActions.hideCommand());
|
||||||
|
}
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case KeyboardEvent.DOM_VK_ESCAPE:
|
||||||
|
return this.context.store.dispatch(consoleActions.hideCommand());
|
||||||
|
case KeyboardEvent.DOM_VK_RETURN:
|
||||||
|
return this.doEnter(e);
|
||||||
|
case KeyboardEvent.DOM_VK_TAB:
|
||||||
|
if (e.shiftKey) {
|
||||||
|
this.context.store.dispatch(consoleActions.completionPrev());
|
||||||
|
} else {
|
||||||
|
this.context.store.dispatch(consoleActions.completionNext());
|
||||||
|
}
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case KeyboardEvent.DOM_VK_OPEN_BRACKET:
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
return this.context.store.dispatch(consoleActions.hideCommand());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeyboardEvent.DOM_VK_M:
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
return this.doEnter(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeyboardEvent.DOM_VK_N:
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
this.selectNext(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeyboardEvent.DOM_VK_P:
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
this.selectPrev(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput(e) {
|
||||||
|
let text = e.target.value;
|
||||||
|
this.context.store.dispatch(consoleActions.setConsoleText(text));
|
||||||
|
if (this.props.mode === 'command') {
|
||||||
|
this.context.store.dispatch(consoleActions.getCompletions(text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (!this.input) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (prevProps.mode !== 'command' && this.props.mode === 'command') {
|
||||||
|
this.context.store.dispatch(
|
||||||
|
consoleActions.getCompletions(this.props.consoleText));
|
||||||
|
this.focus();
|
||||||
|
} else if (prevProps.mode !== 'find' && this.props.mode === 'find') {
|
||||||
|
this.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
switch (this.props.mode) {
|
||||||
|
case 'command':
|
||||||
|
case 'find':
|
||||||
|
return <div className='vimvixen-console-command-wrapper'>
|
||||||
|
<Completion />
|
||||||
|
<Input
|
||||||
|
ref={(c) => { this.input = c; }}
|
||||||
|
mode={this.props.mode}
|
||||||
|
onBlur={this.onBlur.bind(this)}
|
||||||
|
onKeyDown={this.onKeyDown.bind(this)}
|
||||||
|
onInput={this.onInput.bind(this)}
|
||||||
|
value={this.props.consoleText}
|
||||||
|
/>
|
||||||
|
</div>;
|
||||||
|
case 'info':
|
||||||
|
case 'error':
|
||||||
|
return <Message mode={ this.props.mode } >
|
||||||
|
{ this.props.messageText }
|
||||||
|
</Message>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
focus() {
|
||||||
|
window.focus();
|
||||||
|
this.input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => state;
|
||||||
|
export default connect(mapStateToProps)(ConsoleComponent);
|
|
@ -89,18 +89,10 @@ body {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&-prompt:before {
|
&-prompt {
|
||||||
@include consoole-font;
|
@include consoole-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-prompt.prompt-command:before {
|
|
||||||
content: ':';
|
|
||||||
}
|
|
||||||
|
|
||||||
&-prompt.prompt-find:before {
|
|
||||||
content: '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
&-input {
|
&-input {
|
||||||
border: none;
|
border: none;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
56
src/console/components/console/completion.jsx
Normal file
56
src/console/components/console/completion.jsx
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import { Component, h } from 'preact';
|
||||||
|
import { connect } from 'preact-redux';
|
||||||
|
|
||||||
|
const CompletionTitle = (props) => {
|
||||||
|
return <li className='vimvixen-console-completion-title' >{props.title}</li>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CompletionItem = (props) => {
|
||||||
|
let className = 'vimvixen-console-completion-item';
|
||||||
|
if (props.highlight) {
|
||||||
|
className += ' vimvixen-completion-selected';
|
||||||
|
}
|
||||||
|
return <li
|
||||||
|
className={className}
|
||||||
|
style={{ backgroundImage: 'url(' + props.icon + ')' }}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className='vimvixen-console-completion-item-caption'
|
||||||
|
>{props.caption}</span>
|
||||||
|
<span
|
||||||
|
className='vimvixen-console-completion-item-url'
|
||||||
|
>{props.url}</span>
|
||||||
|
</li>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CompletionComponent extends Component {
|
||||||
|
render() {
|
||||||
|
let eles = [];
|
||||||
|
for (let i = 0; i < this.props.completions.length; ++i) {
|
||||||
|
let group = this.props.completions[i];
|
||||||
|
eles.push(<CompletionTitle title={ group.name }/>);
|
||||||
|
for (let j = 0; j < group.items.length; ++j) {
|
||||||
|
let item = group.items[j];
|
||||||
|
let selected =
|
||||||
|
i === this.props.groupSelection &&
|
||||||
|
j === this.props.itemSelection;
|
||||||
|
eles.push(<CompletionItem
|
||||||
|
icon={item.icon}
|
||||||
|
caption={item.caption}
|
||||||
|
url={item.url}
|
||||||
|
highlight={selected}
|
||||||
|
/ >);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className='vimvixen-console-completion'>
|
||||||
|
{ eles }
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => state;
|
||||||
|
export default connect(mapStateToProps)(CompletionComponent);
|
32
src/console/components/console/input.jsx
Normal file
32
src/console/components/console/input.jsx
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { Component, h } from 'preact';
|
||||||
|
|
||||||
|
export default class InputComponent extends Component {
|
||||||
|
focus() {
|
||||||
|
this.input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let prompt = '';
|
||||||
|
if (this.props.mode === 'command') {
|
||||||
|
prompt = ':';
|
||||||
|
} else if (this.props.mode === 'find') {
|
||||||
|
prompt = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='vimvixen-console-command'>
|
||||||
|
<i className='vimvixen-console-command-prompt'>
|
||||||
|
{ prompt }
|
||||||
|
</i>
|
||||||
|
<input
|
||||||
|
className='vimvixen-console-command-input'
|
||||||
|
ref={(c) => { this.input = c; }}
|
||||||
|
onBlur={this.props.onBlur}
|
||||||
|
onKeyDown={this.props.onKeyDown}
|
||||||
|
onInput={this.props.onInput}
|
||||||
|
value={this.props.value}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
18
src/console/components/console/message.jsx
Normal file
18
src/console/components/console/message.jsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { h } from 'preact';
|
||||||
|
|
||||||
|
export default function Message(props) {
|
||||||
|
switch (props.mode) {
|
||||||
|
case 'error':
|
||||||
|
return (
|
||||||
|
<p className='vimvixen-console-message vimvixen-console-error'>
|
||||||
|
{ props.children }
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
case 'info':
|
||||||
|
return (
|
||||||
|
<p className='vimvixen-console-message vimvixen-console-info'>
|
||||||
|
{ props.children }
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,15 +5,5 @@
|
||||||
<title>VimVixen console</title>
|
<title>VimVixen console</title>
|
||||||
<script src='console.js'></script>
|
<script src='console.js'></script>
|
||||||
</head>
|
</head>
|
||||||
<body class='vimvixen-console'>
|
<body class='vimvixen-console'></body>
|
||||||
<p class='vimvixen-console-message'></p>
|
|
||||||
<div id='vimvixen-console-command' class='vimvixen-console-command-wrapper'>
|
|
||||||
<ul id='vimvixen-console-completion' class='vimvixen-console-completion'></ul>
|
|
||||||
<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>
|
</html>
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
import './site.scss';
|
|
||||||
import messages from 'shared/messages';
|
import messages from 'shared/messages';
|
||||||
import CompletionComponent from 'console/components/completion';
|
|
||||||
import ConsoleComponent from 'console/components/console';
|
|
||||||
import reducers from 'console/reducers';
|
import reducers from 'console/reducers';
|
||||||
import { createStore, applyMiddleware } from 'redux';
|
import { createStore, applyMiddleware } from 'redux';
|
||||||
import promise from 'redux-promise';
|
import promise from 'redux-promise';
|
||||||
import * as consoleActions from 'console/actions/console';
|
import * as consoleActions from 'console/actions/console';
|
||||||
|
|
||||||
|
import { Provider } from 'preact-redux';
|
||||||
|
import Console from './components/console';
|
||||||
|
|
||||||
|
import { render, h } from 'preact';
|
||||||
|
|
||||||
const store = createStore(
|
const store = createStore(
|
||||||
reducers,
|
reducers,
|
||||||
applyMiddleware(promise),
|
applyMiddleware(promise),
|
||||||
);
|
);
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
let wrapper = document.querySelector('#vimvixen-console-completion');
|
render(
|
||||||
new CompletionComponent(wrapper, store); // eslint-disable-line no-new
|
<Provider store={store} >
|
||||||
new ConsoleComponent(document.body, store); // eslint-disable-line no-new
|
<Console></Console>
|
||||||
|
</Provider>,
|
||||||
|
document.body);
|
||||||
});
|
});
|
||||||
|
|
||||||
const onMessage = (message) => {
|
const onMessage = (message) => {
|
||||||
|
@ -34,6 +38,5 @@ const onMessage = (message) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener(onMessage);
|
browser.runtime.onMessage.addListener(onMessage);
|
||||||
window.addEventListener('message', (event) => {
|
let port = browser.runtime.connect({ name: 'vimvixen-console' });
|
||||||
onMessage(JSON.parse(event.data));
|
port.onMessage.addListener(onMessage);
|
||||||
}, false);
|
|
|
@ -9,25 +9,6 @@ import messages from 'shared/messages';
|
||||||
import actions from 'content/actions';
|
import actions from 'content/actions';
|
||||||
import * as consoleFrames from '../console-frames';
|
import * as consoleFrames from '../console-frames';
|
||||||
|
|
||||||
const postPatternNotFound = (pattern) => {
|
|
||||||
return consoleFrames.postError(
|
|
||||||
window.document,
|
|
||||||
'Pattern not found: ' + pattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
const postPatternFound = (pattern) => {
|
|
||||||
return consoleFrames.postInfo(
|
|
||||||
window.document,
|
|
||||||
'Pattern found: ' + pattern,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const postNoPrevious = () => {
|
|
||||||
return consoleFrames.postError(
|
|
||||||
window.document,
|
|
||||||
'No previous search keywords');
|
|
||||||
};
|
|
||||||
|
|
||||||
const find = (string, backwards) => {
|
const find = (string, backwards) => {
|
||||||
let caseSensitive = false;
|
let caseSensitive = false;
|
||||||
let wrapScan = true;
|
let wrapScan = true;
|
||||||
|
@ -60,13 +41,13 @@ const findNext = async(currentKeyword, reset, backwards) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!keyword) {
|
if (!keyword) {
|
||||||
return postNoPrevious();
|
return consoleFrames.postError('No previous search keywords');
|
||||||
}
|
}
|
||||||
let found = find(keyword, backwards);
|
let found = find(keyword, backwards);
|
||||||
if (found) {
|
if (found) {
|
||||||
postPatternFound(keyword);
|
consoleFrames.postInfo('Pattern found: ' + keyword);
|
||||||
} else {
|
} else {
|
||||||
postPatternNotFound(keyword);
|
consoleFrames.postError('Pattern not found: ' + keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -85,7 +85,7 @@ const exec = (operation, repeat, settings, addonEnabled) => {
|
||||||
break;
|
break;
|
||||||
case operations.URLS_YANK:
|
case operations.URLS_YANK:
|
||||||
urls.yank(window);
|
urls.yank(window);
|
||||||
consoleFrames.postInfo(window.document, 'Current url yanked');
|
consoleFrames.postInfo('Current url yanked');
|
||||||
break;
|
break;
|
||||||
case operations.URLS_PASTE:
|
case operations.URLS_PASTE:
|
||||||
urls.paste(
|
urls.paste(
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default class MarkComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.ctrlKey || key.metaKey || key.altKey) {
|
if (key.ctrlKey || key.metaKey || key.altKey) {
|
||||||
consoleFrames.postError(window.document, 'Unknown mark');
|
consoleFrames.postError('Unknown mark');
|
||||||
} else if (globalKey(key.key) && markStage.setMode) {
|
} else if (globalKey(key.key) && markStage.setMode) {
|
||||||
this.doSetGlobal(key);
|
this.doSetGlobal(key);
|
||||||
} else if (globalKey(key.key) && markStage.jumpMode) {
|
} else if (globalKey(key.key) && markStage.jumpMode) {
|
||||||
|
@ -55,7 +55,7 @@ export default class MarkComponent {
|
||||||
|
|
||||||
doJump(marks, key, smoothscroll) {
|
doJump(marks, key, smoothscroll) {
|
||||||
if (!marks[key.key]) {
|
if (!marks[key.key]) {
|
||||||
consoleFrames.postError(window.document, 'Mark is not set');
|
consoleFrames.postError('Mark is not set');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,22 +16,23 @@ const blur = (doc) => {
|
||||||
iframe.blur();
|
iframe.blur();
|
||||||
};
|
};
|
||||||
|
|
||||||
const postMessage = (doc, message) => {
|
const postError = (text) => {
|
||||||
let iframe = doc.getElementById('vimvixen-console-frame');
|
browser.runtime.sendMessage({
|
||||||
iframe.contentWindow.postMessage(JSON.stringify(message), '*');
|
type: messages.CONSOLE_FRAME_MESSAGE,
|
||||||
};
|
message: {
|
||||||
|
type: messages.CONSOLE_SHOW_ERROR,
|
||||||
const postError = (doc, message) => {
|
text,
|
||||||
return postMessage(doc, {
|
},
|
||||||
type: messages.CONSOLE_SHOW_ERROR,
|
|
||||||
text: message,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const postInfo = (doc, message) => {
|
const postInfo = (text) => {
|
||||||
return postMessage(doc, {
|
browser.runtime.sendMessage({
|
||||||
type: messages.CONSOLE_SHOW_INFO,
|
type: messages.CONSOLE_FRAME_MESSAGE,
|
||||||
text: message,
|
message: {
|
||||||
|
type: messages.CONSOLE_SHOW_INFO,
|
||||||
|
text,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ export default {
|
||||||
SETTINGS_CHANGED: 'settings.changed',
|
SETTINGS_CHANGED: 'settings.changed',
|
||||||
SETTINGS_QUERY: 'settings.query',
|
SETTINGS_QUERY: 'settings.query',
|
||||||
|
|
||||||
|
WINDOW_TOP_MESSAGE: 'window.top.message',
|
||||||
|
CONSOLE_FRAME_MESSAGE: 'console.frame.message',
|
||||||
|
|
||||||
onWebMessage,
|
onWebMessage,
|
||||||
onBackgroundMessage,
|
onBackgroundMessage,
|
||||||
onMessage,
|
onMessage,
|
||||||
|
|
Reference in a new issue