[wip] content

jh-changes
Shin'ya Ueoka 6 years ago
parent 85b4bd5b07
commit 327144a3aa
  1. 58
      src/content/actions/operation.js
  2. 10
      src/content/actions/setting.js
  3. 33
      src/content/components/common/index.js
  4. 5
      src/content/components/common/keymapper.js
  5. 29
      src/content/components/top-content/index.js
  6. 9
      src/content/index.js

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