Merge pull request #386 from ueokande/addon-enabled-indicator
Addon enabled indicator
This commit is contained in:
commit
104a9666ff
26 changed files with 329 additions and 132 deletions
|
@ -40,5 +40,11 @@
|
|||
],
|
||||
"options_ui": {
|
||||
"page": "build/settings.html"
|
||||
},
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"32": "resources/enabled_32x32.png"
|
||||
},
|
||||
"default_title": "Vim Vixen"
|
||||
}
|
||||
}
|
||||
|
|
BIN
resources/disabled_32x32.png
Normal file
BIN
resources/disabled_32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/enabled_32x32.png
Normal file
BIN
resources/enabled_32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -1,5 +1,5 @@
|
|||
import actions from '../actions';
|
||||
import * as tabs from 'background/tabs';
|
||||
import * as tabs from '../shared/tabs';
|
||||
import * as parsers from 'shared/commands/parsers';
|
||||
import * as properties from 'shared/settings/properties';
|
||||
|
||||
|
|
|
@ -5,4 +5,7 @@ export default {
|
|||
|
||||
// Find
|
||||
FIND_SET_KEYWORD: 'find.set.keyword',
|
||||
|
||||
// Tab
|
||||
TAB_SELECTED: 'tab.selected',
|
||||
};
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import operations from 'shared/operations';
|
||||
import messages from 'shared/messages';
|
||||
import * as tabs from 'background/tabs';
|
||||
import * as zooms from 'background/zooms';
|
||||
|
||||
const sendConsoleShowCommand = (tab, command) => {
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_SHOW_COMMAND,
|
||||
command,
|
||||
});
|
||||
};
|
||||
|
||||
// This switch statement is only gonna get longer as more
|
||||
// features are added, so disable complexity check
|
||||
/* eslint-disable complexity */
|
||||
const exec = (operation, tab) => {
|
||||
switch (operation.type) {
|
||||
case operations.TAB_CLOSE:
|
||||
return tabs.closeTab(tab.id);
|
||||
case operations.TAB_CLOSE_FORCE:
|
||||
return tabs.closeTabForce(tab.id);
|
||||
case operations.TAB_REOPEN:
|
||||
return tabs.reopenTab();
|
||||
case operations.TAB_PREV:
|
||||
return tabs.selectPrevTab(tab.index, operation.count);
|
||||
case operations.TAB_NEXT:
|
||||
return tabs.selectNextTab(tab.index, operation.count);
|
||||
case operations.TAB_FIRST:
|
||||
return tabs.selectFirstTab();
|
||||
case operations.TAB_LAST:
|
||||
return tabs.selectLastTab();
|
||||
case operations.TAB_PREV_SEL:
|
||||
return tabs.selectPrevSelTab();
|
||||
case operations.TAB_RELOAD:
|
||||
return tabs.reload(tab, operation.cache);
|
||||
case operations.TAB_PIN:
|
||||
return tabs.updateTabPinned(tab, true);
|
||||
case operations.TAB_UNPIN:
|
||||
return tabs.updateTabPinned(tab, false);
|
||||
case operations.TAB_TOGGLE_PINNED:
|
||||
return tabs.toggleTabPinned(tab);
|
||||
case operations.TAB_DUPLICATE:
|
||||
return tabs.duplicate(tab.id);
|
||||
case operations.ZOOM_IN:
|
||||
return zooms.zoomIn();
|
||||
case operations.ZOOM_OUT:
|
||||
return zooms.zoomOut();
|
||||
case operations.ZOOM_NEUTRAL:
|
||||
return zooms.neutral();
|
||||
case operations.COMMAND_SHOW:
|
||||
return sendConsoleShowCommand(tab, '');
|
||||
case operations.COMMAND_SHOW_OPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return sendConsoleShowCommand(tab, 'open ' + tab.url);
|
||||
}
|
||||
return sendConsoleShowCommand(tab, 'open ');
|
||||
case operations.COMMAND_SHOW_TABOPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return sendConsoleShowCommand(tab, 'tabopen ' + tab.url);
|
||||
}
|
||||
return sendConsoleShowCommand(tab, 'tabopen ');
|
||||
case operations.COMMAND_SHOW_WINOPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return sendConsoleShowCommand(tab, 'winopen ' + tab.url);
|
||||
}
|
||||
return sendConsoleShowCommand(tab, 'winopen ');
|
||||
case operations.COMMAND_SHOW_BUFFER:
|
||||
return sendConsoleShowCommand(tab, 'buffer ');
|
||||
case operations.FIND_START:
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_SHOW_FIND
|
||||
});
|
||||
case operations.CANCEL:
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_HIDE,
|
||||
});
|
||||
case operations.PAGE_SOURCE:
|
||||
return browser.tabs.create({
|
||||
url: 'view-source:' + tab.url,
|
||||
index: tab.index + 1,
|
||||
openerTabId: tab.id,
|
||||
});
|
||||
default:
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
/* eslint-enable complexity */
|
||||
|
||||
export { exec };
|
|
@ -1,3 +1,5 @@
|
|||
import actions from './index';
|
||||
|
||||
const openNewTab = (url, openerTabId, background = false, adjacent = false) => {
|
||||
if (adjacent) {
|
||||
return browser.tabs.query({
|
||||
|
@ -18,4 +20,11 @@ const openToTab = (url, tab) => {
|
|||
return browser.tabs.update(tab.id, { url: url });
|
||||
};
|
||||
|
||||
export { openNewTab, openToTab };
|
||||
const selected = (tabId) => {
|
||||
return {
|
||||
type: actions.TAB_SELECTED,
|
||||
tabId,
|
||||
};
|
||||
};
|
||||
|
||||
export { openNewTab, openToTab, selected };
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import messages from 'shared/messages';
|
||||
import * as operationActions from 'background/actions/operation';
|
||||
import * as commandActions from 'background/actions/command';
|
||||
import * as settingActions from 'background/actions/setting';
|
||||
import * as findActions from 'background/actions/find';
|
||||
import * as tabActions from 'background/actions/tab';
|
||||
import * as commands from 'shared/commands';
|
||||
import * as completions from '../shared/completions';
|
||||
|
||||
export default class BackgroundComponent {
|
||||
constructor(store) {
|
||||
|
@ -27,10 +26,6 @@ export default class BackgroundComponent {
|
|||
let find = this.store.getState().find;
|
||||
|
||||
switch (message.type) {
|
||||
case messages.BACKGROUND_OPERATION:
|
||||
return this.store.dispatch(
|
||||
operationActions.exec(message.operation, sender.tab),
|
||||
sender);
|
||||
case messages.OPEN_URL:
|
||||
if (message.newTab) {
|
||||
let action = tabActions.openNewTab(
|
||||
|
@ -49,7 +44,7 @@ export default class BackgroundComponent {
|
|||
case messages.SETTINGS_QUERY:
|
||||
return Promise.resolve(this.store.getState().setting.value);
|
||||
case messages.CONSOLE_QUERY_COMPLETIONS:
|
||||
return commands.complete(message.text, settings.value);
|
||||
return completions.complete(message.text, settings.value);
|
||||
case messages.SETTINGS_RELOAD:
|
||||
this.store.dispatch(settingActions.load());
|
||||
return this.broadcastSettingsChanged();
|
||||
|
|
45
src/background/components/indicator.js
Normal file
45
src/background/components/indicator.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import * as indicators from '../shared/indicators';
|
||||
import messages from 'shared/messages';
|
||||
|
||||
export default class IndicatorComponent {
|
||||
constructor(store) {
|
||||
this.store = store;
|
||||
|
||||
messages.onMessage(this.onMessage.bind(this));
|
||||
|
||||
browser.browserAction.onClicked.addListener(this.onClicked);
|
||||
browser.tabs.onActivated.addListener((info) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then(() => {
|
||||
return this.onTabActivated(info);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onTabActivated(info) {
|
||||
return browser.tabs.sendMessage(info.tabId, {
|
||||
type: messages.ADDON_ENABLED_QUERY,
|
||||
}).then((resp) => {
|
||||
return this.updateIndicator(resp.enabled);
|
||||
});
|
||||
}
|
||||
|
||||
onClicked(tab) {
|
||||
browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.ADDON_TOGGLE_ENABLED,
|
||||
});
|
||||
}
|
||||
|
||||
onMessage(message) {
|
||||
switch (message.type) {
|
||||
case messages.ADDON_ENABLED_RESPONSE:
|
||||
return this.updateIndicator(message.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
updateIndicator(enabled) {
|
||||
if (enabled) {
|
||||
return indicators.enable();
|
||||
}
|
||||
return indicators.disable();
|
||||
}
|
||||
}
|
118
src/background/components/operation.js
Normal file
118
src/background/components/operation.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
import messages from 'shared/messages';
|
||||
import operations from 'shared/operations';
|
||||
import * as tabs from '../shared//tabs';
|
||||
import * as zooms from '../shared/zooms';
|
||||
|
||||
export default class BackgroundComponent {
|
||||
constructor(store) {
|
||||
this.store = store;
|
||||
|
||||
browser.runtime.onMessage.addListener((message, sender) => {
|
||||
try {
|
||||
return this.onMessage(message, sender);
|
||||
} catch (e) {
|
||||
return browser.tabs.sendMessage(sender.tab.id, {
|
||||
type: messages.CONSOLE_SHOW_ERROR,
|
||||
text: e.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMessage(message, sender) {
|
||||
switch (message.type) {
|
||||
case messages.BACKGROUND_OPERATION:
|
||||
return this.store.dispatch(
|
||||
this.exec(message.operation, sender.tab),
|
||||
sender);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
exec(operation, tab) {
|
||||
let tabState = this.store.getState().tab;
|
||||
|
||||
switch (operation.type) {
|
||||
case operations.TAB_CLOSE:
|
||||
return tabs.closeTab(tab.id);
|
||||
case operations.TAB_CLOSE_FORCE:
|
||||
return tabs.closeTabForce(tab.id);
|
||||
case operations.TAB_REOPEN:
|
||||
return tabs.reopenTab();
|
||||
case operations.TAB_PREV:
|
||||
return tabs.selectPrevTab(tab.index, operation.count);
|
||||
case operations.TAB_NEXT:
|
||||
return tabs.selectNextTab(tab.index, operation.count);
|
||||
case operations.TAB_FIRST:
|
||||
return tabs.selectFirstTab();
|
||||
case operations.TAB_LAST:
|
||||
return tabs.selectLastTab();
|
||||
case operations.TAB_PREV_SEL:
|
||||
if (tabState.previousSelected > 0) {
|
||||
return tabs.selectTab(tabState.previousSelected);
|
||||
}
|
||||
break;
|
||||
case operations.TAB_RELOAD:
|
||||
return tabs.reload(tab, operation.cache);
|
||||
case operations.TAB_PIN:
|
||||
return tabs.updateTabPinned(tab, true);
|
||||
case operations.TAB_UNPIN:
|
||||
return tabs.updateTabPinned(tab, false);
|
||||
case operations.TAB_TOGGLE_PINNED:
|
||||
return tabs.toggleTabPinned(tab);
|
||||
case operations.TAB_DUPLICATE:
|
||||
return tabs.duplicate(tab.id);
|
||||
case operations.ZOOM_IN:
|
||||
return zooms.zoomIn();
|
||||
case operations.ZOOM_OUT:
|
||||
return zooms.zoomOut();
|
||||
case operations.ZOOM_NEUTRAL:
|
||||
return zooms.neutral();
|
||||
case operations.COMMAND_SHOW:
|
||||
return this.sendConsoleShowCommand(tab, '');
|
||||
case operations.COMMAND_SHOW_OPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return this.sendConsoleShowCommand(tab, 'open ' + tab.url);
|
||||
}
|
||||
return this.sendConsoleShowCommand(tab, 'open ');
|
||||
case operations.COMMAND_SHOW_TABOPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return this.sendConsoleShowCommand(tab, 'tabopen ' + tab.url);
|
||||
}
|
||||
return this.sendConsoleShowCommand(tab, 'tabopen ');
|
||||
case operations.COMMAND_SHOW_WINOPEN:
|
||||
if (operation.alter) {
|
||||
// alter url
|
||||
return this.sendConsoleShowCommand(tab, 'winopen ' + tab.url);
|
||||
}
|
||||
return this.sendConsoleShowCommand(tab, 'winopen ');
|
||||
case operations.COMMAND_SHOW_BUFFER:
|
||||
return this.sendConsoleShowCommand(tab, 'buffer ');
|
||||
case operations.FIND_START:
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_SHOW_FIND
|
||||
});
|
||||
case operations.CANCEL:
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_HIDE,
|
||||
});
|
||||
case operations.PAGE_SOURCE:
|
||||
return browser.tabs.create({
|
||||
url: 'view-source:' + tab.url,
|
||||
index: tab.index + 1,
|
||||
openerTabId: tab.id,
|
||||
});
|
||||
default:
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
sendConsoleShowCommand(tab, command) {
|
||||
return browser.tabs.sendMessage(tab.id, {
|
||||
type: messages.CONSOLE_SHOW_COMMAND,
|
||||
command,
|
||||
});
|
||||
}
|
||||
}
|
17
src/background/components/tab.js
Normal file
17
src/background/components/tab.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import * as tabActions from '../actions/tab';
|
||||
|
||||
export default class TabComponent {
|
||||
constructor(store) {
|
||||
this.store = store;
|
||||
|
||||
browser.tabs.onActivated.addListener((info) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then(() => {
|
||||
return this.onTabActivated(info);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onTabActivated(info) {
|
||||
return this.store.dispatch(tabActions.selected(info.tabId));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
import * as settingActions from 'background/actions/setting';
|
||||
import messages from 'shared/messages';
|
||||
import BackgroundComponent from 'background/components/background';
|
||||
import OperationComponent from 'background/components/operation';
|
||||
import TabComponent from 'background/components/tab';
|
||||
import IndicatorComponent from 'background/components/indicator';
|
||||
import reducers from 'background/reducers';
|
||||
import { createStore } from 'shared/store';
|
||||
import * as versions from 'shared/versions';
|
||||
|
@ -14,8 +17,13 @@ const store = createStore(reducers, (e, sender) => {
|
|||
});
|
||||
}
|
||||
});
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
const backgroundComponent = new BackgroundComponent(store);
|
||||
const operationComponent = new OperationComponent(store);
|
||||
const tabComponent = new TabComponent(store);
|
||||
const indicatorComponent = new IndicatorComponent(store);
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
store.dispatch(settingActions.load());
|
||||
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import settingReducer from './setting';
|
||||
import findReducer from './find';
|
||||
import tabReducer from './tab';
|
||||
|
||||
// Make setting reducer instead of re-use
|
||||
const defaultState = {
|
||||
setting: settingReducer(undefined, {}),
|
||||
find: findReducer(undefined, {}),
|
||||
tab: tabReducer(undefined, {}),
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action = {}) {
|
||||
return Object.assign({}, state, {
|
||||
setting: settingReducer(state.setting, action),
|
||||
find: findReducer(state.find, action),
|
||||
tab: tabReducer(state.tab, action),
|
||||
});
|
||||
}
|
||||
|
|
19
src/background/reducers/tab.js
Normal file
19
src/background/reducers/tab.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import actions from 'background/actions';
|
||||
|
||||
const defaultState = {
|
||||
previousSelected: -1,
|
||||
currentSelected: -1,
|
||||
};
|
||||
|
||||
export default function reducer(state = defaultState, action = {}) {
|
||||
switch (action.type) {
|
||||
case actions.TAB_SELECTED:
|
||||
return {
|
||||
previousSelected: state.currentSelected,
|
||||
currentSelected: action.tabId,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import * as tabs from 'background/tabs';
|
||||
import * as histories from 'background/histories';
|
||||
import * as tabs from './tabs';
|
||||
import * as histories from './histories';
|
||||
|
||||
const getOpenCompletions = (command, keywords, searchConfig) => {
|
||||
return histories.getCompletions(keywords).then((pages) => {
|
||||
|
@ -81,4 +81,4 @@ const complete = (line, settings) => {
|
|||
return getCompletions(line, settings);
|
||||
};
|
||||
|
||||
export default complete;
|
||||
export { complete };
|
10
src/background/shared/completions/tabs.js
Normal file
10
src/background/shared/completions/tabs.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const getCompletions = (keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title && t.title.includes(keyword);
|
||||
});
|
||||
return matched;
|
||||
});
|
||||
};
|
||||
|
||||
export { getCompletions };
|
13
src/background/shared/indicators.js
Normal file
13
src/background/shared/indicators.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const enable = () => {
|
||||
return browser.browserAction.setIcon({
|
||||
path: 'resources/enabled_32x32.png',
|
||||
});
|
||||
};
|
||||
|
||||
const disable = () => {
|
||||
return browser.browserAction.setIcon({
|
||||
path: 'resources/disabled_32x32.png',
|
||||
});
|
||||
};
|
||||
|
||||
export { enable, disable };
|
|
@ -1,13 +1,3 @@
|
|||
let prevSelTab = 1;
|
||||
let currSelTab = 1;
|
||||
|
||||
browser.tabs.onActivated.addListener((activeInfo) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then(() => {
|
||||
prevSelTab = currSelTab;
|
||||
currSelTab = activeInfo.tabId;
|
||||
});
|
||||
});
|
||||
|
||||
const closeTab = (id) => {
|
||||
return browser.tabs.get(id).then((tab) => {
|
||||
if (!tab.pinned) {
|
||||
|
@ -66,15 +56,6 @@ const selectByKeyword = (current, keyword) => {
|
|||
});
|
||||
};
|
||||
|
||||
const getCompletions = (keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title && t.title.includes(keyword);
|
||||
});
|
||||
return matched;
|
||||
});
|
||||
};
|
||||
|
||||
const selectPrevTab = (current, count) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length < 2) {
|
||||
|
@ -111,8 +92,8 @@ const selectLastTab = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const selectPrevSelTab = () => {
|
||||
return browser.tabs.update(prevSelTab, { active: true });
|
||||
const selectTab = (id) => {
|
||||
return browser.tabs.update(id, { active: true });
|
||||
};
|
||||
|
||||
const reload = (current, cache) => {
|
||||
|
@ -139,7 +120,7 @@ const duplicate = (id) => {
|
|||
|
||||
export {
|
||||
closeTab, closeTabForce, reopenTab, selectAt, selectByKeyword,
|
||||
getCompletions, selectPrevTab, selectNextTab, selectFirstTab,
|
||||
selectLastTab, selectPrevSelTab, reload, updateTabPinned,
|
||||
selectPrevTab, selectNextTab, selectFirstTab,
|
||||
selectLastTab, selectTab, reload, updateTabPinned,
|
||||
toggleTabPinned, duplicate
|
||||
};
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
import complete from './complete';
|
||||
|
||||
export { complete };
|
|
@ -48,6 +48,10 @@ export default {
|
|||
FIND_GET_KEYWORD: 'find.get.keyword',
|
||||
FIND_SET_KEYWORD: 'find.set.keyword',
|
||||
|
||||
ADDON_ENABLED_QUERY: 'addon.enabled.query',
|
||||
ADDON_ENABLED_RESPONSE: 'addon.enabled.response',
|
||||
ADDON_TOGGLE_ENABLED: 'addon.toggle.enabled',
|
||||
|
||||
OPEN_URL: 'open.url',
|
||||
|
||||
SETTINGS_RELOAD: 'settings.reload',
|
||||
|
|
13
test/background/actions/tab.test.js
Normal file
13
test/background/actions/tab.test.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import actions from 'background/actions';
|
||||
import * as tabActions from 'background/actions/tab';
|
||||
|
||||
describe("tab actions", () => {
|
||||
describe("selected", () => {
|
||||
it('create TAB_SELECTED action', () => {
|
||||
let action = tabActions.selected(123);
|
||||
expect(action.type).to.equal(actions.TAB_SELECTED);
|
||||
expect(action.tabId).to.equal(123);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
22
test/background/reducers/tab.test.js
Normal file
22
test/background/reducers/tab.test.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import actions from 'background/actions';
|
||||
import tabReducer from 'background/reducers/tab';
|
||||
|
||||
describe("tab reducer", () => {
|
||||
it('return the initial state', () => {
|
||||
let state = tabReducer(undefined, {});
|
||||
expect(state.previousSelected).to.equal(-1);
|
||||
expect(state.currentSelected).to.equal(-1);
|
||||
});
|
||||
|
||||
it('return next state for TAB_SELECTED', () => {
|
||||
let state = undefined;
|
||||
|
||||
state = tabReducer(state, { type: actions.TAB_SELECTED, tabId: 123 });
|
||||
expect(state.previousSelected).to.equal(-1);
|
||||
expect(state.currentSelected).to.equal(123);
|
||||
|
||||
state = tabReducer(state, { type: actions.TAB_SELECTED, tabId: 456 });
|
||||
expect(state.previousSelected).to.equal(123);
|
||||
expect(state.currentSelected).to.equal(456);
|
||||
});
|
||||
});
|
Reference in a new issue