parent
992b3ac65d
commit
d01db82c0d
62 changed files with 1426 additions and 483 deletions
@ -0,0 +1,32 @@ |
||||
import { Message, valueOf } from '../shared/messages'; |
||||
|
||||
export type WebMessageSender = Window | MessagePort | ServiceWorker | null; |
||||
export type WebExtMessageSender = browser.runtime.MessageSender; |
||||
|
||||
export default class MessageListener { |
||||
onWebMessage( |
||||
listener: (msg: Message, sender: WebMessageSender) => void, |
||||
) { |
||||
window.addEventListener('message', (event: MessageEvent) => { |
||||
let sender = event.source; |
||||
let message = null; |
||||
try { |
||||
message = JSON.parse(event.data); |
||||
} catch (e) { |
||||
// ignore unexpected message
|
||||
return; |
||||
} |
||||
listener(message, sender); |
||||
}); |
||||
} |
||||
|
||||
onBackgroundMessage( |
||||
listener: (msg: Message, sender: WebExtMessageSender) => any, |
||||
) { |
||||
browser.runtime.onMessage.addListener( |
||||
(msg: any, sender: WebExtMessageSender) => { |
||||
listener(valueOf(msg), sender); |
||||
}, |
||||
); |
||||
} |
||||
} |
@ -1,31 +1,120 @@ |
||||
export default { |
||||
// Enable/disable
|
||||
ADDON_SET_ENABLED: 'addon.set.enabled', |
||||
|
||||
// Settings
|
||||
SETTING_SET: 'setting.set', |
||||
|
||||
// User input
|
||||
INPUT_KEY_PRESS: 'input.key.press', |
||||
INPUT_CLEAR_KEYS: 'input.clear.keys', |
||||
|
||||
// Completion
|
||||
COMPLETION_SET_ITEMS: 'completion.set.items', |
||||
COMPLETION_SELECT_NEXT: 'completions.select.next', |
||||
COMPLETION_SELECT_PREV: 'completions.select.prev', |
||||
|
||||
// Follow
|
||||
FOLLOW_CONTROLLER_ENABLE: 'follow.controller.enable', |
||||
FOLLOW_CONTROLLER_DISABLE: 'follow.controller.disable', |
||||
FOLLOW_CONTROLLER_KEY_PRESS: 'follow.controller.key.press', |
||||
FOLLOW_CONTROLLER_BACKSPACE: 'follow.controller.backspace', |
||||
|
||||
// Find
|
||||
FIND_SET_KEYWORD: 'find.set.keyword', |
||||
|
||||
// Mark
|
||||
MARK_START_SET: 'mark.start.set', |
||||
MARK_START_JUMP: 'mark.start.jump', |
||||
MARK_CANCEL: 'mark.cancel', |
||||
MARK_SET_LOCAL: 'mark.set.local', |
||||
}; |
||||
import Redux from 'redux'; |
||||
|
||||
// Enable/disable
|
||||
export const ADDON_SET_ENABLED = 'addon.set.enabled'; |
||||
|
||||
// Find
|
||||
export const FIND_SET_KEYWORD = 'find.set.keyword'; |
||||
|
||||
// Settings
|
||||
export const SETTING_SET = 'setting.set'; |
||||
|
||||
// User input
|
||||
export const INPUT_KEY_PRESS = 'input.key.press'; |
||||
export const INPUT_CLEAR_KEYS = 'input.clear.keys'; |
||||
|
||||
// Completion
|
||||
export const COMPLETION_SET_ITEMS = 'completion.set.items'; |
||||
export const COMPLETION_SELECT_NEXT = 'completions.select.next'; |
||||
export const COMPLETION_SELECT_PREV = 'completions.select.prev'; |
||||
|
||||
// Follow
|
||||
export const FOLLOW_CONTROLLER_ENABLE = 'follow.controller.enable'; |
||||
export const FOLLOW_CONTROLLER_DISABLE = 'follow.controller.disable'; |
||||
export const FOLLOW_CONTROLLER_KEY_PRESS = 'follow.controller.key.press'; |
||||
export const FOLLOW_CONTROLLER_BACKSPACE = 'follow.controller.backspace'; |
||||
|
||||
// Mark
|
||||
export const MARK_START_SET = 'mark.start.set'; |
||||
export const MARK_START_JUMP = 'mark.start.jump'; |
||||
export const MARK_CANCEL = 'mark.cancel'; |
||||
export const MARK_SET_LOCAL = 'mark.set.local'; |
||||
|
||||
export const NOOP = 'noop'; |
||||
|
||||
export interface AddonSetEnabledAction extends Redux.Action { |
||||
type: typeof ADDON_SET_ENABLED; |
||||
enabled: boolean; |
||||
} |
||||
|
||||
export interface FindSetKeywordAction extends Redux.Action { |
||||
type: typeof FIND_SET_KEYWORD; |
||||
keyword: string; |
||||
found: boolean; |
||||
} |
||||
|
||||
export interface SettingSetAction extends Redux.Action { |
||||
type: typeof SETTING_SET; |
||||
value: any; |
||||
} |
||||
|
||||
export interface InputKeyPressAction extends Redux.Action { |
||||
type: typeof INPUT_KEY_PRESS; |
||||
key: string; |
||||
} |
||||
|
||||
export interface InputClearKeysAction extends Redux.Action { |
||||
type: typeof INPUT_CLEAR_KEYS; |
||||
} |
||||
|
||||
export interface FollowControllerEnableAction extends Redux.Action { |
||||
type: typeof FOLLOW_CONTROLLER_ENABLE; |
||||
newTab: boolean; |
||||
background: boolean; |
||||
} |
||||
|
||||
export interface FollowControllerDisableAction extends Redux.Action { |
||||
type: typeof FOLLOW_CONTROLLER_DISABLE; |
||||
} |
||||
|
||||
export interface FollowControllerKeyPressAction extends Redux.Action { |
||||
type: typeof FOLLOW_CONTROLLER_KEY_PRESS; |
||||
key: string; |
||||
} |
||||
|
||||
export interface FollowControllerBackspaceAction extends Redux.Action { |
||||
type: typeof FOLLOW_CONTROLLER_BACKSPACE; |
||||
} |
||||
|
||||
export interface MarkStartSetAction extends Redux.Action { |
||||
type: typeof MARK_START_SET; |
||||
} |
||||
|
||||
export interface MarkStartJumpAction extends Redux.Action { |
||||
type: typeof MARK_START_JUMP; |
||||
} |
||||
|
||||
export interface MarkCancelAction extends Redux.Action { |
||||
type: typeof MARK_CANCEL; |
||||
} |
||||
|
||||
export interface MarkSetLocalAction extends Redux.Action { |
||||
type: typeof MARK_SET_LOCAL; |
||||
key: string; |
||||
x: number; |
||||
y: number; |
||||
} |
||||
|
||||
export interface NoopAction extends Redux.Action { |
||||
type: typeof NOOP; |
||||
} |
||||
|
||||
export type AddonAction = AddonSetEnabledAction; |
||||
export type FindAction = FindSetKeywordAction | NoopAction; |
||||
export type SettingAction = SettingSetAction; |
||||
export type InputAction = InputKeyPressAction | InputClearKeysAction; |
||||
export type FollowAction = |
||||
FollowControllerEnableAction | FollowControllerDisableAction | |
||||
FollowControllerKeyPressAction | FollowControllerBackspaceAction; |
||||
export type MarkAction = |
||||
MarkStartSetAction | MarkStartJumpAction | |
||||
MarkCancelAction | MarkSetLocalAction | NoopAction; |
||||
|
||||
export type Action = |
||||
AddonAction | |
||||
FindAction | |
||||
SettingAction | |
||||
InputAction | |
||||
FollowAction | |
||||
MarkAction | |
||||
NoopAction; |
||||
|
@ -0,0 +1,8 @@ |
||||
import promise from 'redux-promise'; |
||||
import reducers from '../reducers'; |
||||
import { createStore, applyMiddleware } from 'redux'; |
||||
|
||||
export const newStore = () => createStore( |
||||
reducers, |
||||
applyMiddleware(promise), |
||||
); |
@ -1,78 +1,276 @@ |
||||
type WebMessageSender = Window | MessagePort | ServiceWorker | null; |
||||
type WebMessageListener = (msg: any, sender: WebMessageSender | null) => void; |
||||
|
||||
const onWebMessage = (listener: WebMessageListener) => { |
||||
window.addEventListener('message', (event: MessageEvent) => { |
||||
let sender = event.source; |
||||
let message = null; |
||||
try { |
||||
message = JSON.parse(event.data); |
||||
} catch (e) { |
||||
// ignore unexpected message
|
||||
return; |
||||
} |
||||
listener(message, sender); |
||||
}); |
||||
}; |
||||
import * as operations from './operations'; |
||||
|
||||
const onBackgroundMessage = ( |
||||
listener: (msg: any, sender: browser.runtime.MessageSender, |
||||
) => void) => { |
||||
browser.runtime.onMessage.addListener(listener); |
||||
}; |
||||
export const BACKGROUND_OPERATION = 'background.operation'; |
||||
|
||||
const onMessage = ( |
||||
listener: (msg: any, sender: WebMessageSender | browser.runtime.MessageSender, |
||||
) => void) => { |
||||
onWebMessage(listener); |
||||
onBackgroundMessage(listener); |
||||
}; |
||||
export const CONSOLE_UNFOCUS = 'console.unfocus'; |
||||
export const CONSOLE_ENTER_COMMAND = 'console.enter.command'; |
||||
export const CONSOLE_ENTER_FIND = 'console.enter.find'; |
||||
export const CONSOLE_QUERY_COMPLETIONS = 'console.query.completions'; |
||||
export const CONSOLE_SHOW_COMMAND = 'console.show.command'; |
||||
export const CONSOLE_SHOW_ERROR = 'console.show.error'; |
||||
export const CONSOLE_SHOW_INFO = 'console.show.info'; |
||||
export const CONSOLE_SHOW_FIND = 'console.show.find'; |
||||
export const CONSOLE_HIDE = 'console.hide'; |
||||
|
||||
export const FOLLOW_START = 'follow.start'; |
||||
export const FOLLOW_REQUEST_COUNT_TARGETS = 'follow.request.count.targets'; |
||||
export const FOLLOW_RESPONSE_COUNT_TARGETS = 'follow.response.count.targets'; |
||||
export const FOLLOW_CREATE_HINTS = 'follow.create.hints'; |
||||
export const FOLLOW_SHOW_HINTS = 'follow.update.hints'; |
||||
export const FOLLOW_REMOVE_HINTS = 'follow.remove.hints'; |
||||
export const FOLLOW_ACTIVATE = 'follow.activate'; |
||||
export const FOLLOW_KEY_PRESS = 'follow.key.press'; |
||||
|
||||
export const MARK_SET_GLOBAL = 'mark.set.global'; |
||||
export const MARK_JUMP_GLOBAL = 'mark.jump.global'; |
||||
|
||||
export const TAB_SCROLL_TO = 'tab.scroll.to'; |
||||
|
||||
export const FIND_NEXT = 'find.next'; |
||||
export const FIND_PREV = 'find.prev'; |
||||
export const FIND_GET_KEYWORD = 'find.get.keyword'; |
||||
export const FIND_SET_KEYWORD = 'find.set.keyword'; |
||||
|
||||
export const ADDON_ENABLED_QUERY = 'addon.enabled.query'; |
||||
export const ADDON_ENABLED_RESPONSE = 'addon.enabled.response'; |
||||
export const ADDON_TOGGLE_ENABLED = 'addon.toggle.enabled'; |
||||
|
||||
export const OPEN_URL = 'open.url'; |
||||
|
||||
export const SETTINGS_CHANGED = 'settings.changed'; |
||||
export const SETTINGS_QUERY = 'settings.query'; |
||||
|
||||
export const CONSOLE_FRAME_MESSAGE = 'console.frame.message'; |
||||
|
||||
interface BackgroundOperationMessage { |
||||
type: typeof BACKGROUND_OPERATION; |
||||
operation: operations.Operation; |
||||
} |
||||
|
||||
interface ConsoleUnfocusMessage { |
||||
type: typeof CONSOLE_UNFOCUS; |
||||
} |
||||
|
||||
interface ConsoleEnterCommandMessage { |
||||
type: typeof CONSOLE_ENTER_COMMAND; |
||||
text: string; |
||||
} |
||||
|
||||
interface ConsoleEnterFindMessage { |
||||
type: typeof CONSOLE_ENTER_FIND; |
||||
text: string; |
||||
} |
||||
|
||||
interface ConsoleQueryCompletionsMessage { |
||||
type: typeof CONSOLE_QUERY_COMPLETIONS; |
||||
text: string; |
||||
} |
||||
|
||||
interface ConsoleShowCommandMessage { |
||||
type: typeof CONSOLE_SHOW_COMMAND; |
||||
command: string; |
||||
} |
||||
|
||||
interface ConsoleShowErrorMessage { |
||||
type: typeof CONSOLE_SHOW_ERROR; |
||||
text: string; |
||||
} |
||||
|
||||
interface ConsoleShowInfoMessage { |
||||
type: typeof CONSOLE_SHOW_INFO; |
||||
text: string; |
||||
} |
||||
|
||||
interface ConsoleShowFindMessage { |
||||
type: typeof CONSOLE_SHOW_FIND; |
||||
} |
||||
|
||||
interface ConsoleHideMessage { |
||||
type: typeof CONSOLE_HIDE; |
||||
} |
||||
|
||||
interface FollowStartMessage { |
||||
type: typeof FOLLOW_START; |
||||
newTab: boolean; |
||||
background: boolean; |
||||
} |
||||
|
||||
interface FollowRequestCountTargetsMessage { |
||||
type: typeof FOLLOW_REQUEST_COUNT_TARGETS; |
||||
viewSize: { width: number, height: number }; |
||||
framePosition: { x: number, y: number }; |
||||
} |
||||
|
||||
interface FollowResponseCountTargetsMessage { |
||||
type: typeof FOLLOW_RESPONSE_COUNT_TARGETS; |
||||
count: number; |
||||
} |
||||
|
||||
interface FollowCreateHintsMessage { |
||||
type: typeof FOLLOW_CREATE_HINTS; |
||||
keysArray: string[]; |
||||
newTab: boolean; |
||||
background: boolean; |
||||
} |
||||
|
||||
interface FollowShowHintsMessage { |
||||
type: typeof FOLLOW_SHOW_HINTS; |
||||
keys: string; |
||||
} |
||||
|
||||
interface FollowRemoveHintsMessage { |
||||
type: typeof FOLLOW_REMOVE_HINTS; |
||||
} |
||||
|
||||
interface FollowActivateMessage { |
||||
type: typeof FOLLOW_ACTIVATE; |
||||
keys: string; |
||||
} |
||||
|
||||
interface FollowKeyPressMessage { |
||||
type: typeof FOLLOW_KEY_PRESS; |
||||
key: string; |
||||
ctrlKey: boolean; |
||||
} |
||||
|
||||
interface MarkSetGlobalMessage { |
||||
type: typeof MARK_SET_GLOBAL; |
||||
key: string; |
||||
x: number; |
||||
y: number; |
||||
} |
||||
|
||||
interface MarkJumpGlobalMessage { |
||||
type: typeof MARK_JUMP_GLOBAL; |
||||
key: string; |
||||
} |
||||
|
||||
interface TabScrollToMessage { |
||||
type: typeof TAB_SCROLL_TO; |
||||
x: number; |
||||
y: number; |
||||
} |
||||
|
||||
interface FindNextMessage { |
||||
type: typeof FIND_NEXT; |
||||
} |
||||
|
||||
interface FindPrevMessage { |
||||
type: typeof FIND_PREV; |
||||
} |
||||
|
||||
interface FindGetKeywordMessage { |
||||
type: typeof FIND_GET_KEYWORD; |
||||
} |
||||
|
||||
interface FindSetKeywordMessage { |
||||
type: typeof FIND_SET_KEYWORD; |
||||
keyword: string; |
||||
found: boolean; |
||||
} |
||||
|
||||
interface AddonEnabledQueryMessage { |
||||
type: typeof ADDON_ENABLED_QUERY; |
||||
} |
||||
|
||||
interface AddonEnabledResponseMessage { |
||||
type: typeof ADDON_ENABLED_RESPONSE; |
||||
enabled: boolean; |
||||
} |
||||
|
||||
interface AddonToggleEnabledMessage { |
||||
type: typeof ADDON_TOGGLE_ENABLED; |
||||
} |
||||
|
||||
interface OpenUrlMessage { |
||||
type: typeof OPEN_URL; |
||||
url: string; |
||||
newTab: boolean; |
||||
background: boolean; |
||||
} |
||||
|
||||
interface SettingsChangedMessage { |
||||
type: typeof SETTINGS_CHANGED; |
||||
} |
||||
|
||||
interface SettingsQueryMessage { |
||||
type: typeof SETTINGS_QUERY; |
||||
} |
||||
|
||||
interface ConsoleFrameMessageMessage { |
||||
type: typeof CONSOLE_FRAME_MESSAGE; |
||||
message: any; |
||||
} |
||||
|
||||
export type Message = |
||||
BackgroundOperationMessage | |
||||
ConsoleUnfocusMessage | |
||||
ConsoleEnterCommandMessage | |
||||
ConsoleEnterFindMessage | |
||||
ConsoleQueryCompletionsMessage | |
||||
ConsoleShowCommandMessage | |
||||
ConsoleShowErrorMessage | |
||||
ConsoleShowInfoMessage | |
||||
ConsoleShowFindMessage | |
||||
ConsoleHideMessage | |
||||
FollowStartMessage | |
||||
FollowRequestCountTargetsMessage | |
||||
FollowResponseCountTargetsMessage | |
||||
FollowCreateHintsMessage | |
||||
FollowShowHintsMessage | |
||||
FollowRemoveHintsMessage | |
||||
FollowActivateMessage | |
||||
FollowKeyPressMessage | |
||||
MarkSetGlobalMessage | |
||||
MarkJumpGlobalMessage | |
||||
TabScrollToMessage | |
||||
FindNextMessage | |
||||
FindPrevMessage | |
||||
FindGetKeywordMessage | |
||||
FindSetKeywordMessage | |
||||
AddonEnabledQueryMessage | |
||||
AddonEnabledResponseMessage | |
||||
AddonToggleEnabledMessage | |
||||
OpenUrlMessage | |
||||
SettingsChangedMessage | |
||||
SettingsQueryMessage | |
||||
ConsoleFrameMessageMessage; |
||||
|
||||
export default { |
||||
BACKGROUND_OPERATION: 'background.operation', |
||||
|
||||
CONSOLE_UNFOCUS: 'console.unfocus', |
||||
CONSOLE_ENTER_COMMAND: 'console.enter.command', |
||||
CONSOLE_ENTER_FIND: 'console.enter.find', |
||||
CONSOLE_QUERY_COMPLETIONS: 'console.query.completions', |
||||
CONSOLE_SHOW_COMMAND: 'console.show.command', |
||||
CONSOLE_SHOW_ERROR: 'console.show.error', |
||||
CONSOLE_SHOW_INFO: 'console.show.info', |
||||
CONSOLE_SHOW_FIND: 'console.show.find', |
||||
CONSOLE_HIDE: 'console.hide', |
||||
|
||||
FOLLOW_START: 'follow.start', |
||||
FOLLOW_REQUEST_COUNT_TARGETS: 'follow.request.count.targets', |
||||
FOLLOW_RESPONSE_COUNT_TARGETS: 'follow.response.count.targets', |
||||
FOLLOW_CREATE_HINTS: 'follow.create.hints', |
||||
FOLLOW_SHOW_HINTS: 'follow.update.hints', |
||||
FOLLOW_REMOVE_HINTS: 'follow.remove.hints', |
||||
FOLLOW_ACTIVATE: 'follow.activate', |
||||
FOLLOW_KEY_PRESS: 'follow.key.press', |
||||
|
||||
MARK_SET_GLOBAL: 'mark.set.global', |
||||
MARK_JUMP_GLOBAL: 'mark.jump.global', |
||||
|
||||
TAB_SCROLL_TO: 'tab.scroll.to', |
||||
|
||||
FIND_NEXT: 'find.next', |
||||
FIND_PREV: 'find.prev', |
||||
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_CHANGED: 'settings.changed', |
||||
SETTINGS_QUERY: 'settings.query', |
||||
|
||||
WINDOW_TOP_MESSAGE: 'window.top.message', |
||||
CONSOLE_FRAME_MESSAGE: 'console.frame.message', |
||||
|
||||
onWebMessage, |
||||
onBackgroundMessage, |
||||
onMessage, |
||||
// eslint-disable-next-line complexity
|
||||
export const valueOf = (o: any): Message => { |
||||
switch (o.type) { |
||||
case CONSOLE_UNFOCUS: |
||||
case CONSOLE_ENTER_COMMAND: |
||||
case CONSOLE_ENTER_FIND: |
||||
case CONSOLE_QUERY_COMPLETIONS: |
||||
case CONSOLE_SHOW_COMMAND: |
||||
case CONSOLE_SHOW_ERROR: |
||||
case CONSOLE_SHOW_INFO: |
||||
case CONSOLE_SHOW_FIND: |
||||
case CONSOLE_HIDE: |
||||
case FOLLOW_START: |
||||
case FOLLOW_REQUEST_COUNT_TARGETS: |
||||
case FOLLOW_RESPONSE_COUNT_TARGETS: |
||||
case FOLLOW_CREATE_HINTS: |
||||
case FOLLOW_SHOW_HINTS: |
||||
case FOLLOW_REMOVE_HINTS: |
||||
case FOLLOW_ACTIVATE: |
||||
case FOLLOW_KEY_PRESS: |
||||
case MARK_SET_GLOBAL: |
||||
case MARK_JUMP_GLOBAL: |
||||
case TAB_SCROLL_TO: |
||||
case FIND_NEXT: |
||||
case FIND_PREV: |
||||
case FIND_GET_KEYWORD: |
||||
case FIND_SET_KEYWORD: |
||||
case ADDON_ENABLED_QUERY: |
||||
case ADDON_ENABLED_RESPONSE: |
||||
case ADDON_TOGGLE_ENABLED: |
||||
case OPEN_URL: |
||||
case SETTINGS_CHANGED: |
||||
case SETTINGS_QUERY: |
||||
case CONSOLE_FRAME_MESSAGE: |
||||
return o; |
||||
} |
||||
throw new Error('unknown operation type: ' + o.type); |
||||
}; |
||||
|
@ -1,80 +1,447 @@ |
||||
const operations: { [key: string]: string } = { |
||||
// Hide console, or cancel some user actions
|
||||
CANCEL: 'cancel', |
||||
|
||||
// Addons
|
||||
ADDON_ENABLE: 'addon.enable', |
||||
ADDON_DISABLE: 'addon.disable', |
||||
ADDON_TOGGLE_ENABLED: 'addon.toggle.enabled', |
||||
|
||||
// Command
|
||||
COMMAND_SHOW: 'command.show', |
||||
COMMAND_SHOW_OPEN: 'command.show.open', |
||||
COMMAND_SHOW_TABOPEN: 'command.show.tabopen', |
||||
COMMAND_SHOW_WINOPEN: 'command.show.winopen', |
||||
COMMAND_SHOW_BUFFER: 'command.show.buffer', |
||||
COMMAND_SHOW_ADDBOOKMARK: 'command.show.addbookmark', |
||||
|
||||
// Scrolls
|
||||
SCROLL_VERTICALLY: 'scroll.vertically', |
||||
SCROLL_HORIZONALLY: 'scroll.horizonally', |
||||
SCROLL_PAGES: 'scroll.pages', |
||||
SCROLL_TOP: 'scroll.top', |
||||
SCROLL_BOTTOM: 'scroll.bottom', |
||||
SCROLL_HOME: 'scroll.home', |
||||
SCROLL_END: 'scroll.end', |
||||
|
||||
// Follows
|
||||
FOLLOW_START: 'follow.start', |
||||
|
||||
// Navigations
|
||||
NAVIGATE_HISTORY_PREV: 'navigate.history.prev', |
||||
NAVIGATE_HISTORY_NEXT: 'navigate.history.next', |
||||
NAVIGATE_LINK_PREV: 'navigate.link.prev', |
||||
NAVIGATE_LINK_NEXT: 'navigate.link.next', |
||||
NAVIGATE_PARENT: 'navigate.parent', |
||||
NAVIGATE_ROOT: 'navigate.root', |
||||
|
||||
// Focus
|
||||
FOCUS_INPUT: 'focus.input', |
||||
|
||||
// Page
|
||||
PAGE_SOURCE: 'page.source', |
||||
PAGE_HOME: 'page.home', |
||||
|
||||
// Tabs
|
||||
TAB_CLOSE: 'tabs.close', |
||||
TAB_CLOSE_FORCE: 'tabs.close.force', |
||||
TAB_CLOSE_RIGHT: 'tabs.close.right', |
||||
TAB_REOPEN: 'tabs.reopen', |
||||
TAB_PREV: 'tabs.prev', |
||||
TAB_NEXT: 'tabs.next', |
||||
TAB_FIRST: 'tabs.first', |
||||
TAB_LAST: 'tabs.last', |
||||
TAB_PREV_SEL: 'tabs.prevsel', |
||||
TAB_RELOAD: 'tabs.reload', |
||||
TAB_PIN: 'tabs.pin', |
||||
TAB_UNPIN: 'tabs.unpin', |
||||
TAB_TOGGLE_PINNED: 'tabs.pin.toggle', |
||||
TAB_DUPLICATE: 'tabs.duplicate', |
||||
|
||||
// Zooms
|
||||
ZOOM_IN: 'zoom.in', |
||||
ZOOM_OUT: 'zoom.out', |
||||
ZOOM_NEUTRAL: 'zoom.neutral', |
||||
|
||||
// Url yank/paste
|
||||
URLS_YANK: 'urls.yank', |
||||
URLS_PASTE: 'urls.paste', |
||||
|
||||
// Find
|
||||
FIND_START: 'find.start', |
||||
FIND_NEXT: 'find.next', |
||||
FIND_PREV: 'find.prev', |
||||
|
||||
// Mark
|
||||
MARK_SET_PREFIX: 'mark.set.prefix', |
||||
MARK_JUMP_PREFIX: 'mark.jump.prefix', |
||||
// Hide console; or cancel some user actions
|
||||
export const CANCEL = 'cancel'; |
||||
|
||||
// Addons
|
||||
export const ADDON_ENABLE = 'addon.enable'; |
||||
export const ADDON_DISABLE = 'addon.disable'; |
||||
export const ADDON_TOGGLE_ENABLED = 'addon.toggle.enabled'; |
||||
|
||||
// Command
|
||||
export const COMMAND_SHOW = 'command.show'; |
||||
export const COMMAND_SHOW_OPEN = 'command.show.open'; |
||||
export const COMMAND_SHOW_TABOPEN = 'command.show.tabopen'; |
||||
export const COMMAND_SHOW_WINOPEN = 'command.show.winopen'; |
||||
export const COMMAND_SHOW_BUFFER = 'command.show.buffer'; |
||||
export const COMMAND_SHOW_ADDBOOKMARK = 'command.show.addbookmark'; |
||||
|
||||
// Scrolls
|
||||
export const SCROLL_VERTICALLY = 'scroll.vertically'; |
||||
export const SCROLL_HORIZONALLY = 'scroll.horizonally'; |
||||
export const SCROLL_PAGES = 'scroll.pages'; |
||||
export const SCROLL_TOP = 'scroll.top'; |
||||
export const SCROLL_BOTTOM = 'scroll.bottom'; |
||||
export const SCROLL_HOME = 'scroll.home'; |
||||
export const SCROLL_END = 'scroll.end'; |
||||
|
||||
// Follows
|
||||
export const FOLLOW_START = 'follow.start'; |
||||
|
||||
// Navigations
|
||||
export const NAVIGATE_HISTORY_PREV = 'navigate.history.prev'; |
||||
export const NAVIGATE_HISTORY_NEXT = 'navigate.history.next'; |
||||
export const NAVIGATE_LINK_PREV = 'navigate.link.prev'; |
||||
export const NAVIGATE_LINK_NEXT = 'navigate.link.next'; |
||||
export const NAVIGATE_PARENT = 'navigate.parent'; |
||||
export const NAVIGATE_ROOT = 'navigate.root'; |
||||
|
||||
// Focus
|
||||
export const FOCUS_INPUT = 'focus.input'; |
||||
|
||||
// Page
|
||||
export const PAGE_SOURCE = 'page.source'; |
||||
export const PAGE_HOME = 'page.home'; |
||||
|
||||
// Tabs
|
||||
export const TAB_CLOSE = 'tabs.close'; |
||||
export const TAB_CLOSE_FORCE = 'tabs.close.force'; |
||||
export const TAB_CLOSE_RIGHT = 'tabs.close.right'; |
||||
export const TAB_REOPEN = 'tabs.reopen'; |
||||
export const TAB_PREV = 'tabs.prev'; |
||||
export const TAB_NEXT = 'tabs.next'; |
||||
export const TAB_FIRST = 'tabs.first'; |
||||
export const TAB_LAST = 'tabs.last'; |
||||
export const TAB_PREV_SEL = 'tabs.prevsel'; |
||||
export const TAB_RELOAD = 'tabs.reload'; |
||||
export const TAB_PIN = 'tabs.pin'; |
||||
export const TAB_UNPIN = 'tabs.unpin'; |
||||
export const TAB_TOGGLE_PINNED = 'tabs.pin.toggle'; |
||||
export const TAB_DUPLICATE = 'tabs.duplicate'; |
||||
|
||||
// Zooms
|
||||
export const ZOOM_IN = 'zoom.in'; |
||||
export const ZOOM_OUT = 'zoom.out'; |
||||
export const ZOOM_NEUTRAL = 'zoom.neutral'; |
||||
|
||||
// Url yank/paste
|
||||
export const URLS_YANK = 'urls.yank'; |
||||
export const URLS_PASTE = 'urls.paste'; |
||||
|
||||
// Find
|
||||
export const FIND_START = 'find.start'; |
||||
export const FIND_NEXT = 'find.next'; |
||||
export const FIND_PREV = 'find.prev'; |
||||
|
||||
// Mark
|
||||
export const MARK_SET_PREFIX = 'mark.set.prefix'; |
||||
export const MARK_JUMP_PREFIX = 'mark.jump.prefix'; |
||||
|
||||
export interface CancelOperation { |
||||
type: typeof CANCEL; |
||||
} |
||||
|
||||
export interface AddonEnableOperation { |
||||
type: typeof ADDON_ENABLE; |
||||
} |
||||
|
||||
export interface AddonDisableOperation { |
||||
type: typeof ADDON_DISABLE; |
||||
} |
||||
|
||||
export interface AddonToggleEnabledOperation { |
||||
type: typeof ADDON_TOGGLE_ENABLED; |
||||
} |
||||
|
||||
export interface CommandShowOperation { |
||||
type: typeof COMMAND_SHOW; |
||||
} |
||||
|
||||
export interface CommandShowOpenOperation { |
||||
type: typeof COMMAND_SHOW_OPEN; |
||||
alter: boolean; |
||||
} |
||||
|
||||
export interface CommandShowTabopenOperation { |
||||
type: typeof COMMAND_SHOW_TABOPEN; |
||||
alter: boolean; |
||||
} |
||||
|
||||
export interface CommandShowWinopenOperation { |
||||
type: typeof COMMAND_SHOW_WINOPEN; |
||||
alter: boolean; |
||||
} |
||||
|
||||
export interface CommandShowBufferOperation { |
||||
type: typeof COMMAND_SHOW_BUFFER; |
||||
} |
||||
|
||||
export interface CommandShowAddbookmarkOperation { |
||||
type: typeof COMMAND_SHOW_ADDBOOKMARK; |
||||
alter: boolean; |
||||
} |
||||
|
||||
export interface ScrollVerticallyOperation { |
||||
type: typeof SCROLL_VERTICALLY; |
||||
count: number; |
||||
} |
||||
|
||||
export interface ScrollHorizonallyOperation { |
||||
type: typeof SCROLL_HORIZONALLY; |
||||
count: number; |
||||
} |
||||
|
||||
export interface ScrollPagesOperation { |
||||
type: typeof SCROLL_PAGES; |
||||
count: number; |
||||
} |
||||
|
||||
export interface ScrollTopOperation { |
||||
type: typeof SCROLL_TOP; |
||||
} |
||||
|
||||
export interface ScrollBottomOperation { |
||||
type: typeof SCROLL_BOTTOM; |
||||
} |
||||
|
||||
export interface ScrollHomeOperation { |
||||
type: typeof SCROLL_HOME; |
||||
} |
||||
|
||||
export interface ScrollEndOperation { |
||||
type: typeof SCROLL_END; |
||||
} |
||||
|
||||
export interface FollowStartOperation { |
||||
type: typeof FOLLOW_START; |
||||
newTab: boolean; |
||||
background: boolean; |
||||
} |
||||
|
||||
export interface NavigateHistoryPrevOperation { |
||||
type: typeof NAVIGATE_HISTORY_PREV; |
||||
} |
||||
|
||||
export interface NavigateHistoryNextOperation { |
||||
type: typeof NAVIGATE_HISTORY_NEXT; |
||||
} |
||||
|
||||
export interface NavigateLinkPrevOperation { |
||||
type: typeof NAVIGATE_LINK_PREV; |
||||
} |
||||
|
||||
export interface NavigateLinkNextOperation { |
||||
type: typeof NAVIGATE_LINK_NEXT; |
||||
} |
||||
|
||||
export interface NavigateParentOperation { |
||||
type: typeof NAVIGATE_PARENT; |
||||
} |
||||
|
||||
export interface NavigateRootOperation { |
||||
type: typeof NAVIGATE_ROOT; |
||||
} |
||||
|
||||
export interface FocusInputOperation { |
||||
type: typeof FOCUS_INPUT; |
||||
} |
||||
|
||||
export interface PageSourceOperation { |
||||
type: typeof PAGE_SOURCE; |
||||
} |
||||
|
||||
export interface PageHomeOperation { |
||||
type: typeof PAGE_HOME; |
||||
newTab: boolean; |
||||
} |
||||
|
||||
export interface TabCloseOperation { |
||||
type: typeof TAB_CLOSE; |
||||
} |
||||
|
||||
export interface TabCloseForceOperation { |
||||
type: typeof TAB_CLOSE_FORCE; |
||||
} |
||||
|
||||
export interface TabCloseRightOperation { |
||||
type: typeof TAB_CLOSE_RIGHT; |
||||
} |
||||
|
||||
export interface TabReopenOperation { |
||||
type: typeof TAB_REOPEN; |
||||
} |
||||
|
||||
export interface TabPrevOperation { |
||||
type: typeof TAB_PREV; |
||||
} |
||||
|
||||
export interface TabNextOperation { |
||||
type: typeof TAB_NEXT; |
||||
} |
||||
|
||||
export interface TabFirstOperation { |
||||
type: typeof TAB_FIRST; |
||||
} |
||||
|
||||
export interface TabLastOperation { |
||||
type: typeof TAB_LAST; |
||||
} |
||||
|
||||
export interface TabPrevSelOperation { |
||||
type: typeof TAB_PREV_SEL; |
||||
} |
||||
|
||||
export interface TabReloadOperation { |
||||
type: typeof TAB_RELOAD; |
||||
cache: boolean; |
||||
} |
||||
|
||||
export interface TabPinOperation { |
||||
type: typeof TAB_PIN; |
||||
} |
||||
|
||||
export interface TabUnpinOperation { |
||||
type: typeof TAB_UNPIN; |
||||
} |
||||
|
||||
export interface TabTogglePinnedOperation { |
||||
type: typeof TAB_TOGGLE_PINNED; |
||||
} |
||||
|
||||
export interface TabDuplicateOperation { |
||||
type: typeof TAB_DUPLICATE; |
||||
} |
||||
|
||||
export interface ZoomInOperation { |
||||
type: typeof ZOOM_IN; |
||||
} |
||||
|
||||
export interface ZoomOutOperation { |
||||
type: typeof ZOOM_OUT; |
||||
} |
||||
|
||||
export interface ZoomNeutralOperation { |
||||
type: typeof ZOOM_NEUTRAL; |
||||
} |
||||
|
||||
export interface UrlsYankOperation { |
||||
type: typeof URLS_YANK; |
||||
} |
||||
|
||||
export interface UrlsPasteOperation { |
||||
type: typeof URLS_PASTE; |
||||
newTab: boolean; |
||||
} |
||||
|
||||
export interface FindStartOperation { |
||||
type: typeof FIND_START; |
||||
} |
||||
|
||||
export interface FindNextOperation { |
||||
type: typeof FIND_NEXT; |
||||
} |
||||
|
||||
export interface FindPrevOperation { |
||||
type: typeof FIND_PREV; |
||||
} |
||||
|
||||
export interface MarkSetPrefixOperation { |
||||
type: typeof MARK_SET_PREFIX; |
||||
} |
||||
|
||||
export interface MarkJumpPrefixOperation { |
||||
type: typeof MARK_JUMP_PREFIX; |
||||
} |
||||
|
||||
export type Operation = |
||||
CancelOperation | |
||||
AddonEnableOperation | |
||||
AddonDisableOperation | |
||||
AddonToggleEnabledOperation | |
||||
CommandShowOperation | |
||||
CommandShowOpenOperation | |
||||
CommandShowTabopenOperation | |
||||
CommandShowWinopenOperation | |
||||
CommandShowBufferOperation | |
||||
CommandShowAddbookmarkOperation | |
||||
ScrollVerticallyOperation | |
||||
ScrollHorizonallyOperation | |
||||
ScrollPagesOperation | |
||||
ScrollTopOperation | |
||||
ScrollBottomOperation | |
||||
ScrollHomeOperation | |
||||
ScrollEndOperation | |
||||
FollowStartOperation | |
||||
NavigateHistoryPrevOperation | |
||||
NavigateHistoryNextOperation | |
||||
NavigateLinkPrevOperation | |
||||
NavigateLinkNextOperation | |
||||
NavigateParentOperation | |
||||
NavigateRootOperation | |
||||
FocusInputOperation | |
||||
PageSourceOperation | |
||||
PageHomeOperation | |
||||
TabCloseOperation | |
||||
TabCloseForceOperation | |
||||
TabCloseRightOperation | |
||||
TabReopenOperation | |
||||
TabPrevOperation | |
||||
TabNextOperation | |
||||
TabFirstOperation | |
||||
TabLastOperation | |
||||
TabPrevSelOperation | |
||||
TabReloadOperation | |
||||
TabPinOperation | |
||||
TabUnpinOperation | |
||||
TabTogglePinnedOperation | |
||||
TabDuplicateOperation | |
||||
ZoomInOperation | |
||||
ZoomOutOperation | |
||||
ZoomNeutralOperation | |
||||
UrlsYankOperation | |
||||
UrlsPasteOperation | |
||||
FindStartOperation | |
||||
FindNextOperation | |
||||
FindPrevOperation | |
||||
MarkSetPrefixOperation | |
||||
MarkJumpPrefixOperation; |
||||
|
||||
const assertOptionalBoolean = (obj: any, name: string) => { |
||||
if (Object.prototype.hasOwnProperty.call(obj, name) && |
||||
typeof obj[name] !== 'boolean') { |
||||
throw new TypeError(`Not a boolean parameter '${name}'`); |
||||
} |
||||
}; |
||||
|
||||
const assertRequiredNumber = (obj: any, name: string) => { |
||||
if (!Object.prototype.hasOwnProperty.call(obj, name) || |
||||
typeof obj[name] !== 'number') { |
||||
throw new TypeError(`Missing number parameter '${name}`); |
||||
} |
||||
}; |
||||
|
||||
export default operations; |
||||
// eslint-disable-next-line complexity, max-lines-per-function
|
||||
export const valueOf = (o: any): Operation => { |
||||
if (!Object.prototype.hasOwnProperty.call(o, 'type')) { |
||||
throw new TypeError(`missing 'type' field`); |
||||
} |
||||
switch (o.type) { |
||||
case COMMAND_SHOW_OPEN: |
||||
case COMMAND_SHOW_TABOPEN: |
||||
case COMMAND_SHOW_WINOPEN: |
||||
case COMMAND_SHOW_ADDBOOKMARK: |
||||
assertOptionalBoolean(o, 'alter'); |
||||
return { type: o.type, alter: Boolean(o.alter) }; |
||||
case SCROLL_VERTICALLY: |
||||
case SCROLL_HORIZONALLY: |
||||
case SCROLL_PAGES: |
||||
assertRequiredNumber(o, 'count'); |
||||
return { type: o.type, count: Number(o.count) }; |
||||
case FOLLOW_START: |
||||
assertOptionalBoolean(o, 'newTab'); |
||||
assertOptionalBoolean(o, 'background'); |
||||
return { |
||||
type: FOLLOW_START, |
||||
newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab), |
||||
background: Boolean(typeof o.background === undefined ? true : o.background), // eslint-disable-line max-len
|
||||
}; |
||||
case PAGE_HOME: |
||||
assertOptionalBoolean(o, 'newTab'); |
||||
return { |
||||
type: PAGE_HOME, |
||||
newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab), |
||||
}; |
||||
case TAB_RELOAD: |
||||
assertOptionalBoolean(o, 'cache'); |
||||
return { |
||||
type: TAB_RELOAD, |
||||
cache: Boolean(typeof o.cache === undefined ? false : o.cache), |
||||
}; |
||||
case URLS_PASTE: |
||||
assertOptionalBoolean(o, 'newTab'); |
||||
return { |
||||
type: URLS_PASTE, |
||||
newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab), |
||||
}; |
||||
case CANCEL: |
||||
case ADDON_ENABLE: |
||||
case ADDON_DISABLE: |
||||
case ADDON_TOGGLE_ENABLED: |
||||
case COMMAND_SHOW: |
||||
case COMMAND_SHOW_BUFFER: |
||||
case SCROLL_TOP: |
||||
case SCROLL_BOTTOM: |
||||
case SCROLL_HOME: |
||||
case SCROLL_END: |
||||
case NAVIGATE_HISTORY_PREV: |
||||
case NAVIGATE_HISTORY_NEXT: |
||||
case NAVIGATE_LINK_PREV: |
||||
case NAVIGATE_LINK_NEXT: |
||||
case NAVIGATE_PARENT: |
||||
case NAVIGATE_ROOT: |
||||
case FOCUS_INPUT: |
||||
case PAGE_SOURCE: |
||||
case TAB_CLOSE: |
||||
case TAB_CLOSE_FORCE: |
||||
case TAB_CLOSE_RIGHT: |
||||
case TAB_REOPEN: |
||||
case TAB_PREV: |
||||
case TAB_NEXT: |
||||
case TAB_FIRST: |
||||
case TAB_LAST: |
||||
case TAB_PREV_SEL: |
||||
case TAB_PIN: |
||||
case TAB_UNPIN: |
||||
case TAB_TOGGLE_PINNED: |
||||
case TAB_DUPLICATE: |
||||
case ZOOM_IN: |
||||
case ZOOM_OUT: |
||||
case ZOOM_NEUTRAL: |
||||
case URLS_YANK: |
||||
case FIND_START: |
||||
case FIND_NEXT: |
||||
case FIND_PREV: |
||||
case MARK_SET_PREFIX: |
||||
case MARK_JUMP_PREFIX: |
||||
return { type: o.type }; |
||||
} |
||||
throw new Error('unknown operation type: ' + o.type); |
||||
}; |
||||
|
@ -0,0 +1,41 @@ |
||||
import * as operations from 'shared/operations'; |
||||
|
||||
describe('operations', () => { |
||||
describe('#valueOf', () => { |
||||
it('returns an Operation', () => { |
||||
let op: operations.Operation = operations.valueOf({ |
||||
type: operations.SCROLL_VERTICALLY, |
||||
count: 10, |
||||
}); |
||||
expect(op.type).to.equal(operations.SCROLL_VERTICALLY); |
||||
expect(op.count).to.equal(10); |
||||
}); |
||||
|
||||
it('throws an Error on missing required parameter', () => { |
||||
expect(() => operations.valueOf({ |
||||
type: operations.SCROLL_VERTICALLY, |
||||
})).to.throw(TypeError); |
||||
}); |
||||
|
||||
it('fills default valus of optional parameter', () => { |
||||
let op: operations.Operation = operations.valueOf({ |
||||
type: operations.COMMAND_SHOW_OPEN, |
||||
}); |
||||
|
||||
expect(op.type).to.equal(operations.COMMAND_SHOW_OPEN) |
||||
expect(op.alter).to.be.false; |
||||
}); |
||||
|
||||
it('throws an Error on mismatch of parameter', () => { |
||||
expect(() => operations.valueOf({ |
||||
type: operations.SCROLL_VERTICALLY, |
||||
count: '10', |
||||
})).to.throw(TypeError); |
||||
|
||||
expect(() => valueOf({ |
||||
type: operations.COMMAND_SHOW_OPEN, |
||||
alter: 'true', |
||||
})).to.throw(TypeError); |
||||
}); |
||||
}); |
||||
}) |
Reference in new issue