From 7198fa17ea2e4b7dede0b644358696934596ca15 Mon Sep 17 00:00:00 2001 From: Kevin Cox Date: Mon, 16 Oct 2017 21:05:26 +0100 Subject: [PATCH 1/4] Implement minimal custom command. It's mostly UI and some wiring which is left. --- src/modes/command/client/commands/misc.js | 22 ++++++++++++++++++++++ src/modes/command/client/trie.js | 9 ++++++++- src/options/Keybindings/config.json | 11 +++++++++++ src/options/Keybindings/default.json | 12 ++++++++---- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/modes/command/client/commands/misc.js b/src/modes/command/client/commands/misc.js index 20c9567..691291f 100644 --- a/src/modes/command/client/commands/misc.js +++ b/src/modes/command/client/commands/misc.js @@ -28,3 +28,25 @@ export function passAllKeys (event) { event.passKeyType = 'all' return 'Pass' } + +// TODO: Get from options. +let customCommands = { + toHttps: { + preventDefault: true, // The default. + code: + 'document.location = document.location.href.replace(/^http:/, "https:")' + } +} + +// TODO reduce amount of visible internal state. +function trampoline (_src, event) { + eval(_src) +} + +export function customCommand (id, event) { + let impl = customCommands[id] + console.log('Custom command', id, impl) + + if (impl.preventDefault) event.preventDefault() + return trampoline(impl.code, event) +} diff --git a/src/modes/command/client/trie.js b/src/modes/command/client/trie.js index 80d342a..72bc8ea 100644 --- a/src/modes/command/client/trie.js +++ b/src/modes/command/client/trie.js @@ -25,6 +25,13 @@ export function advanceInputTrie (event) { default: event.preventDefault() event.stopImmediatePropagation() - return commands[command](event) || 'Same' + var cmd + if (command.startsWith('customCommand_')) { + let id = command.slice(14) // Drop prefix. + cmd = commands.customCommand.bind(null, id) + } else { + cmd = commands[command] + } + return cmd(event) || 'Same' } } diff --git a/src/options/Keybindings/config.json b/src/options/Keybindings/config.json index 42e7b8f..22b391d 100644 --- a/src/options/Keybindings/config.json +++ b/src/options/Keybindings/config.json @@ -485,6 +485,17 @@ "label": "Activate Clipboard in Incognito Window", "key": "clipboardIncognitoWindow", "default": [] + }, + { + "type": "header", + "label": "Custom" + }, + { + "comment": "TODO: generate dynamically", + "type": "keybinding", + "label": "Custom Command", + "key": "customCommand_toHttps", + "default": [] } ] } diff --git a/src/options/Keybindings/default.json b/src/options/Keybindings/default.json index f50e3e6..4329cb7 100644 --- a/src/options/Keybindings/default.json +++ b/src/options/Keybindings/default.json @@ -198,7 +198,8 @@ { "code": "KeyY", "key": "y" }, { "code": "KeyN", "key": "N", "shiftKey": true } ] - ] + ], + "customCommand_toHttps": [] } }, { @@ -373,7 +374,8 @@ { "code": "KeyY", "key": "y" }, { "code": "KeyN", "key": "N", "shiftKey": true } ] - ] + ], + "customCommand_toHttps": [] } }, { @@ -505,7 +507,8 @@ { "code": "KeyY", "key": "y" }, { "code": "KeyN", "key": "N", "shiftKey": true } ] - ] + ], + "customCommand_toHttps": [] } }, { @@ -634,7 +637,8 @@ [{ "code": "KeyP", "key": "P", "shiftKey": true }] ], "clipboardNewWindow": [], - "clipboardIncognitoWindow": [] + "clipboardIncognitoWindow": [], + "customCommand_toHttps": [] } } ] From 5a3fd1330f3c57981e9cc64037898a2624b7a15c Mon Sep 17 00:00:00 2001 From: Kevin Cox Date: Mon, 16 Oct 2017 21:28:58 +0100 Subject: [PATCH 2/4] Eval user code in global scope. This prevents the user from seeing our internals, allowing us to provide a more stable API. --- src/modes/command/client/commands/misc.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/modes/command/client/commands/misc.js b/src/modes/command/client/commands/misc.js index 691291f..aceb8a1 100644 --- a/src/modes/command/client/commands/misc.js +++ b/src/modes/command/client/commands/misc.js @@ -38,15 +38,16 @@ let customCommands = { } } -// TODO reduce amount of visible internal state. -function trampoline (_src, event) { - eval(_src) -} - export function customCommand (id, event) { let impl = customCommands[id] console.log('Custom command', id, impl) if (impl.preventDefault) event.preventDefault() - return trampoline(impl.code, event) + let global_eval = eval; // This causes the eval to happen in the global scope. + let func = global_eval(` + (event) => { + ${impl.code} + } + `); + return func(event); } From 56db5ba61241542cf18ee174e73edfc9ab5ed882 Mon Sep 17 00:00:00 2001 From: Kevin Cox Date: Mon, 23 Oct 2017 22:25:55 +0100 Subject: [PATCH 3/4] Start work on UI. It's not wired up at all but it's a start. It is missing keybindings which look like they will take some work. --- src/options/CustomCommands/config.json | 10 +++++ src/options/CustomCommands/default.json | 11 +++++ src/options/CustomCommands/index.js | 9 ++++ .../OptionWidgets/CustomCommands/index.js | 45 +++++++++++++++++++ .../OptionItem/OptionWidgets/index.js | 3 ++ src/storage/procedures.js | 6 ++- src/storage/transform.js | 4 +- 7 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/options/CustomCommands/config.json create mode 100644 src/options/CustomCommands/default.json create mode 100644 src/options/CustomCommands/index.js create mode 100644 src/pages/options/Content/OptionsCard/OptionsList/OptionItem/OptionWidgets/CustomCommands/index.js diff --git a/src/options/CustomCommands/config.json b/src/options/CustomCommands/config.json new file mode 100644 index 0000000..d4f232e --- /dev/null +++ b/src/options/CustomCommands/config.json @@ -0,0 +1,10 @@ +{ + "name": "Custom Commands", + "options": [ + { + "type": "customcommands", + "key": "customCommands", + "default": [] + } + ] +} diff --git a/src/options/CustomCommands/default.json b/src/options/CustomCommands/default.json new file mode 100644 index 0000000..8aca381 --- /dev/null +++ b/src/options/CustomCommands/default.json @@ -0,0 +1,11 @@ +{ + "name": "Custom Commands", + "profiles": [ + { + "name": "default", + "options": { + "customCommands": [] + } + } + ] +} diff --git a/src/options/CustomCommands/index.js b/src/options/CustomCommands/index.js new file mode 100644 index 0000000..0f8d817 --- /dev/null +++ b/src/options/CustomCommands/index.js @@ -0,0 +1,9 @@ +import { getAttributes } from 'lib/util' + +export default (options, config) => { + console.error('CustomCommand/index.js called', options, config) + const backgroundOptions = {} + const clientOptions = {} + const errors = {} + return { backgroundOptions, clientOptions, errors } +} diff --git a/src/pages/options/Content/OptionsCard/OptionsList/OptionItem/OptionWidgets/CustomCommands/index.js b/src/pages/options/Content/OptionsCard/OptionsList/OptionItem/OptionWidgets/CustomCommands/index.js new file mode 100644 index 0000000..7bddec8 --- /dev/null +++ b/src/pages/options/Content/OptionsCard/OptionsList/OptionItem/OptionWidgets/CustomCommands/index.js @@ -0,0 +1,45 @@ +import { Component, h } from 'preact' +import TextArea from '../TextArea' + +const DEFAULT = { + source: 'document.body.style.backgroundColor = "blue"' +} + +class CustomCommand extends Component { + render ({ command, onChange }) { + return ( +
  • +

    This is a command

    +