make top-content component and frame-content component
This commit is contained in:
parent
042aa94936
commit
4c9d0433a6
13 changed files with 102 additions and 76 deletions
46
src/content/components/common/index.js
Normal file
46
src/content/components/common/index.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import InputComponent from './input';
|
||||||
|
import KeymapperComponent from './keymapper';
|
||||||
|
import FollowComponent from './follow';
|
||||||
|
import * as inputActions from 'content/actions/input';
|
||||||
|
import messages from 'shared/messages';
|
||||||
|
|
||||||
|
export default class Common {
|
||||||
|
constructor(win, store) {
|
||||||
|
const follow = new FollowComponent(win, store);
|
||||||
|
const input = new InputComponent(win.document.body, store);
|
||||||
|
const keymapper = new KeymapperComponent(store);
|
||||||
|
|
||||||
|
input.onKey((key, ctrl) => {
|
||||||
|
follow.key(key, ctrl);
|
||||||
|
keymapper.key(key, ctrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.store = store;
|
||||||
|
this.children = [
|
||||||
|
follow,
|
||||||
|
input,
|
||||||
|
keymapper,
|
||||||
|
];
|
||||||
|
|
||||||
|
this.reloadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.children.forEach(c => c.update());
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage(message) {
|
||||||
|
switch (message) {
|
||||||
|
case messages.SETTINGS_CHANGED:
|
||||||
|
this.reloadSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadSettings() {
|
||||||
|
browser.runtime.sendMessage({
|
||||||
|
type: messages.SETTINGS_QUERY,
|
||||||
|
}).then((settings) => {
|
||||||
|
this.store.dispatch(inputActions.setKeymaps(settings.keymaps));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export default class ContentInputComponent {
|
export default class InputComponent {
|
||||||
constructor(target) {
|
constructor(target) {
|
||||||
this.pressed = {};
|
this.pressed = {};
|
||||||
this.onKeyListeners = [];
|
this.onKeyListeners = [];
|
16
src/content/components/frame-content.js
Normal file
16
src/content/components/frame-content.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import CommonComponent from './common';
|
||||||
|
|
||||||
|
export default class FrameContent {
|
||||||
|
|
||||||
|
constructor(win, store) {
|
||||||
|
this.children = [new CommonComponent(win, store)];
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.children.forEach(c => c.update());
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage(message) {
|
||||||
|
this.children.forEach(c => c.onMessage(message));
|
||||||
|
}
|
||||||
|
}
|
28
src/content/components/top-content.js
Normal file
28
src/content/components/top-content.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import CommonComponent from './common';
|
||||||
|
import * as consoleFrames from '../console-frames';
|
||||||
|
import messages from 'shared/messages';
|
||||||
|
|
||||||
|
export default class TopContent {
|
||||||
|
|
||||||
|
constructor(win, store) {
|
||||||
|
this.win = win;
|
||||||
|
this.children = [new CommonComponent(win, store)];
|
||||||
|
|
||||||
|
// TODO make component
|
||||||
|
consoleFrames.initialize(window.document);
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.children.forEach(c => c.update());
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage(message) {
|
||||||
|
switch (message.type) {
|
||||||
|
case messages.CONSOLE_HIDE_COMMAND:
|
||||||
|
this.win.focus();
|
||||||
|
consoleFrames.blur(window.document);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
this.children.forEach(c => c.onMessage(message));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,78 +1,14 @@
|
||||||
import './console-frame.scss';
|
import './console-frame.scss';
|
||||||
import * as consoleFrames from './console-frames';
|
|
||||||
import * as inputActions from './actions/input';
|
|
||||||
import { createStore } from 'shared/store';
|
import { createStore } from 'shared/store';
|
||||||
import ContentInputComponent from 'content/components/content-input';
|
|
||||||
import KeymapperComponent from 'content/components/keymapper';
|
|
||||||
import FollowComponent from 'content/components/follow';
|
|
||||||
import reducers from 'content/reducers';
|
import reducers from 'content/reducers';
|
||||||
import messages from 'shared/messages';
|
import TopContentComponent from './components/top-content';
|
||||||
|
import FrameContentComponent from './components/frame-content';
|
||||||
|
|
||||||
const store = createStore(reducers);
|
const store = createStore(reducers);
|
||||||
const followComponent = new FollowComponent(window, store);
|
|
||||||
const contentInputComponent =
|
|
||||||
new ContentInputComponent(window.document.body, store);
|
|
||||||
const keymapperComponent = new KeymapperComponent(store);
|
|
||||||
contentInputComponent.onKey((key, ctrl) => {
|
|
||||||
return followComponent.key(key, ctrl);
|
|
||||||
});
|
|
||||||
contentInputComponent.onKey((key, ctrl) => {
|
|
||||||
return keymapperComponent.key(key, ctrl);
|
|
||||||
});
|
|
||||||
store.subscribe(() => {
|
|
||||||
try {
|
|
||||||
followComponent.update();
|
|
||||||
contentInputComponent.update();
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const reloadSettings = () => {
|
let rootComponent = window.self === window.top
|
||||||
return browser.runtime.sendMessage({
|
? new TopContentComponent(window, store)
|
||||||
type: messages.SETTINGS_QUERY,
|
: new FrameContentComponent(window, store);
|
||||||
}).then((settings) => {
|
|
||||||
store.dispatch(inputActions.setKeymaps(settings.keymaps));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: the followin methods should be implemented in each top component and
|
browser.runtime.onMessage.addListener(msg => rootComponent.onMessage(msg));
|
||||||
// frame component
|
rootComponent.update();
|
||||||
const initTopComponents = () => {
|
|
||||||
consoleFrames.initialize(window.document);
|
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener((action) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case messages.CONSOLE_HIDE_COMMAND:
|
|
||||||
window.focus();
|
|
||||||
consoleFrames.blur(window.document);
|
|
||||||
return Promise.resolve();
|
|
||||||
case messages.SETTINGS_CHANGED:
|
|
||||||
return reloadSettings();
|
|
||||||
default:
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const initFrameConponents = () => {
|
|
||||||
browser.runtime.onMessage.addListener((action) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case messages.CONSOLE_HIDE_COMMAND:
|
|
||||||
window.focus();
|
|
||||||
return Promise.resolve();
|
|
||||||
case messages.SETTINGS_CHANGED:
|
|
||||||
return reloadSettings();
|
|
||||||
default:
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (window.self === window.top) {
|
|
||||||
initTopComponents();
|
|
||||||
} else {
|
|
||||||
initFrameConponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadSettings();
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import FollowComponent from 'content/components/follow';
|
import FollowComponent from 'content/components/common/follow';
|
||||||
|
|
||||||
describe('FollowComponent', () => {
|
describe('FollowComponent', () => {
|
||||||
describe('#getTargetElements', () => {
|
describe('#getTargetElements', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
document.body.innerHTML = __html__['test/content/components/follow.html'];
|
document.body.innerHTML = __html__['test/content/components/common/follow.html'];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns visible links', () => {
|
it('returns visible links', () => {
|
|
@ -1,9 +1,9 @@
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import Hint from 'content/components/hint';
|
import Hint from 'content/components/common/hint';
|
||||||
|
|
||||||
describe('Hint class', () => {
|
describe('Hint class', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
document.body.innerHTML = __html__['test/content/components/hint.html'];
|
document.body.innerHTML = __html__['test/content/components/common/hint.html'];
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#constructor', () => {
|
describe('#constructor', () => {
|
Reference in a new issue