[wip] content
This commit is contained in:
parent
85b4bd5b07
commit
327144a3aa
6 changed files with 86 additions and 58 deletions
|
@ -20,58 +20,78 @@ const exec = (operation, repeat, settings) => {
|
||||||
case operations.ADDON_TOGGLE_ENABLED:
|
case operations.ADDON_TOGGLE_ENABLED:
|
||||||
return addonActions.toggleEnabled();
|
return addonActions.toggleEnabled();
|
||||||
case operations.FIND_NEXT:
|
case operations.FIND_NEXT:
|
||||||
return window.top.postMessage(JSON.stringify({
|
window.top.postMessage(JSON.stringify({
|
||||||
type: messages.FIND_NEXT,
|
type: messages.FIND_NEXT,
|
||||||
}), '*');
|
}), '*');
|
||||||
|
break;
|
||||||
case operations.FIND_PREV:
|
case operations.FIND_PREV:
|
||||||
return window.top.postMessage(JSON.stringify({
|
window.top.postMessage(JSON.stringify({
|
||||||
type: messages.FIND_PREV,
|
type: messages.FIND_PREV,
|
||||||
}), '*');
|
}), '*');
|
||||||
|
break;
|
||||||
case operations.SCROLL_VERTICALLY:
|
case operations.SCROLL_VERTICALLY:
|
||||||
return scrolls.scrollVertically(operation.count, smoothscroll, repeat);
|
scrolls.scrollVertically(operation.count, smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_HORIZONALLY:
|
case operations.SCROLL_HORIZONALLY:
|
||||||
return scrolls.scrollHorizonally(operation.count, smoothscroll, repeat);
|
scrolls.scrollHorizonally(operation.count, smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_PAGES:
|
case operations.SCROLL_PAGES:
|
||||||
return scrolls.scrollPages(operation.count, smoothscroll, repeat);
|
scrolls.scrollPages(operation.count, smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_TOP:
|
case operations.SCROLL_TOP:
|
||||||
return scrolls.scrollTop(smoothscroll, repeat);
|
scrolls.scrollTop(smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_BOTTOM:
|
case operations.SCROLL_BOTTOM:
|
||||||
return scrolls.scrollBottom(smoothscroll, repeat);
|
scrolls.scrollBottom(smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_HOME:
|
case operations.SCROLL_HOME:
|
||||||
return scrolls.scrollHome(smoothscroll, repeat);
|
scrolls.scrollHome(smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.SCROLL_END:
|
case operations.SCROLL_END:
|
||||||
return scrolls.scrollEnd(smoothscroll, repeat);
|
scrolls.scrollEnd(smoothscroll, repeat);
|
||||||
|
break;
|
||||||
case operations.FOLLOW_START:
|
case operations.FOLLOW_START:
|
||||||
return window.top.postMessage(JSON.stringify({
|
window.top.postMessage(JSON.stringify({
|
||||||
type: messages.FOLLOW_START,
|
type: messages.FOLLOW_START,
|
||||||
newTab: operation.newTab,
|
newTab: operation.newTab,
|
||||||
background: operation.background,
|
background: operation.background,
|
||||||
}), '*');
|
}), '*');
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_HISTORY_PREV:
|
case operations.NAVIGATE_HISTORY_PREV:
|
||||||
return navigates.historyPrev(window);
|
navigates.historyPrev(window);
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_HISTORY_NEXT:
|
case operations.NAVIGATE_HISTORY_NEXT:
|
||||||
return navigates.historyNext(window);
|
navigates.historyNext(window);
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_LINK_PREV:
|
case operations.NAVIGATE_LINK_PREV:
|
||||||
return navigates.linkPrev(window);
|
navigates.linkPrev(window);
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_LINK_NEXT:
|
case operations.NAVIGATE_LINK_NEXT:
|
||||||
return navigates.linkNext(window);
|
navigates.linkNext(window);
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_PARENT:
|
case operations.NAVIGATE_PARENT:
|
||||||
return navigates.parent(window);
|
navigates.parent(window);
|
||||||
|
break;
|
||||||
case operations.NAVIGATE_ROOT:
|
case operations.NAVIGATE_ROOT:
|
||||||
return navigates.root(window);
|
navigates.root(window);
|
||||||
|
break;
|
||||||
case operations.FOCUS_INPUT:
|
case operations.FOCUS_INPUT:
|
||||||
return focuses.focusInput();
|
focuses.focusInput();
|
||||||
|
break;
|
||||||
case operations.URLS_YANK:
|
case operations.URLS_YANK:
|
||||||
urls.yank(window);
|
urls.yank(window);
|
||||||
return consoleFrames.postInfo(window.document, 'Current url yanked');
|
consoleFrames.postInfo(window.document, 'Current url yanked');
|
||||||
|
break;
|
||||||
case operations.URLS_PASTE:
|
case operations.URLS_PASTE:
|
||||||
return urls.paste(window, operation.newTab ? operation.newTab : false);
|
urls.paste(window, operation.newTab ? operation.newTab : false);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
browser.runtime.sendMessage({
|
browser.runtime.sendMessage({
|
||||||
type: messages.BACKGROUND_OPERATION,
|
type: messages.BACKGROUND_OPERATION,
|
||||||
operation,
|
operation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return { type: '' };
|
||||||
};
|
};
|
||||||
|
|
||||||
export { exec };
|
export { exec };
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import actions from 'content/actions';
|
import actions from 'content/actions';
|
||||||
import * as keyUtils from 'shared/utils/keys';
|
import * as keyUtils from 'shared/utils/keys';
|
||||||
import operations from 'shared/operations';
|
import operations from 'shared/operations';
|
||||||
|
import messages from 'shared/messages';
|
||||||
|
|
||||||
const reservedKeymaps = {
|
const reservedKeymaps = {
|
||||||
'<Esc>': { type: operations.CANCEL },
|
'<Esc>': { type: operations.CANCEL },
|
||||||
|
@ -26,4 +27,11 @@ const set = (value) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export { set };
|
const load = async() => {
|
||||||
|
let settings = await browser.runtime.sendMessage({
|
||||||
|
type: messages.SETTINGS_QUERY,
|
||||||
|
});
|
||||||
|
return set(settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { load };
|
||||||
|
|
|
@ -4,6 +4,7 @@ import FollowComponent from './follow';
|
||||||
import * as settingActions from 'content/actions/setting';
|
import * as settingActions from 'content/actions/setting';
|
||||||
import messages from 'shared/messages';
|
import messages from 'shared/messages';
|
||||||
import * as addonActions from '../../actions/addon';
|
import * as addonActions from '../../actions/addon';
|
||||||
|
import * as re from 'shared/utils/re';
|
||||||
|
|
||||||
export default class Common {
|
export default class Common {
|
||||||
constructor(win, store) {
|
constructor(win, store) {
|
||||||
|
@ -14,8 +15,10 @@ export default class Common {
|
||||||
input.onKey(key => follow.key(key));
|
input.onKey(key => follow.key(key));
|
||||||
input.onKey(key => keymapper.key(key));
|
input.onKey(key => keymapper.key(key));
|
||||||
|
|
||||||
|
this.win = win;
|
||||||
this.store = store;
|
this.store = store;
|
||||||
this.prevEnabled = undefined;
|
this.prevEnabled = undefined;
|
||||||
|
this.prevBlacklist = undefined;
|
||||||
|
|
||||||
this.reloadSettings();
|
this.reloadSettings();
|
||||||
|
|
||||||
|
@ -42,14 +45,34 @@ export default class Common {
|
||||||
enabled,
|
enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let blacklist = JSON.stringify(this.store.getState().setting.blacklist);
|
||||||
|
if (blacklist !== this.prevBlacklist) {
|
||||||
|
this.prevBlacklist = blacklist;
|
||||||
|
|
||||||
|
this.disableIfBlack(this.store.getState().setting.blacklist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async reloadSettings() {
|
disableIfBlack(blacklist) {
|
||||||
|
let loc = this.win.location;
|
||||||
|
let partial = loc.host + loc.pathname;
|
||||||
|
let matched = blacklist
|
||||||
|
.map((item) => {
|
||||||
|
let pattern = item.includes('/') ? item : item + '/*';
|
||||||
|
return re.fromWildcard(pattern);
|
||||||
|
})
|
||||||
|
.some(regex => regex.test(partial));
|
||||||
|
if (matched) {
|
||||||
|
this.store.dispatch(addonActions.disable());
|
||||||
|
} else {
|
||||||
|
this.store.dispatch(addonActions.enable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadSettings() {
|
||||||
try {
|
try {
|
||||||
let settings = await browser.runtime.sendMessage({
|
this.store.dispatch(settingActions.load());
|
||||||
type: messages.SETTINGS_QUERY,
|
|
||||||
});
|
|
||||||
this.store.dispatch(settingActions.set(settings));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Sometime sendMessage fails when background script is not ready.
|
// Sometime sendMessage fails when background script is not ready.
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
|
|
|
@ -20,6 +20,7 @@ export default class KeymapperComponent {
|
||||||
this.store = store;
|
this.store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line max-statements
|
||||||
key(key) {
|
key(key) {
|
||||||
this.store.dispatch(inputActions.keyPress(key));
|
this.store.dispatch(inputActions.keyPress(key));
|
||||||
|
|
||||||
|
@ -47,8 +48,8 @@ export default class KeymapperComponent {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let operation = keymaps.get(matched[0]);
|
let operation = keymaps.get(matched[0]);
|
||||||
this.store.dispatch(operationActions.exec(
|
let act = operationActions.exec(operation, key.repeat, state.setting);
|
||||||
operation, key.repeat, state.setting));
|
this.store.dispatch(act);
|
||||||
this.store.dispatch(inputActions.clearKeys());
|
this.store.dispatch(inputActions.clearKeys());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,13 @@ import CommonComponent from '../common';
|
||||||
import FollowController from './follow-controller';
|
import FollowController from './follow-controller';
|
||||||
import FindComponent from './find';
|
import FindComponent from './find';
|
||||||
import * as consoleFrames from '../../console-frames';
|
import * as consoleFrames from '../../console-frames';
|
||||||
import * as addonActions from '../../actions/addon';
|
|
||||||
import messages from 'shared/messages';
|
import messages from 'shared/messages';
|
||||||
import * as re from 'shared/utils/re';
|
|
||||||
|
|
||||||
export default class TopContent {
|
export default class TopContent {
|
||||||
|
|
||||||
constructor(win, store) {
|
constructor(win, store) {
|
||||||
this.win = win;
|
this.win = win;
|
||||||
this.store = store;
|
this.store = store;
|
||||||
this.prevBlacklist = undefined;
|
|
||||||
|
|
||||||
new CommonComponent(win, store); // eslint-disable-line no-new
|
new CommonComponent(win, store); // eslint-disable-line no-new
|
||||||
new FollowController(win, store); // eslint-disable-line no-new
|
new FollowController(win, store); // eslint-disable-line no-new
|
||||||
|
@ -21,32 +18,6 @@ export default class TopContent {
|
||||||
consoleFrames.initialize(this.win.document);
|
consoleFrames.initialize(this.win.document);
|
||||||
|
|
||||||
messages.onMessage(this.onMessage.bind(this));
|
messages.onMessage(this.onMessage.bind(this));
|
||||||
|
|
||||||
this.store.subscribe(() => this.update());
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
let blacklist = this.store.getState().setting.blacklist;
|
|
||||||
if (JSON.stringify(this.prevBlacklist) !== JSON.stringify(blacklist)) {
|
|
||||||
this.disableIfBlack(blacklist);
|
|
||||||
this.prevBlacklist = blacklist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disableIfBlack(blacklist) {
|
|
||||||
let loc = this.win.location;
|
|
||||||
let partial = loc.host + loc.pathname;
|
|
||||||
let matched = blacklist
|
|
||||||
.map((item) => {
|
|
||||||
let pattern = item.includes('/') ? item : item + '/*';
|
|
||||||
return re.fromWildcard(pattern);
|
|
||||||
})
|
|
||||||
.some(regex => regex.test(partial));
|
|
||||||
if (matched) {
|
|
||||||
this.store.dispatch(addonActions.disable());
|
|
||||||
} else {
|
|
||||||
this.store.dispatch(addonActions.enable());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMessage(message) {
|
onMessage(message) {
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import './console-frame.scss';
|
import './console-frame.scss';
|
||||||
import { createStore } from 'shared/store';
|
import { createStore, applyMiddleware } from 'redux';
|
||||||
|
import promise from 'redux-promise';
|
||||||
import reducers from 'content/reducers';
|
import reducers from 'content/reducers';
|
||||||
import TopContentComponent from './components/top-content';
|
import TopContentComponent from './components/top-content';
|
||||||
import FrameContentComponent from './components/frame-content';
|
import FrameContentComponent from './components/frame-content';
|
||||||
|
|
||||||
const store = createStore(reducers);
|
const store = createStore(
|
||||||
|
reducers,
|
||||||
|
applyMiddleware(promise),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
if (window.self === window.top) {
|
if (window.self === window.top) {
|
||||||
new TopContentComponent(window, store); // eslint-disable-line no-new
|
new TopContentComponent(window, store); // eslint-disable-line no-new
|
||||||
|
|
Reference in a new issue