aboutsummaryrefslogtreecommitdiff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/actions/find.js59
-rw-r--r--src/content/actions/follow-controller.js3
-rw-r--r--src/content/actions/operation.js8
-rw-r--r--src/content/actions/setting.js9
-rw-r--r--src/content/components/common/follow.js9
-rw-r--r--src/content/components/common/index.js19
-rw-r--r--src/content/components/common/input.js6
-rw-r--r--src/content/components/top-content/find.js13
-rw-r--r--src/content/components/top-content/follow-controller.js11
-rw-r--r--src/content/components/top-content/index.js9
-rw-r--r--src/content/console-frames.js9
-rw-r--r--src/content/reducers/find.js2
-rw-r--r--src/content/reducers/follow-controller.js2
13 files changed, 113 insertions, 46 deletions
diff --git a/src/content/actions/find.js b/src/content/actions/find.js
index 80d6210..c7345cc 100644
--- a/src/content/actions/find.js
+++ b/src/content/actions/find.js
@@ -5,6 +5,7 @@
// NOTE: window.find is not standard API
// https://developer.mozilla.org/en-US/docs/Web/API/Window/find
+import messages from 'shared/messages';
import actions from 'content/actions';
import * as consoleFrames from '../console-frames';
@@ -14,6 +15,13 @@ const postPatternNotFound = (pattern) => {
'Pattern not found: ' + pattern);
};
+const postPatternFound = (pattern) => {
+ return consoleFrames.postInfo(
+ window.document,
+ 'Pattern found: ' + pattern,
+ );
+};
+
const find = (string, backwards) => {
let caseSensitive = false;
let wrapScan = true;
@@ -24,32 +32,49 @@ const find = (string, backwards) => {
return window.find(string, caseSensitive, backwards, wrapScan);
};
-const findNext = (keyword, reset, backwards) => {
+const findNext = (currentKeyword, reset, backwards) => {
if (reset) {
window.getSelection().removeAllRanges();
}
- let found = find(keyword, backwards);
- if (!found) {
- window.getSelection().removeAllRanges();
- found = find(keyword, backwards);
+ let promise = Promise.resolve(currentKeyword);
+ if (currentKeyword) {
+ browser.runtime.sendMessage({
+ type: messages.FIND_SET_KEYWORD,
+ keyword: currentKeyword,
+ });
+ } else {
+ promise = browser.runtime.sendMessage({
+ type: messages.FIND_GET_KEYWORD,
+ });
}
- if (!found) {
- postPatternNotFound(keyword);
- }
- return {
- type: actions.FIND_SET_KEYWORD,
- keyword,
- found,
- };
+
+ return promise.then((keyword) => {
+ let found = find(keyword, backwards);
+ if (!found) {
+ window.getSelection().removeAllRanges();
+ found = find(keyword, backwards);
+ }
+ if (found) {
+ postPatternFound(keyword);
+ } else {
+ postPatternNotFound(keyword);
+ }
+
+ return {
+ type: actions.FIND_SET_KEYWORD,
+ keyword,
+ found,
+ };
+ });
};
-const next = (keyword, reset) => {
- return findNext(keyword, reset, false);
+const next = (currentKeyword, reset) => {
+ return findNext(currentKeyword, reset, false);
};
-const prev = (keyword, reset) => {
- return findNext(keyword, reset, true);
+const prev = (currentKeyword, reset) => {
+ return findNext(currentKeyword, reset, true);
};
export { next, prev };
diff --git a/src/content/actions/follow-controller.js b/src/content/actions/follow-controller.js
index 3fd4dce..006b248 100644
--- a/src/content/actions/follow-controller.js
+++ b/src/content/actions/follow-controller.js
@@ -1,9 +1,10 @@
import actions from 'content/actions';
-const enable = (newTab) => {
+const enable = (newTab, background) => {
return {
type: actions.FOLLOW_CONTROLLER_ENABLE,
newTab,
+ background,
};
};
diff --git a/src/content/actions/operation.js b/src/content/actions/operation.js
index 5fd0f48..9171766 100644
--- a/src/content/actions/operation.js
+++ b/src/content/actions/operation.js
@@ -44,7 +44,8 @@ const exec = (operation, repeat, settings) => {
case operations.FOLLOW_START:
return window.top.postMessage(JSON.stringify({
type: messages.FOLLOW_START,
- newTab: operation.newTab
+ newTab: operation.newTab,
+ background: operation.background,
}), '*');
case operations.NAVIGATE_HISTORY_PREV:
return navigates.historyPrev(window);
@@ -62,10 +63,7 @@ const exec = (operation, repeat, settings) => {
return focuses.focusInput();
case operations.URLS_YANK:
urls.yank(window);
- return consoleFrames.postMessage(window.document, {
- type: messages.CONSOLE_SHOW_INFO,
- text: 'Current url yanked',
- });
+ return consoleFrames.postInfo(window.document, 'Current url yanked');
case operations.URLS_PASTE:
return urls.paste(window, operation.newTab ? operation.newTab : false);
default:
diff --git a/src/content/actions/setting.js b/src/content/actions/setting.js
index 0238c71..4c1e385 100644
--- a/src/content/actions/setting.js
+++ b/src/content/actions/setting.js
@@ -1,10 +1,17 @@
import actions from 'content/actions';
import * as keyUtils from 'shared/utils/keys';
+import operations from 'shared/operations';
+
+const reservedKeymaps = {
+ '<Esc>': { type: operations.CANCEL },
+ '<C-[>': { type: operations.CANCEL },
+};
const set = (value) => {
let entries = [];
if (value.keymaps) {
- entries = Object.entries(value.keymaps).map((entry) => {
+ let keymaps = Object.assign({}, value.keymaps, reservedKeymaps);
+ entries = Object.entries(keymaps).map((entry) => {
return [
keyUtils.fromMapKeys(entry[0]),
entry[1],
diff --git a/src/content/components/common/follow.js b/src/content/components/common/follow.js
index 42dd897..2a55ea3 100644
--- a/src/content/components/common/follow.js
+++ b/src/content/components/common/follow.js
@@ -50,6 +50,7 @@ export default class Follow {
this.win = win;
this.store = store;
this.newTab = false;
+ this.background = false;
this.hints = {};
this.targets = [];
@@ -63,6 +64,7 @@ export default class Follow {
this.win.parent.postMessage(JSON.stringify({
type: messages.FOLLOW_KEY_PRESS,
key: key.key,
+ ctrlKey: key.ctrlKey,
}), '*');
return true;
}
@@ -84,6 +86,7 @@ export default class Follow {
type: messages.OPEN_URL,
url: element.href,
newTab: true,
+ background: this.background,
});
}
@@ -95,12 +98,13 @@ export default class Follow {
}), '*');
}
- createHints(keysArray, newTab) {
+ createHints(keysArray, newTab, background) {
if (keysArray.length !== this.targets.length) {
throw new Error('illegal hint count');
}
this.newTab = newTab;
+ this.background = background;
this.hints = {};
for (let i = 0; i < keysArray.length; ++i) {
let keys = keysArray[i];
@@ -166,7 +170,8 @@ export default class Follow {
case messages.FOLLOW_REQUEST_COUNT_TARGETS:
return this.countHints(sender, message.viewSize, message.framePosition);
case messages.FOLLOW_CREATE_HINTS:
- return this.createHints(message.keysArray, message.newTab);
+ return this.createHints(
+ message.keysArray, message.newTab, message.background);
case messages.FOLLOW_SHOW_HINTS:
return this.showHints(message.keys);
case messages.FOLLOW_ACTIVATE:
diff --git a/src/content/components/common/index.js b/src/content/components/common/index.js
index 565632c..9b7b083 100644
--- a/src/content/components/common/index.js
+++ b/src/content/components/common/index.js
@@ -3,6 +3,7 @@ import KeymapperComponent from './keymapper';
import FollowComponent from './follow';
import * as settingActions from 'content/actions/setting';
import messages from 'shared/messages';
+import * as addonActions from '../../actions/addon';
export default class Common {
constructor(win, store) {
@@ -14,16 +15,32 @@ export default class Common {
input.onKey(key => keymapper.key(key));
this.store = store;
+ this.prevEnabled = undefined;
this.reloadSettings();
messages.onMessage(this.onMessage.bind(this));
+ store.subscribe(() => this.update());
}
onMessage(message) {
switch (message.type) {
case messages.SETTINGS_CHANGED:
- this.reloadSettings();
+ return this.reloadSettings();
+ case messages.ADDON_TOGGLE_ENABLED:
+ return this.store.dispatch(addonActions.toggleEnabled());
+ }
+ }
+
+ update() {
+ let enabled = this.store.getState().addon.enabled;
+ if (enabled !== this.prevEnabled) {
+ this.prevEnabled = enabled;
+
+ browser.runtime.sendMessage({
+ type: messages.ADDON_ENABLED_RESPONSE,
+ enabled,
+ });
}
}
diff --git a/src/content/components/common/input.js b/src/content/components/common/input.js
index 22b0a91..eefaf10 100644
--- a/src/content/components/common/input.js
+++ b/src/content/components/common/input.js
@@ -1,6 +1,10 @@
import * as dom from 'shared/utils/dom';
import * as keys from 'shared/utils/keys';
+const cancelKey = (e) => {
+ return e.key === 'Escape' || e.key === '[' && e.ctrlKey;
+};
+
export default class InputComponent {
constructor(target) {
this.pressed = {};
@@ -37,7 +41,7 @@ export default class InputComponent {
capture(e) {
if (this.fromInput(e)) {
- if (e.key === 'Escape' && e.target.blur) {
+ if (cancelKey(e) && e.target.blur) {
e.target.blur();
}
return;
diff --git a/src/content/components/top-content/find.js b/src/content/components/top-content/find.js
index bccf040..4d46d79 100644
--- a/src/content/components/top-content/find.js
+++ b/src/content/components/top-content/find.js
@@ -1,6 +1,5 @@
import * as findActions from 'content/actions/find';
import messages from 'shared/messages';
-import * as consoleFrames from '../../console-frames';
export default class FindComponent {
constructor(win, store) {
@@ -32,23 +31,11 @@ export default class FindComponent {
next() {
let state = this.store.getState().find;
-
- if (!state.found) {
- return consoleFrames.postError(
- window.document,
- 'Pattern not found: ' + state.keyword);
- }
return this.store.dispatch(findActions.next(state.keyword, false));
}
prev() {
let state = this.store.getState().find;
-
- if (!state.found) {
- return consoleFrames.postError(
- window.document,
- 'Pattern not found: ' + state.keyword);
- }
return this.store.dispatch(findActions.prev(state.keyword, false));
}
}
diff --git a/src/content/components/top-content/follow-controller.js b/src/content/components/top-content/follow-controller.js
index 1e7f3cd..7f36604 100644
--- a/src/content/components/top-content/follow-controller.js
+++ b/src/content/components/top-content/follow-controller.js
@@ -28,11 +28,11 @@ export default class FollowController {
switch (message.type) {
case messages.FOLLOW_START:
return this.store.dispatch(
- followControllerActions.enable(message.newTab));
+ followControllerActions.enable(message.newTab, message.background));
case messages.FOLLOW_RESPONSE_COUNT_TARGETS:
return this.create(message.count, sender);
case messages.FOLLOW_KEY_PRESS:
- return this.keyPress(message.key);
+ return this.keyPress(message.key, message.ctrlKey);
}
}
@@ -69,7 +69,11 @@ export default class FollowController {
});
}
- keyPress(key) {
+ keyPress(key, ctrlKey) {
+ if (key === '[' && ctrlKey) {
+ this.store.dispatch(followControllerActions.disable());
+ return true;
+ }
switch (key) {
case 'Enter':
this.activate();
@@ -125,6 +129,7 @@ export default class FollowController {
type: messages.FOLLOW_CREATE_HINTS,
keysArray: produced,
newTab: this.state.newTab,
+ background: this.state.background,
}), '*');
}
diff --git a/src/content/components/top-content/index.js b/src/content/components/top-content/index.js
index cf21ec4..a0d0480 100644
--- a/src/content/components/top-content/index.js
+++ b/src/content/components/top-content/index.js
@@ -44,15 +44,24 @@ export default class TopContent {
.some(regex => regex.test(partial));
if (matched) {
this.store.dispatch(addonActions.disable());
+ } else {
+ this.store.dispatch(addonActions.enable());
}
}
onMessage(message) {
+ let addonState = this.store.getState().addon;
+
switch (message.type) {
case messages.CONSOLE_UNFOCUS:
this.win.focus();
consoleFrames.blur(window.document);
return Promise.resolve();
+ case messages.ADDON_ENABLED_QUERY:
+ return Promise.resolve({
+ type: messages.ADDON_ENABLED_RESPONSE,
+ enabled: addonState.enabled,
+ });
}
}
}
diff --git a/src/content/console-frames.js b/src/content/console-frames.js
index 515ae09..0c0ec02 100644
--- a/src/content/console-frames.js
+++ b/src/content/console-frames.js
@@ -28,4 +28,11 @@ const postError = (doc, message) => {
});
};
-export { initialize, blur, postMessage, postError };
+const postInfo = (doc, message) => {
+ return postMessage(doc, {
+ type: messages.CONSOLE_SHOW_INFO,
+ text: message,
+ });
+};
+
+export { initialize, blur, postError, postInfo };
diff --git a/src/content/reducers/find.js b/src/content/reducers/find.js
index eb43c37..8d63ee5 100644
--- a/src/content/reducers/find.js
+++ b/src/content/reducers/find.js
@@ -1,7 +1,7 @@
import actions from 'content/actions';
const defaultState = {
- keyword: '',
+ keyword: null,
found: false,
};
diff --git a/src/content/reducers/follow-controller.js b/src/content/reducers/follow-controller.js
index 2afb232..78fd848 100644
--- a/src/content/reducers/follow-controller.js
+++ b/src/content/reducers/follow-controller.js
@@ -3,6 +3,7 @@ import actions from 'content/actions';
const defaultState = {
enabled: false,
newTab: false,
+ background: false,
keys: '',
};
@@ -12,6 +13,7 @@ export default function reducer(state = defaultState, action = {}) {
return Object.assign({}, state, {
enabled: true,
newTab: action.newTab,
+ background: action.background,
keys: '',
});
case actions.FOLLOW_CONTROLLER_DISABLE: