aboutsummaryrefslogtreecommitdiff
path: root/src/shared/operations.ts
blob: beca7b9fcc59d9ceea3b872d099f9f8fa6bbc769 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
// 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';

// Repeat
export const REPEAT_LAST = 'repeat.last';

// Internal
export const INTERNAL_OPEN_URL = 'internal.open.url';

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;
  select?: 'left' | 'right';
}

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 interface RepeatLastOperation {
  type: typeof REPEAT_LAST;
}

export interface InternalOpenUrl {
  type: typeof INTERNAL_OPEN_URL;
  url: string;
  newTab?: boolean;
  newWindow?: boolean;
  background?: boolean;
}

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 |
  RepeatLastOperation |
  InternalOpenUrl;

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} (${typeof obj[name]})'`,
    );
  }
};

const assertOptionalString = (obj: any, name: string, values?: string[]) => {
  if (Object.prototype.hasOwnProperty.call(obj, name)) {
    const value = obj[name];
    if (typeof value !== 'string') {
      throw new TypeError(
        `Not a string parameter: '${name}' (${typeof value})`,
      );
    }
    if (values && values.length && values.indexOf(value) === -1) {
      // eslint-disable-next-line max-len
      throw new TypeError(`Invalid parameter for '${name}': '${value}'`);
    }
  }
};

const assertRequiredNumber = (obj: any, name: string) => {
  if (!Object.prototype.hasOwnProperty.call(obj, name) ||
    typeof obj[name] !== 'number') {
    throw new TypeError(`Missing number parameter: '${name}`);
  }
};

const assertRequiredString = (obj: any, name: string) => {
  if (!Object.prototype.hasOwnProperty.call(obj, name) ||
    typeof obj[name] !== 'string') {
    throw new TypeError(`Missing string parameter: '${name}`);
  }
};

// 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_CLOSE:
    assertOptionalString(o, 'select', ['left', 'right']);
    return {
      type: TAB_CLOSE,
      select: (typeof o.select === 'undefined' ? 'right' : o.select),
    };
  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 INTERNAL_OPEN_URL:
    assertOptionalBoolean(o, 'newTab');
    assertOptionalBoolean(o, 'newWindow');
    assertOptionalBoolean(o, 'background');
    assertRequiredString(o, 'url');
    return {
      type: INTERNAL_OPEN_URL,
      url: o.url,
      newTab: Boolean(typeof o.newTab === 'undefined' ? false : o.newTab),
      newWindow: Boolean(typeof o.newWindow === 'undefined' ? false : o.newWindow), // eslint-disable-line max-len
      background: Boolean(typeof o.background === 'undefined' ? true : o.background), // eslint-disable-line max-len
    };
  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_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:
  case REPEAT_LAST:
    return { type: o.type };
  }
  throw new TypeError('Unknown operation type: ' + o.type);
};

export const isNRepeatable = (type: string): boolean => {
  switch (type) {
  case SCROLL_VERTICALLY:
  case SCROLL_HORIZONALLY:
  case SCROLL_PAGES:
  case NAVIGATE_HISTORY_PREV:
  case NAVIGATE_HISTORY_NEXT:
  case NAVIGATE_PARENT:
  case TAB_CLOSE:
  case TAB_CLOSE_FORCE:
  case TAB_CLOSE_RIGHT:
  case TAB_REOPEN:
  case TAB_PREV:
  case TAB_NEXT:
  case TAB_DUPLICATE:
  case ZOOM_IN:
  case ZOOM_OUT:
  case URLS_PASTE:
  case FIND_NEXT:
  case FIND_PREV:
  case REPEAT_LAST:
    return true;
  }
  return false;
};