mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 02:09:40 +08:00
Fix issues with non-US keyboards and add key binding settings page (#2930)
Replaced the key manager by atom-keymap to support non-US keyboards and dead key translation on macOS and Windows. In addition, a GUI for key bindings was added.
This commit is contained in:
parent
c959d185b2
commit
6b3ead958e
@ -7,7 +7,6 @@ Usage: marktext [commands] [path ...]
|
||||
|
||||
--debug Enable debug mode
|
||||
--safe Disable plugins and other user configuration
|
||||
--dump-keyboard-layout Dump keyboard information
|
||||
-n, --new-window Open a new window on second-instance
|
||||
--user-data-dir Change the user data directory
|
||||
--disable-gpu Disable GPU hardware acceleration
|
||||
|
@ -17,12 +17,13 @@ Here is an example:
|
||||
- `Option` on macOS
|
||||
- `Ctrl`
|
||||
- `Shift`
|
||||
- `Alt` and `AltGr` on Linux and Windows
|
||||
- `Super` on Linux and Windows
|
||||
- `Alt` (equal to `Option` on macOS)
|
||||
|
||||
Please don't bind `AltGr`, use `Cltr+Alt` instead.
|
||||
|
||||
## Available keys
|
||||
|
||||
- `0-9`, `A-Z`, `F1-F24` and punctuations
|
||||
- `0-9`, `A-Z`, `F1-F24` and punctuations like `/` or `#`
|
||||
- `Plus`, `Space`, `Tab`, `Backspace`, `Delete`, `Insert`, `Return/Enter`, `Esc`, `Home`, `End` and `PrintScreen`
|
||||
- `Up`, `Down`, `Left` and `Right`
|
||||
- `PageUp` and `PageDown`
|
||||
|
@ -62,11 +62,11 @@ MarkText key bindings for Linux. Please see [general key bindings](KEYBINDINGS.m
|
||||
| `paragraph.math-formula` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>M</kbd> | Insert a math block |
|
||||
| `paragraph.html-block` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> | Insert a HTML block |
|
||||
| `paragraph.order-list` | <kbd>Ctrl</kbd>+<kbd>G</kbd> | Insert a ordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd> | Insert a unordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Ctrl</kbd>+<kbd>H</kbd> | Insert a unordered list |
|
||||
| `paragraph.task-list` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>X</kbd> | Insert a task list |
|
||||
| `paragraph.loose-list-item` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>L</kbd> | Convert a list item to a loose list item |
|
||||
| `paragraph.paragraph` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>0</kbd> | Convert a heading to a paragraph |
|
||||
| `paragraph.horizontal-line` | <kbd>Ctrl</kbd>+<kbd>H</kbd> | Add a horizontal line |
|
||||
| `paragraph.horizontal-line` | <kbd>Ctrl</kbd>+<kbd>\_</kbd> | Add a horizontal line |
|
||||
| `paragraph.front-matter` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Y</kbd> | Insert a YAML frontmatter block |
|
||||
|
||||
#### Format menu
|
||||
@ -79,7 +79,7 @@ MarkText key bindings for Linux. Please see [general key bindings](KEYBINDINGS.m
|
||||
| `format.superscript` | - | Change the selected text to underline |
|
||||
| `format.subscript` | - | Change the selected text to underline |
|
||||
| `format.highlight` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>H</kbd> | Highlight the selected text by <mark>tag</mark> |
|
||||
| `format.inline-code` | <kbd>Ctrl</kbd>+<kbd>`</kbd> | Change the selected text to inline code |
|
||||
| `format.inline-code` | <kbd>Ctrl</kbd>+<kbd>Y</kbd> | Change the selected text to inline code |
|
||||
| `format.inline-math` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>M</kbd> | Change the selected text to inline math |
|
||||
| `format.strike` | <kbd>Ctrl</kbd>+<kbd>D</kbd> | Strike through the selected text |
|
||||
| `format.hyperlink` | <kbd>Ctrl</kbd>+<kbd>L</kbd> | Insert a hyperlink |
|
||||
@ -136,4 +136,4 @@ MarkText key bindings for Linux. Please see [general key bindings](KEYBINDINGS.m
|
||||
|
||||
| Id | Default | Description |
|
||||
| ----------------- | ---------------------------- | ---------------------- |
|
||||
| `file.quick-open` | <kbd>Ctrl</kbd>+<kbd>P</kbd> | Open quick open dialog |
|
||||
| `file.quick-open` | <kbd>Ctrl</kbd>+<kbd>P</kbd> | Show quick open dialog |
|
||||
|
@ -6,12 +6,12 @@ MarkText key bindings for macOS. Please see [general key bindings](KEYBINDINGS.m
|
||||
|
||||
#### MarkText menu
|
||||
|
||||
| Id | Default | Description |
|
||||
| ------------------ | ---------------------------------------------- | -------------------------------------- |
|
||||
| `mt.hide` | <kbd>Command</kbd>+<kbd>H</kbd> | Hide MarkText |
|
||||
| `mt.hide-others` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> | Hide all other windows except MarkText |
|
||||
| `file.preferences` | <kbd>Command</kbd>+<kbd>,</kbd> | Open settings window |
|
||||
| `file.quit` | <kbd>Command</kbd>+<kbd>Q</kbd> | Quit MarkText |
|
||||
| Id | Default | Description |
|
||||
| ------------------ | ------------------------------------------------- | -------------------------------------- |
|
||||
| `mt.hide` | <kbd>Command</kbd>+<kbd>H</kbd> | Hide MarkText |
|
||||
| `mt.hide-others` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>H</kbd> | Hide all other windows except MarkText |
|
||||
| `file.preferences` | <kbd>Command</kbd>+<kbd>,</kbd> | Open settings window |
|
||||
| `file.quit` | <kbd>Command</kbd>+<kbd>Q</kbd> | Quit MarkText |
|
||||
|
||||
#### File menu
|
||||
|
||||
@ -31,51 +31,51 @@ MarkText key bindings for macOS. Please see [general key bindings](KEYBINDINGS.m
|
||||
|
||||
#### Edit menu
|
||||
|
||||
| Id | Default | Description |
|
||||
|:------------------------ | ------------------------------------------------ | ----------------------------------------------- |
|
||||
| `edit.undo` | <kbd>Command</kbd>+<kbd>Z</kbd> | Undo last operation |
|
||||
| `edit.redo` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd> | Redo last operation |
|
||||
| `edit.cut` | <kbd>Command</kbd>+<kbd>X</kbd> | Cut selected text |
|
||||
| `edit.copy` | <kbd>Command</kbd>+<kbd>C</kbd> | Copy selected text |
|
||||
| `edit.paste` | <kbd>Command</kbd>+<kbd>V</kbd> | Paste text |
|
||||
| `edit.copy-as-markdown` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>C</kbd> | Copy selected text as markdown |
|
||||
| `edit.copy-as-html` | - | Copy selected text as html |
|
||||
| `edit.paste-as-plaintext` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd> | Copy selected text as plaintext |
|
||||
| `edit.select-all` | <kbd>Command</kbd>+<kbd>A</kbd> | Select all text of the document |
|
||||
| `edit.duplicate` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>P</kbd> | Duplicate the current paragraph |
|
||||
| `edit.create-paragraph` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>N</kbd> | Create a new paragraph after the current one |
|
||||
| `edit.delete-paragraph` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>D</kbd> | Delete current paragraph |
|
||||
| `edit.find` | <kbd>Command</kbd>+<kbd>F</kbd> | Find information in the document |
|
||||
| `edit.find-next` | <kbd>Cmd</kbd>+<kbd>G</kbd> | Continue the search and find the next match |
|
||||
| `edit.find-previous` | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>G</kbd> | Continue the search and find the previous match |
|
||||
| `edit.replace` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>F</kbd> | Replace the information with a replacement |
|
||||
| `edit.find-in-folder` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>F</kbd> | Find files contain the keyword in opend folder |
|
||||
| `edit.screenshot` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>A</kbd> | Get the screenshot |
|
||||
| Id | Default | Description |
|
||||
|:------------------------- | ------------------------------------------------- | ----------------------------------------------- |
|
||||
| `edit.undo` | <kbd>Command</kbd>+<kbd>Z</kbd> | Undo last operation |
|
||||
| `edit.redo` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd> | Redo last operation |
|
||||
| `edit.cut` | <kbd>Command</kbd>+<kbd>X</kbd> | Cut selected text |
|
||||
| `edit.copy` | <kbd>Command</kbd>+<kbd>C</kbd> | Copy selected text |
|
||||
| `edit.paste` | <kbd>Command</kbd>+<kbd>V</kbd> | Paste text |
|
||||
| `edit.copy-as-markdown` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>C</kbd> | Copy selected text as markdown |
|
||||
| `edit.copy-as-html` | - | Copy selected text as html |
|
||||
| `edit.paste-as-plaintext` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd> | Copy selected text as plaintext |
|
||||
| `edit.select-all` | <kbd>Command</kbd>+<kbd>A</kbd> | Select all text of the document |
|
||||
| `edit.duplicate` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>P</kbd> | Duplicate the current paragraph |
|
||||
| `edit.create-paragraph` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>N</kbd> | Create a new paragraph after the current one |
|
||||
| `edit.delete-paragraph` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>D</kbd> | Delete current paragraph |
|
||||
| `edit.find` | <kbd>Command</kbd>+<kbd>F</kbd> | Find information in the document |
|
||||
| `edit.find-next` | <kbd>Cmd</kbd>+<kbd>G</kbd> | Continue the search and find the next match |
|
||||
| `edit.find-previous` | <kbd>Shift</kbd>+<kbd>Cmd</kbd>+<kbd>G</kbd> | Continue the search and find the previous match |
|
||||
| `edit.replace` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>F</kbd> | Replace the information with a replacement |
|
||||
| `edit.find-in-folder` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>F</kbd> | Find files contain the keyword in opend folder |
|
||||
| `edit.screenshot` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>A</kbd> | Get the screenshot |
|
||||
|
||||
#### Paragraph menu
|
||||
|
||||
| Id | Default | Description |
|
||||
| --------------------------- | ------------------------------------------------ | ---------------------------------------- |
|
||||
| `paragraph.heading-1` | <kbd>Command</kbd>+<kbd>1</kbd> | Set line as heading 1 |
|
||||
| `paragraph.heading-2` | <kbd>Command</kbd>+<kbd>2</kbd> | Set line as heading 2 |
|
||||
| `paragraph.heading-3` | <kbd>Command</kbd>+<kbd>3</kbd> | Set line as heading 3 |
|
||||
| `paragraph.heading-4` | <kbd>Command</kbd>+<kbd>4</kbd> | Set line as heading 4 |
|
||||
| `paragraph.heading-5` | <kbd>Command</kbd>+<kbd>5</kbd> | Set line as heading 5 |
|
||||
| `paragraph.heading-6` | <kbd>Command</kbd>+<kbd>6</kbd> | Set line as heading 6 |
|
||||
| `paragraph.upgrade-heading` | <kbd>Command</kbd>+<kbd>=</kbd> | Upgrade a heading |
|
||||
| `paragraph.degrade-heading` | <kbd>Command</kbd>+<kbd>-</kbd> | Degrade a heading |
|
||||
| `paragraph.table` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd> | Insert a table |
|
||||
| `paragraph.code-fence` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd> | Insert a code block |
|
||||
| `paragraph.quote-block` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>Q</kbd> | Insert a quote block |
|
||||
| `paragraph.math-formula` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>M</kbd> | Insert a math block |
|
||||
| `paragraph.html-block` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>J</kbd> | Insert a HTML block |
|
||||
| `paragraph.order-list` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>O</kbd> | Insert a ordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>U</kbd> | Insert a unordered list |
|
||||
| `paragraph.task-list` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>X</kbd> | Insert a task list |
|
||||
| `paragraph.loose-list-item` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>L</kbd> | Convert a list item to a loose list item |
|
||||
| `paragraph.paragraph` | <kbd>Command</kbd>+<kbd>0</kbd> | Convert a heading to a paragraph |
|
||||
| `paragraph.horizontal-line` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>-</kbd> | Add a horizontal line |
|
||||
| `paragraph.front-matter` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>Y</kbd> | Insert a YAML frontmatter block |
|
||||
| Id | Default | Description |
|
||||
| --------------------------- | ------------------------------------------------- | ---------------------------------------- |
|
||||
| `paragraph.heading-1` | <kbd>Command</kbd>+<kbd>1</kbd> | Set line as heading 1 |
|
||||
| `paragraph.heading-2` | <kbd>Command</kbd>+<kbd>2</kbd> | Set line as heading 2 |
|
||||
| `paragraph.heading-3` | <kbd>Command</kbd>+<kbd>3</kbd> | Set line as heading 3 |
|
||||
| `paragraph.heading-4` | <kbd>Command</kbd>+<kbd>4</kbd> | Set line as heading 4 |
|
||||
| `paragraph.heading-5` | <kbd>Command</kbd>+<kbd>5</kbd> | Set line as heading 5 |
|
||||
| `paragraph.heading-6` | <kbd>Command</kbd>+<kbd>6</kbd> | Set line as heading 6 |
|
||||
| `paragraph.upgrade-heading` | <kbd>Command</kbd>+<kbd>=</kbd> | Upgrade a heading |
|
||||
| `paragraph.degrade-heading` | <kbd>Command</kbd>+<kbd>-</kbd> | Degrade a heading |
|
||||
| `paragraph.table` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd> | Insert a table |
|
||||
| `paragraph.code-fence` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>C</kbd> | Insert a code block |
|
||||
| `paragraph.quote-block` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>Q</kbd> | Insert a quote block |
|
||||
| `paragraph.math-formula` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>M</kbd> | Insert a math block |
|
||||
| `paragraph.html-block` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>J</kbd> | Insert a HTML block |
|
||||
| `paragraph.order-list` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>O</kbd> | Insert a ordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>U</kbd> | Insert a unordered list |
|
||||
| `paragraph.task-list` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>X</kbd> | Insert a task list |
|
||||
| `paragraph.loose-list-item` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>L</kbd> | Convert a list item to a loose list item |
|
||||
| `paragraph.paragraph` | <kbd>Command</kbd>+<kbd>0</kbd> | Convert a heading to a paragraph |
|
||||
| `paragraph.horizontal-line` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>-</kbd> | Add a horizontal line |
|
||||
| `paragraph.front-matter` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>Y</kbd> | Insert a YAML frontmatter block |
|
||||
|
||||
#### Format menu
|
||||
|
||||
@ -106,18 +106,18 @@ MarkText key bindings for macOS. Please see [general key bindings](KEYBINDINGS.m
|
||||
|
||||
#### View menu
|
||||
|
||||
| Id | Default | Description |
|
||||
| ----------------------- | ------------------------------------------------ | ---------------------------------------- |
|
||||
| `view.command-palette` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> | Toggle command palette |
|
||||
| `view.source-code-mode` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>S</kbd> | Switch to source code mode |
|
||||
| `view.typewriter-mode` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>T</kbd> | Enable typewriter mode |
|
||||
| `view.focus-mode` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>J</kbd> | Enable focus mode |
|
||||
| `view.toggle-sidebar` | <kbd>Command</kbd>+<kbd>J</kbd> | Toggle sidebar |
|
||||
| `view.toggle-tabbar` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>B</kbd> | Toggle tabbar |
|
||||
| `view.toggle-toc` . | <kbd>Command</kbd>+<kbd>K</kbd> | Toggle table of contents |
|
||||
| `view.toggle-dev-tools` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>I</kbd> | Toggle developer tools (debug mode only) |
|
||||
| `view.dev-reload` | <kbd>Command</kbd>+<kbd>Alt</kbd>+<kbd>R</kbd> | Reload window (debug mode only) |
|
||||
| `view.reload-images` | <kbd>Command</kbd>+<kbd>R</kbd> | Reload images |
|
||||
| Id | Default | Description |
|
||||
| ----------------------- | ------------------------------------------------- | ---------------------------------------- |
|
||||
| `view.command-palette` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> | Toggle command palette |
|
||||
| `view.source-code-mode` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>S</kbd> | Switch to source code mode |
|
||||
| `view.typewriter-mode` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>T</kbd> | Enable typewriter mode |
|
||||
| `view.focus-mode` | <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>J</kbd> | Enable focus mode |
|
||||
| `view.toggle-sidebar` | <kbd>Command</kbd>+<kbd>J</kbd> | Toggle sidebar |
|
||||
| `view.toggle-tabbar` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>B</kbd> | Toggle tabbar |
|
||||
| `view.toggle-toc` . | <kbd>Command</kbd>+<kbd>K</kbd> | Toggle table of contents |
|
||||
| `view.toggle-dev-tools` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>I</kbd> | Toggle developer tools (debug mode only) |
|
||||
| `view.dev-reload` | <kbd>Command</kbd>+<kbd>Option</kbd>+<kbd>R</kbd> | Reload window (debug mode only) |
|
||||
| `view.reload-images` | <kbd>Command</kbd>+<kbd>R</kbd> | Reload images |
|
||||
|
||||
## Available key bindings
|
||||
|
||||
|
@ -57,16 +57,16 @@ MarkText key bindings for Windows. Please see [general key bindings](KEYBINDINGS
|
||||
| `paragraph.upgrade-heading` | <kbd>Ctrl</kbd>+<kbd>=</kbd> | Upgrade a heading |
|
||||
| `paragraph.degrade-heading` | <kbd>Ctrl</kbd>+<kbd>-</kbd> | Degrade a heading |
|
||||
| `paragraph.table` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd> | Insert a table |
|
||||
| `paragraph.code-fence` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd> | Insert a code block |
|
||||
| `paragraph.quote-block` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Q</kbd> | Insert a quote block |
|
||||
| `paragraph.math-formula` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>M</kbd> | Insert a math block |
|
||||
| `paragraph.code-fence` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> | Insert a code block |
|
||||
| `paragraph.quote-block` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Q</kbd> | Insert a quote block |
|
||||
| `paragraph.math-formula` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>N</kbd> | Insert a math block |
|
||||
| `paragraph.html-block` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>H</kbd> | Insert a HTML block |
|
||||
| `paragraph.order-list` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>O</kbd> | Insert a ordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>U</kbd> | Insert a unordered list |
|
||||
| `paragraph.order-list` | <kbd>Ctrl</kbd>+<kbd>G</kbd> | Insert a ordered list |
|
||||
| `paragraph.bullet-list` | <kbd>Ctrl</kbd>+<kbd>H</kbd> | Insert a unordered list |
|
||||
| `paragraph.task-list` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>X</kbd> | Insert a task list |
|
||||
| `paragraph.loose-list-item` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>L</kbd> | Convert a list item to a loose list item |
|
||||
| `paragraph.paragraph` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>0</kbd> | Convert a heading to a paragraph |
|
||||
| `paragraph.horizontal-line` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>-</kbd> | Add a horizontal line |
|
||||
| `paragraph.horizontal-line` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd> | Add a horizontal line |
|
||||
| `paragraph.front-matter` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Y</kbd> | Insert a YAML frontmatter block |
|
||||
|
||||
#### Format menu
|
||||
@ -102,7 +102,7 @@ MarkText key bindings for Windows. Please see [general key bindings](KEYBINDINGS
|
||||
| ----------------------- | --------------------------------------------- | ---------------------------------------- |
|
||||
| `view.command-palette` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> | Toggle command palette |
|
||||
| `view.source-code-mode` | <kbd>Ctrl</kbd>+<kbd>E</kbd> | Switch to source code mode |
|
||||
| `view.typewriter-mode` | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>T</kbd> | Enable typewriter mode |
|
||||
| `view.typewriter-mode` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd> | Enable typewriter mode |
|
||||
| `view.focus-mode` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>J</kbd> | Enable focus mode |
|
||||
| `view.toggle-sidebar` | <kbd>Ctrl</kbd>+<kbd>J</kbd> | Toggle sidebar |
|
||||
| `view.toggle-tabbar` | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>B</kbd> | Toggle tabbar |
|
||||
|
@ -12,9 +12,11 @@ files:
|
||||
- "!**/node_modules/**/{CHANGELOG.md,README.md,README,readme.md,readme}"
|
||||
- "!node_modules/css-b64-images/{draft.png,draft.xcf}"
|
||||
- "!node_modules/dagre-d3-renderer/dist/demo/"
|
||||
- "!node_modules/dagre-d3/dist/demo/"
|
||||
- "!node_modules/dragula/resources"
|
||||
- "!node_modules/**/*.js.map"
|
||||
- "!node_modules/**/*.cjs.map"
|
||||
- "!node_modules/**/*.mjs.map"
|
||||
- "!node_modules/**/*.ts.map"
|
||||
# Don't bundle build files
|
||||
- "!node_modules/@felixrieseberg/spellchecker/bin"
|
||||
@ -26,6 +28,16 @@ files:
|
||||
- "!node_modules/fontmanager-redux/bin"
|
||||
- "!node_modules/keyboard-layout/bin"
|
||||
- "!node_modules/keytar/bin"
|
||||
- "!node_modules/native-keymap/bin"
|
||||
# Large source files that aren't needed
|
||||
- "!node_modules/dagre-d3/dist/dagre-d3.min.js"
|
||||
- "!node_modules/mermaid/dist/mermaid.js"
|
||||
- "!node_modules/mermaid/dist/mermaid.min.js"
|
||||
- "!node_modules/mermaid/dist/mermaid.esm.min.mjs"
|
||||
- "!node_modules/katex/dist/katex.min.js"
|
||||
- "!node_modules/katex/dist/katex.mjs"
|
||||
- "!node_modules/vega/build-es5/"
|
||||
- "!node_modules/vega-embed/build-es5/"
|
||||
# Don't bundle Linux build files
|
||||
- "!node_modules/@hfelix/spellchecker/build/Release/hunspell.a"
|
||||
- "!node_modules/ced/build/Release/compact_enc_det.a"
|
||||
|
55
package.json
55
package.json
@ -33,23 +33,22 @@
|
||||
"validate-licenses": "node tools/validateLicenses.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.1",
|
||||
"@hfelix/electron-localshortcut": "^3.1.1",
|
||||
"@electron/remote": "^2.0.4",
|
||||
"@hfelix/electron-localshortcut": "^4.0.0-rc.1",
|
||||
"@hfelix/electron-spellchecker": "^2.0.0",
|
||||
"@marktext/file-icons": "^1.0.6",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"arg": "^5.0.1",
|
||||
"axios": "^0.24.0",
|
||||
"axios": "^0.25.0",
|
||||
"ced": "^2.0.0",
|
||||
"chokidar": "^3.5.2",
|
||||
"codemirror": "^5.65.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"codemirror": "^5.65.1",
|
||||
"command-exists": "^1.2.9",
|
||||
"dayjs": "^1.10.7",
|
||||
"dom-autoscroller": "^2.3.4",
|
||||
"dompurify": "^2.3.4",
|
||||
"dompurify": "^2.3.5",
|
||||
"dragula": "^3.7.3",
|
||||
"electron-is-accelerator": "^0.2.0",
|
||||
"electron-log": "^4.4.4",
|
||||
"electron-log": "^4.4.5",
|
||||
"electron-store": "^8.0.1",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"element-resize-detector": "^1.2.4",
|
||||
@ -62,17 +61,17 @@
|
||||
"github-markdown-css": "^3.0.1",
|
||||
"html-tags": "^3.1.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"iso-639-1": "^2.1.11",
|
||||
"iso-639-1": "^2.1.12",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.12",
|
||||
"katex": "^0.15.2",
|
||||
"keyboard-layout": "^2.0.17",
|
||||
"keytar": "^7.7.0",
|
||||
"mermaid": "^8.13.10",
|
||||
"minizlib": "^2.1.1",
|
||||
"minizlib": "^2.1.2",
|
||||
"native-keymap": "^3.1.1",
|
||||
"plist": "^3.0.4",
|
||||
"popper.js": "^1.16.1",
|
||||
"prismjs": "^1.26.0",
|
||||
"snabbdom": "^3.2.0",
|
||||
"snabbdom": "^3.3.1",
|
||||
"snabbdom-to-html": "^7.0.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"turndown": "^7.1.1",
|
||||
@ -89,36 +88,36 @@
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.7",
|
||||
"@babel/core": "^7.16.12",
|
||||
"@babel/eslint-parser": "^7.16.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.16.7",
|
||||
"@babel/plugin-proposal-function-bind": "^7.16.7",
|
||||
"@babel/plugin-syntax-class-properties": "^7.12.13",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.16.8",
|
||||
"@babel/preset-env": "^7.16.8",
|
||||
"@babel/plugin-transform-runtime": "^7.16.10",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/register": "^7.16.9",
|
||||
"@babel/runtime": "^7.16.7",
|
||||
"@markedjs/html-differ": "^4.0.0",
|
||||
"@playwright/test": "^1.17.2",
|
||||
"@playwright/test": "^1.18.1",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"cfonts": "^2.10.0",
|
||||
"chai": "^4.3.4",
|
||||
"chai": "^4.3.6",
|
||||
"chalk": "^4.1.2",
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"copy-webpack-plugin": "^10.2.0",
|
||||
"copy-webpack-plugin": "^10.2.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.5.1",
|
||||
"del": "^6.0.0",
|
||||
"devtron": "^1.4.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"electron": "^15.3.4",
|
||||
"electron-builder": "^22.14.8",
|
||||
"electron": "^15.3.6",
|
||||
"electron-builder": "^22.14.13",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-rebuild": "^3.2.5",
|
||||
"electron-rebuild": "^3.2.7",
|
||||
"electron-updater": "^4.6.3",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
@ -129,30 +128,30 @@
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^6.0.0",
|
||||
"eslint-plugin-standard": "^4.1.0",
|
||||
"eslint-plugin-vue": "^8.2.0",
|
||||
"eslint-plugin-vue": "^8.4.0",
|
||||
"eslint-webpack-plugin": "^3.1.1",
|
||||
"esm": "^3.2.25",
|
||||
"file-loader": "^6.2.0",
|
||||
"git-revision-webpack-plugin": "^5.0.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"karma": "^6.3.11",
|
||||
"karma": "^6.3.12",
|
||||
"karma-chai": "^0.1.0",
|
||||
"karma-coverage": "^2.1.0",
|
||||
"karma-electron": "^7.1.0",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-sourcemap-loader": "^0.3.8",
|
||||
"karma-spec-reporter": "0.0.32",
|
||||
"karma-spec-reporter": "0.0.33",
|
||||
"karma-webpack": "^5.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"listr": "^0.14.3",
|
||||
"marked": "^1.2.9",
|
||||
"mini-css-extract-plugin": "^2.5.1",
|
||||
"mini-css-extract-plugin": "^2.5.3",
|
||||
"mocha": "^8.4.0",
|
||||
"node-fetch": "^2.6.6",
|
||||
"node-loader": "^2.0.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"playwright": "^1.17.2",
|
||||
"playwright": "^1.18.1",
|
||||
"postcss": "^8.4.5",
|
||||
"postcss-loader": "^6.2.1",
|
||||
"postcss-preset-env": "^7.2.3",
|
||||
@ -168,9 +167,9 @@
|
||||
"vue-loader": "^15.9.8",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"webpack": "^5.66.0",
|
||||
"webpack": "^5.67.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.7.3",
|
||||
"webpack-hot-middleware": "^2.25.1",
|
||||
"webpack-merge": "^5.8.0"
|
||||
|
File diff suppressed because it is too large
Load Diff
32
src/common/keybinding/index.js
Normal file
32
src/common/keybinding/index.js
Normal file
@ -0,0 +1,32 @@
|
||||
const isOsx = process.platform === 'darwin'
|
||||
|
||||
const _normalizeAccelerator = accelerator => {
|
||||
return accelerator.toLowerCase()
|
||||
.replace('commandorcontrol', isOsx ? 'cmd' : 'ctrl')
|
||||
.replace('cmdorctrl', isOsx ? 'cmd' : 'ctrl')
|
||||
.replace('control', 'ctrl')
|
||||
.replace('meta', 'cmd') // meta := cmd (macOS only) or super
|
||||
.replace('command', 'cmd')
|
||||
.replace('option', 'alt')
|
||||
}
|
||||
|
||||
export const isEqualAccelerator = (a, b) => {
|
||||
a = _normalizeAccelerator(a)
|
||||
b = _normalizeAccelerator(b)
|
||||
const i1 = a.indexOf('+')
|
||||
const i2 = b.indexOf('+')
|
||||
if (i1 === -1 && i2 === -1) {
|
||||
return a === b
|
||||
} else if (i1 === -1 || i2 === -1) {
|
||||
return false
|
||||
}
|
||||
|
||||
const partsA = a.split('+')
|
||||
const partsB = b.split('+')
|
||||
if (partsA.length !== partsB.length || partsA.length <= 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
const intersection = new Set([...partsA, ...partsB])
|
||||
return intersection.size === partsB.length
|
||||
}
|
@ -9,6 +9,7 @@ import { isLinux, isOsx, isWindows } from '../config'
|
||||
import parseArgs from '../cli/parser'
|
||||
import { normalizeAndResolvePath } from '../filesystem'
|
||||
import { normalizeMarkdownPath } from '../filesystem/markdown'
|
||||
import { registerKeyboardListeners } from '../keyboard'
|
||||
import { selectTheme } from '../menu/actions/theme'
|
||||
import { dockMenu } from '../menu/templates'
|
||||
import ensureDefaultDict from '../preferences/hunspell'
|
||||
@ -427,6 +428,8 @@ class App {
|
||||
}
|
||||
|
||||
_listenForIpcMain () {
|
||||
registerKeyboardListeners()
|
||||
|
||||
ipcMain.on('app-create-editor-window', () => {
|
||||
this._createEditorWindow()
|
||||
})
|
||||
@ -566,6 +569,18 @@ class App {
|
||||
const { keybindings } = this._accessor
|
||||
keybindings.openConfigInFileManager()
|
||||
})
|
||||
|
||||
ipcMain.handle('mt::keybinding-get-pref-keybindings', () => {
|
||||
const { keybindings } = this._accessor
|
||||
const defaultKeybindings = keybindings.getDefaultKeybindings()
|
||||
const userKeybindings = keybindings.getUserKeybindings()
|
||||
return { defaultKeybindings, userKeybindings }
|
||||
})
|
||||
|
||||
ipcMain.handle('mt::keybinding-save-user-keybindings', async (event, userKeybindings) => {
|
||||
const { keybindings } = this._accessor
|
||||
return await keybindings.setUserKeybindings(userKeybindings)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ import { app } from 'electron'
|
||||
import os from 'os'
|
||||
import { isDirectory } from 'common/filesystem'
|
||||
import parseArgs from './parser'
|
||||
import { dumpKeyboardInformation } from '../keyboard'
|
||||
import { getPath } from '../utils'
|
||||
|
||||
const write = s => process.stdout.write(s)
|
||||
@ -24,7 +23,6 @@ const cli = () => {
|
||||
|
||||
--debug Enable debug mode
|
||||
--safe Disable plugins and other user configuration
|
||||
--dump-keyboard-layout Dump keyboard information
|
||||
-n, --new-window Open a new window on second-instance
|
||||
--user-data-dir Change the user data directory
|
||||
--disable-gpu Disable GPU hardware acceleration
|
||||
@ -44,11 +42,6 @@ const cli = () => {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (args['--dump-keyboard-layout']) {
|
||||
writeLine(dumpKeyboardInformation())
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// Check for portable mode and ensure the user data path is absolute. We assume
|
||||
// that the path is writable if not this lead to an application crash.
|
||||
if (!args['--user-data-dir']) {
|
||||
|
@ -14,7 +14,6 @@ const parseArgs = (argv = null, permissive = true) => {
|
||||
const spec = {
|
||||
'--debug': Boolean,
|
||||
'--safe': Boolean,
|
||||
'--dump-keyboard-layout': Boolean,
|
||||
|
||||
'--new-window': Boolean,
|
||||
'-n': '--new-window',
|
||||
|
@ -12,7 +12,7 @@ export const editorWinOptions = Object.freeze({
|
||||
webSecurity: false
|
||||
},
|
||||
useContentSize: true,
|
||||
show: true, // Show the window after the app is ready.
|
||||
show: true,
|
||||
frame: false,
|
||||
titleBarStyle: 'hiddenInset',
|
||||
zoomFactor: 1.0
|
||||
@ -31,9 +31,7 @@ export const preferencesWinOptions = Object.freeze({
|
||||
},
|
||||
fullscreenable: false,
|
||||
fullscreen: false,
|
||||
resizable: false,
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
useContentSize: true,
|
||||
show: true,
|
||||
frame: false,
|
||||
|
@ -1,56 +1,76 @@
|
||||
// import EventEmitter from 'events'
|
||||
import { getCurrentKeyboardLayout, getCurrentKeyboardLanguage, getCurrentKeymap } from 'keyboard-layout'
|
||||
import { ipcMain, shell } from 'electron'
|
||||
import log from 'electron-log'
|
||||
import EventEmitter from 'events'
|
||||
import fsPromises from 'fs/promises'
|
||||
import { getCurrentKeyboardLayout, getKeyMap, onDidChangeKeyboardLayout } from 'native-keymap'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
|
||||
export const getKeyboardLanguage = () => {
|
||||
const lang = getCurrentKeyboardLanguage()
|
||||
if (lang.length >= 2) {
|
||||
return lang.substring(0, 2)
|
||||
let currentKeyboardInfo = null
|
||||
const loadKeyboardInfo = () => {
|
||||
currentKeyboardInfo = {
|
||||
layout: getCurrentKeyboardLayout(),
|
||||
keymap: getKeyMap()
|
||||
}
|
||||
return lang
|
||||
return currentKeyboardInfo
|
||||
}
|
||||
|
||||
export const dumpKeyboardInformation = () => {
|
||||
return `Layout: ${getCurrentKeyboardLayout()}\n` +
|
||||
`Language: ${getCurrentKeyboardLanguage()}\n\n` +
|
||||
JSON.stringify(getCurrentKeymap(), null, 2)
|
||||
export const getKeyboardInfo = () => {
|
||||
if (!currentKeyboardInfo) {
|
||||
return loadKeyboardInfo()
|
||||
}
|
||||
return currentKeyboardInfo
|
||||
}
|
||||
|
||||
export const getVirtualLetters = () => {
|
||||
// Full list of supported virtual keys:
|
||||
// https://github.com/parro-it/keyboardevent-from-electron-accelerator/blob/afdbd57bead1e139d7bd03c763778dce6ca8c35d/main.js#L104
|
||||
const currentKeymap = getCurrentKeymap()
|
||||
const vkeys = {}
|
||||
for (const key in currentKeymap) {
|
||||
// TODO(fxha): Possibly, we can fix more broken accelerators without apply a manually fix later.
|
||||
if (!key.startsWith('Key')) {
|
||||
continue
|
||||
}
|
||||
const unmodifiedKey = currentKeymap[key].unmodified
|
||||
if (unmodifiedKey) {
|
||||
// uppercase character / vkey name (A: KeyA)
|
||||
vkeys[unmodifiedKey.toUpperCase()] = key
|
||||
const KEYBOARD_LAYOUT_MONITOR_CHANNEL_ID = 'onDidChangeKeyboardLayout'
|
||||
class KeyboardLayoutMonitor extends EventEmitter {
|
||||
constructor () {
|
||||
super()
|
||||
this._isSubscribed = false
|
||||
this._emitTimer = null
|
||||
}
|
||||
|
||||
addListener (callback) {
|
||||
this._ensureNativeListener()
|
||||
this.on(KEYBOARD_LAYOUT_MONITOR_CHANNEL_ID, callback)
|
||||
}
|
||||
|
||||
removeListener (callback) {
|
||||
this.removeListener(KEYBOARD_LAYOUT_MONITOR_CHANNEL_ID, callback)
|
||||
}
|
||||
|
||||
_ensureNativeListener () {
|
||||
if (!this._isSubscribed) {
|
||||
this._isSubscribed = true
|
||||
onDidChangeKeyboardLayout(() => {
|
||||
// The keyboard layout change event may be emitted multiple times.
|
||||
clearTimeout(this._emitTimer)
|
||||
this._emitTimer = setTimeout(() => {
|
||||
this.emit(KEYBOARD_LAYOUT_MONITOR_CHANNEL_ID, loadKeyboardInfo())
|
||||
this._emitTimer = null
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
}
|
||||
return vkeys
|
||||
}
|
||||
|
||||
// class KeyboardLayoutMonitor {
|
||||
//
|
||||
// constructor() {
|
||||
// this._eventEmitter = new EventEmitter()
|
||||
// this._subscription = null
|
||||
// }
|
||||
//
|
||||
// onDidChangeCurrentKeyboardLayout (callback) {
|
||||
// if (!this._subscription) {
|
||||
// this._subscription = onDidChangeCurrentKeyboardLayout(layout => {
|
||||
// this._eventEmitter.emit('onDidChangeCurrentKeyboardLayout', layout)
|
||||
// })
|
||||
// }
|
||||
// this._eventEmitter.on('onDidChangeCurrentKeyboardLayout', callback)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // TODO(@fxha): Reload ShortcutHandler on change
|
||||
// export const keyboardLayoutMonitor = new KeyboardLayoutMonitor()
|
||||
// Export a single-instance of the monitor.
|
||||
export const keyboardLayoutMonitor = new KeyboardLayoutMonitor()
|
||||
|
||||
export const registerKeyboardListeners = () => {
|
||||
ipcMain.handle('mt::keybinding-get-keyboard-info', async () => {
|
||||
return getKeyboardInfo()
|
||||
})
|
||||
ipcMain.on('mt::keybinding-debug-dump-keyboard-info', async () => {
|
||||
const dumpPath = path.join(os.tmpdir(), 'marktext_keyboard_info.json')
|
||||
const content = JSON.stringify(getKeyboardInfo(), null, 2)
|
||||
fsPromises.writeFile(dumpPath, content, 'utf8')
|
||||
.then(() => {
|
||||
console.log(`Keyboard information written to "${dumpPath}".`)
|
||||
shell.openPath(dumpPath)
|
||||
})
|
||||
.catch(error => {
|
||||
log.error('Error dumping keyboard information:', error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
// Key bindings for macOS.
|
||||
|
||||
// NOTE: Avoid pure `Option` aka `Alt` shortcuts on macOS because these are used to produce alternative characters on all letters and digits.
|
||||
// Our current key manager will forbid the usage of these key combinations too.
|
||||
|
||||
export default new Map([
|
||||
// MarkText menu
|
||||
['mt.hide', 'Command+H'],
|
||||
['mt.hide-others', 'Command+Alt+H'],
|
||||
['mt.hide-others', 'Command+Option+H'],
|
||||
['file.preferences', 'Command+,'], // located under MarkText menu in macOS only
|
||||
|
||||
// File menu
|
||||
@ -30,15 +33,15 @@ export default new Map([
|
||||
['edit.copy-as-html', ''],
|
||||
['edit.paste-as-plaintext', 'Command+Shift+V'],
|
||||
['edit.select-all', 'Command+A'],
|
||||
['edit.duplicate', 'Command+Alt+D'],
|
||||
['edit.duplicate', 'Command+Option+D'],
|
||||
['edit.create-paragraph', 'Shift+Command+N'],
|
||||
['edit.delete-paragraph', 'Shift+Command+D'],
|
||||
['edit.find', 'Command+F'],
|
||||
['edit.find-next', 'Cmd+G'],
|
||||
['edit.find-previous', 'Cmd+Shift+G'],
|
||||
['edit.replace', 'Command+Alt+F'],
|
||||
['edit.replace', 'Command+Option+F'],
|
||||
['edit.find-in-folder', 'Shift+Command+F'],
|
||||
['edit.screenshot', 'Command+Alt+A'], // macOS only
|
||||
['edit.screenshot', 'Command+Option+A'], // macOS only
|
||||
|
||||
// Paragraph menu
|
||||
['paragraph.heading-1', 'Command+1'],
|
||||
@ -50,17 +53,17 @@ export default new Map([
|
||||
['paragraph.upgrade-heading', 'Command+='],
|
||||
['paragraph.degrade-heading', 'Command+-'],
|
||||
['paragraph.table', 'Command+Shift+T'],
|
||||
['paragraph.code-fence', 'Command+Alt+C'],
|
||||
['paragraph.quote-block', 'Command+Alt+Q'],
|
||||
['paragraph.math-formula', 'Command+Alt+M'],
|
||||
['paragraph.html-block', 'Command+Alt+J'],
|
||||
['paragraph.order-list', 'Command+Alt+O'],
|
||||
['paragraph.bullet-list', 'Command+Alt+U'],
|
||||
['paragraph.task-list', 'Command+Alt+X'],
|
||||
['paragraph.loose-list-item', 'Command+Alt+L'],
|
||||
['paragraph.code-fence', 'Command+Option+C'],
|
||||
['paragraph.quote-block', 'Command+Option+Q'],
|
||||
['paragraph.math-formula', 'Command+Option+M'],
|
||||
['paragraph.html-block', 'Command+Option+J'],
|
||||
['paragraph.order-list', 'Command+Option+O'],
|
||||
['paragraph.bullet-list', 'Command+Option+U'],
|
||||
['paragraph.task-list', 'Command+Option+X'],
|
||||
['paragraph.loose-list-item', 'Command+Option+L'],
|
||||
['paragraph.paragraph', 'Command+0'],
|
||||
['paragraph.horizontal-line', 'Command+Alt+-'],
|
||||
['paragraph.front-matter', 'Command+Alt+Y'],
|
||||
['paragraph.horizontal-line', 'Command+Option+-'],
|
||||
['paragraph.front-matter', 'Command+Option+Y'],
|
||||
|
||||
// Format menu
|
||||
['format.strong', 'Command+B'],
|
||||
@ -85,14 +88,14 @@ export default new Map([
|
||||
|
||||
// View menu
|
||||
['view.command-palette', 'Command+Shift+P'],
|
||||
['view.source-code-mode', 'Command+Alt+S'],
|
||||
['view.typewriter-mode', 'Command+Alt+T'],
|
||||
['view.source-code-mode', 'Command+Option+S'],
|
||||
['view.typewriter-mode', 'Command+Option+T'],
|
||||
['view.focus-mode', 'Command+Shift+J'],
|
||||
['view.toggle-sidebar', 'Command+J'],
|
||||
['view.toggle-toc', 'Command+K'],
|
||||
['view.toggle-tabbar', 'Command+Alt+B'],
|
||||
['view.toggle-dev-tools', 'Command+Alt+I'],
|
||||
['view.dev-reload', 'Command+Alt+R'],
|
||||
['view.toggle-tabbar', 'Command+Option+B'],
|
||||
['view.toggle-dev-tools', 'Command+Option+I'],
|
||||
['view.dev-reload', 'Command+Option+R'],
|
||||
['view.reload-images', 'Command+R'],
|
||||
|
||||
// ======== Not included in application menu ========================
|
||||
|
@ -1,6 +1,11 @@
|
||||
// Key bindings for Linux.
|
||||
|
||||
// NOTE: Avoid `Ctrl+Alt` and `Alt` shortcuts on Linux because Ubuntu based OSs have reserved system shortcuts (see GH#2370).
|
||||
// Binding shortcuts to these modifiers will result in odd behavior on Ubuntu.
|
||||
// NOTE: Don't use `Ctrl+Shift+U` because it's used IBus for unicode support.
|
||||
// NOTE: We can't determine the character for a dead key and no translation is provided. E.g. Ctrl+` (=Ctrl+Shift+´) on a
|
||||
// none nodeadkeys german keyboard cannot be interpreted. In general don't bind default shortcuts to characters that
|
||||
// can be produced with ^ or ` on any keyboard. --> ^, `, ", ~, ...
|
||||
|
||||
export default new Map([
|
||||
// MarkText menu on macOS only
|
||||
@ -57,11 +62,11 @@ export default new Map([
|
||||
['paragraph.math-formula', 'Ctrl+Alt+M'],
|
||||
['paragraph.html-block', 'Ctrl+Alt+H'],
|
||||
['paragraph.order-list', 'Ctrl+G'],
|
||||
['paragraph.bullet-list', 'Ctrl+Shift+U'],
|
||||
['paragraph.bullet-list', 'Ctrl+H'],
|
||||
['paragraph.task-list', 'Ctrl+Shift+X'],
|
||||
['paragraph.loose-list-item', 'Ctrl+Shift+L'],
|
||||
['paragraph.paragraph', 'Ctrl+Shift+0'],
|
||||
['paragraph.horizontal-line', 'Ctrl+H'],
|
||||
['paragraph.horizontal-line', 'Ctrl+_'], // Ctrl+Shift+-
|
||||
['paragraph.front-matter', 'Ctrl+Shift+Y'],
|
||||
|
||||
// Format menu
|
||||
@ -71,7 +76,7 @@ export default new Map([
|
||||
['format.superscript', ''],
|
||||
['format.subscript', ''],
|
||||
['format.highlight', 'Ctrl+Shift+H'],
|
||||
['format.inline-code', 'Ctrl+`'],
|
||||
['format.inline-code', 'Ctrl+Y'],
|
||||
['format.inline-math', 'Ctrl+Shift+M'],
|
||||
['format.strike', 'Ctrl+D'],
|
||||
['format.hyperlink', 'Ctrl+L'],
|
||||
|
@ -1,5 +1,9 @@
|
||||
// Key bindings for Windows.
|
||||
|
||||
// NOTE: Avoid `Ctrl+Alt` and `AltGr` shortcuts on Windows because these are used to produce alternative characters.
|
||||
// Unlike Linux, `Ctrl+Alt` is an alias to `AltGr` on Windows and will produce alternative characters too.
|
||||
// We'll should try bind no keys to `Alt` "modifiers" because there are only a few key bindings available.
|
||||
|
||||
export default new Map([
|
||||
// MarkText menu on macOS only
|
||||
['mt.hide', ''],
|
||||
@ -50,16 +54,16 @@ export default new Map([
|
||||
['paragraph.upgrade-heading', 'Ctrl+='],
|
||||
['paragraph.degrade-heading', 'Ctrl+-'],
|
||||
['paragraph.table', 'Ctrl+Shift+T'],
|
||||
['paragraph.code-fence', 'Ctrl+Alt+C'],
|
||||
['paragraph.quote-block', 'Ctrl+Alt+Q'],
|
||||
['paragraph.math-formula', 'Ctrl+Alt+M'],
|
||||
['paragraph.code-fence', 'Ctrl+Shift+K'],
|
||||
['paragraph.quote-block', 'Ctrl+Shift+Q'],
|
||||
['paragraph.math-formula', 'Ctrl+Alt+N'],
|
||||
['paragraph.html-block', 'Ctrl+Alt+H'],
|
||||
['paragraph.order-list', 'Ctrl+Alt+O'],
|
||||
['paragraph.bullet-list', 'Ctrl+Alt+U'],
|
||||
['paragraph.order-list', 'Ctrl+G'],
|
||||
['paragraph.bullet-list', 'Ctrl+H'],
|
||||
['paragraph.task-list', 'Ctrl+Alt+X'],
|
||||
['paragraph.loose-list-item', 'Ctrl+Alt+L'],
|
||||
['paragraph.paragraph', 'Ctrl+Shift+0'],
|
||||
['paragraph.horizontal-line', 'Ctrl+Alt+-'],
|
||||
['paragraph.horizontal-line', 'Ctrl+Shift+U'],
|
||||
['paragraph.front-matter', 'Ctrl+Alt+Y'],
|
||||
|
||||
// Format menu
|
||||
@ -86,7 +90,7 @@ export default new Map([
|
||||
// View menu
|
||||
['view.command-palette', 'Ctrl+Shift+P'],
|
||||
['view.source-code-mode', 'Ctrl+E'],
|
||||
['view.typewriter-mode', 'Ctrl+Alt+T'],
|
||||
['view.typewriter-mode', 'Ctrl+Shift+G'],
|
||||
['view.focus-mode', 'Ctrl+Shift+J'],
|
||||
['view.toggle-sidebar', 'Ctrl+J'],
|
||||
['view.toggle-toc', 'Ctrl+K'],
|
||||
|
@ -1,20 +1,17 @@
|
||||
import { shell, Menu } from 'electron'
|
||||
import fs from 'fs'
|
||||
import fsPromises from 'fs/promises'
|
||||
import path from 'path'
|
||||
import log from 'electron-log'
|
||||
import isAccelerator from 'electron-is-accelerator'
|
||||
import electronLocalshortcut from '@hfelix/electron-localshortcut'
|
||||
import { electronLocalshortcut, isValidElectronAccelerator } from '@hfelix/electron-localshortcut'
|
||||
import { isFile2 } from 'common/filesystem'
|
||||
import { isEqualAccelerator } from 'common/keybinding'
|
||||
import { isLinux, isOsx } from '../config'
|
||||
import { getKeyboardLanguage, getVirtualLetters } from '../keyboard'
|
||||
import { getKeyboardInfo, keyboardLayoutMonitor } from '../keyboard'
|
||||
import keybindingsDarwin from './keybindingsDarwin'
|
||||
import keybindingsLinux from './keybindingsLinux'
|
||||
import keybindingsWindows from './keybindingsWindows'
|
||||
|
||||
// Problematic key bindings:
|
||||
// Inline Code: Ctrl+` -> dead key
|
||||
// Upgrade Heading: Ctrl+= -> points to Ctrl+Plus which is ok; Ctrl+Plus is broken
|
||||
|
||||
class Keybindings {
|
||||
/**
|
||||
* @param {string} userDataPath The user data path.
|
||||
@ -22,11 +19,9 @@ class Keybindings {
|
||||
constructor (userDataPath) {
|
||||
this.configPath = path.join(userDataPath, 'keybindings.json')
|
||||
|
||||
this.keys = this._getOsKeyMap()
|
||||
|
||||
// Fix non-US keyboards
|
||||
this.mnemonics = new Map()
|
||||
this._fixLayout()
|
||||
this.userKeybindings = new Map()
|
||||
this.keys = this.getDefaultKeybindings()
|
||||
this._prepareKeyMapper()
|
||||
|
||||
// Load user-defined keybindings
|
||||
this._loadLocalKeybindings()
|
||||
@ -44,23 +39,11 @@ class Keybindings {
|
||||
for (const item of acceleratorMap) {
|
||||
let { accelerator } = item
|
||||
|
||||
// Fix broken shortcuts because of dead keys or non-US keyboard problems. We bind the
|
||||
// shortcut to another accelerator because of key mapping issues. E.g: 'Alt+/' is not
|
||||
// available on a German keyboard, because you have to press 'Shift+7' to produce '/'.
|
||||
// In this case we can remap the accelerator to 'Alt+7' or 'Ctrl+Shift+7'.
|
||||
const acceleratorFix = this.mnemonics.get(accelerator)
|
||||
if (acceleratorFix) {
|
||||
accelerator = acceleratorFix
|
||||
}
|
||||
|
||||
// Regisiter shortcuts on the BrowserWindow instead of using Chromium's native menu.
|
||||
// This makes it possible to receive key down events before Chromium/Electron and we
|
||||
// can handle reserved Chromium shortcuts. Afterwards prevent the default action of
|
||||
// the event so the native menu is not triggered.
|
||||
electronLocalshortcut.register(win, accelerator, () => {
|
||||
if (global.MARKTEXT_DEBUG && process.env.MARKTEXT_DEBUG_KEYBOARD) {
|
||||
console.log(`You pressed ${accelerator}`)
|
||||
}
|
||||
callMenuCallback(item, win)
|
||||
return true // prevent default action
|
||||
})
|
||||
@ -76,9 +59,7 @@ class Keybindings {
|
||||
.catch(err => console.error(err))
|
||||
}
|
||||
|
||||
// --- private --------------------------------
|
||||
|
||||
_getOsKeyMap () {
|
||||
getDefaultKeybindings () {
|
||||
if (isOsx) {
|
||||
return keybindingsDarwin
|
||||
} else if (isLinux) {
|
||||
@ -87,58 +68,50 @@ class Keybindings {
|
||||
return keybindingsWindows
|
||||
}
|
||||
|
||||
_fixLayout () {
|
||||
// Fix wrong virtual key mapping on non-QWERTY layouts
|
||||
electronLocalshortcut.updateVirtualKeys(getVirtualLetters())
|
||||
|
||||
// Fix broken shortcuts and dead keys
|
||||
const lang = getKeyboardLanguage()
|
||||
switch (lang) {
|
||||
// Fix inline code
|
||||
case 'ch':
|
||||
case 'de':
|
||||
case 'dk':
|
||||
case 'fi':
|
||||
case 'no':
|
||||
case 'se':
|
||||
this._fixInlineCode()
|
||||
if (!isOsx) {
|
||||
this._fixDeadKey()
|
||||
}
|
||||
break
|
||||
|
||||
// Fix dead key only
|
||||
case 'es':
|
||||
case 'fr':
|
||||
case 'hr':
|
||||
case 'it':
|
||||
case 'pl':
|
||||
case 'pt':
|
||||
if (!isOsx) {
|
||||
this._fixDeadKey()
|
||||
}
|
||||
break
|
||||
|
||||
// Custom layouts
|
||||
case 'bg':
|
||||
if (!isOsx) {
|
||||
this.mnemonics.set('CmdOrCtrl+/', 'CmdOrCtrl+8')
|
||||
this._fixInlineCode()
|
||||
}
|
||||
break
|
||||
}
|
||||
/**
|
||||
* Returns all user key bindings.
|
||||
*
|
||||
* @returns {Map<String, String>} User key bindings.
|
||||
*/
|
||||
getUserKeybindings () {
|
||||
return this.userKeybindings
|
||||
}
|
||||
|
||||
_fixDeadKey () {
|
||||
this.mnemonics.set('CmdOrCtrl+/', 'CmdOrCtrl+7')
|
||||
/**
|
||||
* Sets and saves the given user key bindings on disk.
|
||||
*
|
||||
* @param {Map<String, String>} userKeybindings New user key bindings.
|
||||
* @returns {Promise<Boolean>}
|
||||
*/
|
||||
async setUserKeybindings (userKeybindings) {
|
||||
this.userKeybindings = new Map(userKeybindings)
|
||||
return this._saveUserKeybindings()
|
||||
}
|
||||
|
||||
// Fix dead backquote key on layouts like German
|
||||
_fixInlineCode () {
|
||||
if (isOsx) {
|
||||
this.keys.set('format.inline-code', 'Cmd+Shift+B')
|
||||
} else {
|
||||
this.keys.set('format.inline-code', 'Ctrl+Alt+B')
|
||||
// --- private --------------------------------
|
||||
|
||||
_prepareKeyMapper () {
|
||||
// Update the key mapper to prevent problems on non-US keyboards.
|
||||
const { layout, keymap } = getKeyboardInfo()
|
||||
electronLocalshortcut.setKeyboardLayout(layout, keymap)
|
||||
|
||||
// Notify key mapper when the keyboard layout was changed.
|
||||
keyboardLayoutMonitor.addListener(({ layout, keymap }) => {
|
||||
if (global.MARKTEXT_DEBUG && process.env.MARKTEXT_DEBUG_KEYBOARD) {
|
||||
console.log('[DEBUG] Keyboard layout changed:\n', layout)
|
||||
}
|
||||
electronLocalshortcut.setKeyboardLayout(layout, keymap)
|
||||
})
|
||||
}
|
||||
|
||||
async _saveUserKeybindings () {
|
||||
const { configPath, userKeybindings } = this
|
||||
try {
|
||||
const userKeybindingJson = JSON.stringify(Object.fromEntries(userKeybindings), null, 2)
|
||||
await fsPromises.writeFile(configPath, userKeybindingJson, 'utf8')
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,14 +120,9 @@ class Keybindings {
|
||||
return
|
||||
}
|
||||
|
||||
let json
|
||||
try {
|
||||
json = JSON.parse(fs.readFileSync(this.configPath, 'utf8'))
|
||||
} catch (_) {
|
||||
json = null
|
||||
}
|
||||
if (!json || typeof json !== 'object') {
|
||||
log.warn('Invalid keybindings.json configuration.')
|
||||
const rawUserKeybindings = this._loadUserKeybindingsFromDisk()
|
||||
if (!rawUserKeybindings) {
|
||||
log.warn('Invalid keybinding configuration: failed to load or parse file.')
|
||||
return
|
||||
}
|
||||
|
||||
@ -165,15 +133,17 @@ class Keybindings {
|
||||
// }
|
||||
|
||||
const userAccelerators = new Map()
|
||||
for (const key in json) {
|
||||
for (const key in rawUserKeybindings) {
|
||||
if (this.keys.has(key)) {
|
||||
const value = json[key]
|
||||
const value = rawUserKeybindings[key]
|
||||
if (typeof value === 'string') {
|
||||
if (value.length === 0) {
|
||||
// Unset key
|
||||
userAccelerators.set(key, '')
|
||||
} else if (isAccelerator(value)) {
|
||||
} else if (isValidElectronAccelerator(value)) {
|
||||
userAccelerators.set(key, value)
|
||||
} else {
|
||||
console.error(`[WARNING] "${value}" is not a valid accelerator.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,7 +152,7 @@ class Keybindings {
|
||||
// Check for duplicate user shortcuts
|
||||
for (const [keyA, valueA] of userAccelerators) {
|
||||
for (const [keyB, valueB] of userAccelerators) {
|
||||
if (valueA !== '' && keyA !== keyB && this._isEqualAccelerator(valueA, valueB)) {
|
||||
if (valueA !== '' && keyA !== keyB && isEqualAccelerator(valueA, valueB)) {
|
||||
const err = `Invalid keybindings.json configuration: Duplicate value for "${keyA}" and "${keyB}"!`
|
||||
console.log(err)
|
||||
log.error(err)
|
||||
@ -201,10 +171,18 @@ class Keybindings {
|
||||
// Check for duplicate shortcuts
|
||||
for (const [userKey, userValue] of userAccelerators) {
|
||||
for (const [key, value] of accelerators) {
|
||||
if (this._isEqualAccelerator(value, userValue)) {
|
||||
// This is a workaround to unset key bindings that the user used in `keybindings.json` before
|
||||
// proper settings. Keep this for now, but add the ID to the users key binding that we show the
|
||||
// right bindings in settings.
|
||||
if (isEqualAccelerator(value, userValue)) {
|
||||
// Unset default key
|
||||
accelerators.set(key, '')
|
||||
|
||||
// This entry is actually unset because the user used the accelerator.
|
||||
if (userAccelerators.get(key) == null) {
|
||||
userAccelerators.set(key, '')
|
||||
}
|
||||
|
||||
// A accelerator should only exist once in the default map.
|
||||
break
|
||||
}
|
||||
@ -214,27 +192,21 @@ class Keybindings {
|
||||
|
||||
// Update key bindings
|
||||
this.keys = accelerators
|
||||
|
||||
// Save user keybindings for settings
|
||||
this.userKeybindings = userAccelerators
|
||||
}
|
||||
|
||||
_isEqualAccelerator (a, b) {
|
||||
a = a.toLowerCase().replace('cmdorctrl', 'ctrl').replace('command', 'ctrl')
|
||||
b = b.toLowerCase().replace('cmdorctrl', 'ctrl').replace('command', 'ctrl')
|
||||
const i1 = a.indexOf('+')
|
||||
const i2 = b.indexOf('+')
|
||||
if (i1 === -1 && i2 === -1) {
|
||||
return a === b
|
||||
} else if (i1 === -1 || i2 === -1) {
|
||||
return false
|
||||
_loadUserKeybindingsFromDisk () {
|
||||
try {
|
||||
const obj = JSON.parse(fs.readFileSync(this.configPath, 'utf8'))
|
||||
if (typeof obj !== 'object') {
|
||||
return null
|
||||
}
|
||||
return obj
|
||||
} catch (_) {
|
||||
return null
|
||||
}
|
||||
|
||||
const keysA = a.split('+')
|
||||
const keysB = b.split('+')
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
const intersection = new Set([...keysA, ...keysB])
|
||||
return intersection.size === keysB.length
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,24 @@ export const edit = (win, type) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const nativeCut = win => {
|
||||
if (win) {
|
||||
win.webContents.cut()
|
||||
}
|
||||
}
|
||||
|
||||
export const nativeCopy = win => {
|
||||
if (win) {
|
||||
win.webContents.copy()
|
||||
}
|
||||
}
|
||||
|
||||
export const nativePaste = win => {
|
||||
if (win) {
|
||||
win.webContents.paste()
|
||||
}
|
||||
}
|
||||
|
||||
export const screenshot = win => {
|
||||
ipcMain.emit('screen-capture', win)
|
||||
}
|
||||
|
@ -550,6 +550,12 @@ export const closeTab = win => {
|
||||
}
|
||||
}
|
||||
|
||||
export const closeWindow = win => {
|
||||
if (win) {
|
||||
win.close()
|
||||
}
|
||||
}
|
||||
|
||||
export const save = win => {
|
||||
if (win && win.webContents) {
|
||||
win.webContents.send('mt::editor-ask-file-save')
|
||||
|
@ -1,4 +1,15 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { ipcMain, Menu } from 'electron'
|
||||
import { isOsx } from '../../config'
|
||||
|
||||
export const minimizeWindow = win => {
|
||||
if (win) {
|
||||
if (isOsx) {
|
||||
Menu.sendActionToFirstResponder('performMiniaturize:')
|
||||
} else {
|
||||
win.minimize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const toggleAlwaysOnTop = win => {
|
||||
if (win) {
|
||||
|
@ -21,15 +21,21 @@ export default function (keybindings) {
|
||||
}, {
|
||||
label: 'Cut',
|
||||
accelerator: keybindings.getAccelerator('edit.cut'),
|
||||
role: 'cut'
|
||||
click (menuItem, browserWindow) {
|
||||
actions.nativeCut(browserWindow)
|
||||
}
|
||||
}, {
|
||||
label: 'Copy',
|
||||
accelerator: keybindings.getAccelerator('edit.copy'),
|
||||
role: 'copy'
|
||||
click (menuItem, browserWindow) {
|
||||
actions.nativeCopy(browserWindow)
|
||||
}
|
||||
}, {
|
||||
label: 'Paste',
|
||||
accelerator: keybindings.getAccelerator('edit.paste'),
|
||||
role: 'paste'
|
||||
click (menuItem, browserWindow) {
|
||||
actions.nativePaste(browserWindow)
|
||||
}
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
|
@ -162,7 +162,9 @@ export default function (keybindings, userPreference, recentlyUsedFiles) {
|
||||
}, {
|
||||
label: 'Close Window',
|
||||
accelerator: keybindings.getAccelerator('file.close-window'),
|
||||
role: 'close'
|
||||
click (menuItem, browserWindow) {
|
||||
actions.closeWindow(browserWindow)
|
||||
}
|
||||
}, {
|
||||
type: 'separator',
|
||||
visible: !isOsx
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { app } from 'electron'
|
||||
import { app, Menu } from 'electron'
|
||||
import { showAboutDialog } from '../actions/help'
|
||||
import * as actions from '../actions/marktext'
|
||||
|
||||
// macOS only menu.
|
||||
|
||||
export default function (keybindings) {
|
||||
return {
|
||||
label: 'MarkText',
|
||||
@ -32,14 +34,20 @@ export default function (keybindings) {
|
||||
}, {
|
||||
label: 'Hide MarkText',
|
||||
accelerator: keybindings.getAccelerator('mt.hide'),
|
||||
role: 'hide'
|
||||
click () {
|
||||
Menu.sendActionToFirstResponder('hide:')
|
||||
}
|
||||
}, {
|
||||
label: 'Hide Others',
|
||||
accelerator: keybindings.getAccelerator('mt.hide-others'),
|
||||
role: 'hideothers'
|
||||
click () {
|
||||
Menu.sendActionToFirstResponder('hideOtherApplications:')
|
||||
}
|
||||
}, {
|
||||
label: 'Show All',
|
||||
role: 'unhide'
|
||||
click () {
|
||||
Menu.sendActionToFirstResponder('unhideAllApplications:')
|
||||
}
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { toggleAlwaysOnTop } from '../actions/window'
|
||||
import { Menu } from 'electron'
|
||||
import { minimizeWindow, toggleAlwaysOnTop } from '../actions/window'
|
||||
import { zoomIn, zoomOut } from '../../windows/utils'
|
||||
import { isOsx } from '../../config'
|
||||
|
||||
@ -9,7 +10,9 @@ export default function (keybindings) {
|
||||
submenu: [{
|
||||
label: 'Minimize',
|
||||
accelerator: keybindings.getAccelerator('window.minimize'),
|
||||
role: 'minimize'
|
||||
click (menuItem, browserWindow) {
|
||||
minimizeWindow(browserWindow)
|
||||
}
|
||||
}, {
|
||||
id: 'alwaysOnTopMenuItem',
|
||||
label: 'Always on Top',
|
||||
@ -48,7 +51,9 @@ export default function (keybindings) {
|
||||
if (isOsx) {
|
||||
menu.submenu.push({
|
||||
label: 'Bring All to Front',
|
||||
role: 'front'
|
||||
click () {
|
||||
Menu.sendActionToFirstResponder('arrangeInFront:')
|
||||
}
|
||||
})
|
||||
}
|
||||
return menu
|
||||
|
@ -182,6 +182,9 @@ class EditorWindow extends BaseWindow {
|
||||
|
||||
mainWindowState.manage(win)
|
||||
|
||||
// Disable application menu shortcuts because we want to handle key bindings yourself.
|
||||
win.webContents.setIgnoreMenuShortcuts(true)
|
||||
|
||||
// Delay load files and directories after the current control flow.
|
||||
setTimeout(() => {
|
||||
if (rootDirectory) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import path from 'path'
|
||||
import { BrowserWindow, ipcMain } from 'electron'
|
||||
import { enable as remoteEnable } from '@electron/remote/main'
|
||||
import electronLocalshortcut from '@hfelix/electron-localshortcut'
|
||||
import { electronLocalshortcut } from '@hfelix/electron-localshortcut'
|
||||
import BaseWindow, { WindowLifecycle, WindowType } from './base'
|
||||
import { centerWindowOptions } from './utils'
|
||||
import { TITLE_BAR_HEIGHT, preferencesWinOptions, isLinux, isOsx } from '../config'
|
||||
|
@ -43,6 +43,8 @@ class Clipboard {
|
||||
eventCenter.attachDOMEvent(document.body, 'copy', docCopyCutHandler)
|
||||
}
|
||||
|
||||
// TODO: `document.execCommand` is deprecated!
|
||||
|
||||
copyAsMarkdown () {
|
||||
this._copyType = 'copyAsMarkdown'
|
||||
document.execCommand('copy')
|
||||
|
@ -1,7 +1,7 @@
|
||||
import loadRenderer from '../../renderers'
|
||||
import { CLASS_OR_ID, PREVIEW_DOMPURIFY_CONFIG } from '../../config'
|
||||
import { conflict, mixins, camelToSnake, sanitize } from '../../utils'
|
||||
import { patch, toVNode, toHTML, h, addNStoVNodeSvgChildren } from './snabbdom'
|
||||
import { patch, toVNode, toHTML, h } from './snabbdom'
|
||||
import { beginRules } from '../rules'
|
||||
import renderInlines from './renderInlines'
|
||||
import renderBlock from './renderBlock'
|
||||
@ -176,7 +176,6 @@ class StateRender {
|
||||
const children = blocks.map(block => {
|
||||
return this.renderBlock(null, block, activeBlocks, matches, true)
|
||||
})
|
||||
addNStoVNodeSvgChildren(children)
|
||||
const newVdom = h(selector, children)
|
||||
const rootDom = document.querySelector(selector) || this.container
|
||||
const oldVdom = toVNode(rootDom)
|
||||
|
@ -29,21 +29,3 @@ export const htmlToVNode = html => { // helper function for convert html to vnod
|
||||
|
||||
return toVNode(wrapper).children
|
||||
}
|
||||
|
||||
const addNS = ({ data, children, sel }) => {
|
||||
data.ns = 'http://www.w3.org/2000/svg'
|
||||
if (sel !== 'foreignObject' && children !== undefined) {
|
||||
for (const vNode of children) {
|
||||
if (vNode.data === undefined) continue
|
||||
addNS(vNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const addNStoVNodeSvgChildren = (children = []) => {
|
||||
for (const vNode of children) {
|
||||
if (vNode.data === undefined) continue
|
||||
if (vNode.sel.startsWith('svg')) addNS(vNode)
|
||||
addNStoVNodeSvgChildren(vNode.children)
|
||||
}
|
||||
}
|
||||
|
119
src/renderer/commands/descriptions.js
Normal file
119
src/renderer/commands/descriptions.js
Normal file
@ -0,0 +1,119 @@
|
||||
const commandDescriptions = Object.freeze({
|
||||
// ============================================
|
||||
// # Key binding descriptions
|
||||
// #
|
||||
|
||||
'mt.hide': 'MarkText: Hide MarkText',
|
||||
'mt.hide-others': 'MarkText: Hide Others',
|
||||
'file.new-file': 'File: New Window',
|
||||
'file.new-tab': 'File: New Tab',
|
||||
'file.open-file': 'File: Open file',
|
||||
'file.open-folder': 'File: Open Folder',
|
||||
'file.save': 'File: Save',
|
||||
'file.save-as': 'File: Save As...',
|
||||
'file.move-file': 'File: Move...',
|
||||
'file.rename-file': 'File: Rename...',
|
||||
'file.quick-open': 'File: Show quick open dialog',
|
||||
'file.print': 'File: Print current Tab',
|
||||
'file.preferences': 'MarkText: Preferences',
|
||||
'file.close-tab': 'File: Close current Tab',
|
||||
'file.close-window': 'File: Close Window',
|
||||
'file.quit': 'MarkText: Quit',
|
||||
'edit.undo': 'Edit: Undo',
|
||||
'edit.redo': 'Edit: Redo',
|
||||
'edit.cut': 'Edit: Cut',
|
||||
'edit.copy': 'Edit: Copy',
|
||||
'edit.paste': 'Edit: Paste',
|
||||
'edit.copy-as-markdown': 'Edit: Copy as Markdown',
|
||||
'edit.copy-as-html': 'Edit: Copy as HTML',
|
||||
'edit.paste-as-plaintext': 'Edit: Paste as Plain Text',
|
||||
'edit.select-all': 'Edit: Select All',
|
||||
'edit.duplicate': 'Edit: Duplicate',
|
||||
'edit.create-paragraph': 'Edit: Create Paragraph',
|
||||
'edit.delete-paragraph': 'Edit: Delete Paragraph',
|
||||
'edit.find': 'Edit: Find',
|
||||
'edit.find-next': 'Edit: Find Next',
|
||||
'edit.find-previous': 'Edit: Find Previous',
|
||||
'edit.replace': 'Edit: Replace',
|
||||
'edit.find-in-folder': 'Edit: Find in Folder',
|
||||
'edit.screenshot': 'Edit: Make Screenshot',
|
||||
'paragraph.heading-1': 'Paragraph: Transform into Heading 1',
|
||||
'paragraph.heading-2': 'Paragraph: Transform into Heading 2',
|
||||
'paragraph.heading-3': 'Paragraph: Transform into Heading 3',
|
||||
'paragraph.heading-4': 'Paragraph: Transform into Heading 4',
|
||||
'paragraph.heading-5': 'Paragraph: Transform into Heading 5',
|
||||
'paragraph.heading-6': 'Paragraph: Transform into Heading 6',
|
||||
'paragraph.upgrade-heading': 'Paragraph: Upgrade Heading',
|
||||
'paragraph.degrade-heading': 'Paragraph: Degrade Heading',
|
||||
'paragraph.table': 'Paragraph: Create Table',
|
||||
'paragraph.code-fence': 'Paragraph: Transform into Code Fence',
|
||||
'paragraph.quote-block': 'Paragraph: Transform into Quote Block',
|
||||
'paragraph.math-formula': 'Paragraph: Transform into Math Formula',
|
||||
'paragraph.html-block': 'Paragraph: Transform into HTML Block',
|
||||
'paragraph.order-list': 'Paragraph: Transform into Order List',
|
||||
'paragraph.bullet-list': 'Paragraph: Transform into Bullet List',
|
||||
'paragraph.task-list': 'Paragraph: Transform into Task List',
|
||||
'paragraph.loose-list-item': 'Paragraph: Convert to Loose List Item',
|
||||
'paragraph.paragraph': 'Paragraph: Create new Paragraph',
|
||||
'paragraph.horizontal-line': 'Paragraph: Insert Horizontal Line',
|
||||
'paragraph.front-matter': 'Paragraph: Insert Front Matter',
|
||||
'format.strong': 'Format: Strong',
|
||||
'format.emphasis': 'Format: Emphasis',
|
||||
'format.underline': 'Format: Underline',
|
||||
'format.superscript': 'Format: Superscript',
|
||||
'format.subscript': 'Format: Subscript',
|
||||
'format.highlight': 'Format: Highlight',
|
||||
'format.inline-code': 'Format: Inline Code',
|
||||
'format.inline-math': 'Format: Inline Math',
|
||||
'format.strike': 'Format: Strike',
|
||||
'format.hyperlink': 'Format: Hyperlink',
|
||||
'format.image': 'Format: Insert Image',
|
||||
'format.clear-format': 'Format: Clear Format',
|
||||
'window.minimize': 'Window: Minimize',
|
||||
'window.toggle-always-on-top': 'Window: Always on Top',
|
||||
'window.zoom-in': 'Window: Zoom In',
|
||||
'window.zoom-out': 'Window: Zoom Out',
|
||||
'window.toggle-full-screen': 'Window: Toggle Full Screen',
|
||||
'view.command-palette': 'View: Show Command Palette',
|
||||
'view.source-code-mode': 'View: Toggle Source Code Mode',
|
||||
'view.typewriter-mode': 'View: Toggle Typewriter Mode',
|
||||
'view.focus-mode': 'View: Focus Mode',
|
||||
'view.toggle-sidebar': 'View: Toggle Sidebar',
|
||||
'view.toggle-toc': 'View: Toggle Table of Content',
|
||||
'view.toggle-tabbar': 'View: Toggle Tabs',
|
||||
'view.toggle-dev-tools': 'View: Show Developer Tools (Debug)',
|
||||
'view.dev-reload': 'View: Reload Window (Debug)',
|
||||
'tabs.cycle-forward': 'Misc: Cycle Tabs Forward',
|
||||
'tabs.cycle-backward': 'Misc: Cycle Tabs Backward',
|
||||
'tabs.switch-to-left': 'Misc: Switch tab to the left',
|
||||
'tabs.switch-to-right': 'Misc: Switch tab to the right',
|
||||
'tabs.switch-to-first': 'Misc: Switch tab to the 1st',
|
||||
'tabs.switch-to-second': 'Misc: Switch tab to the 2st',
|
||||
'tabs.switch-to-third': 'Misc: Switch tab to the 3st',
|
||||
'tabs.switch-to-fourth': 'Misc: Switch tab to the 4st',
|
||||
'tabs.switch-to-fifth': 'Misc: Switch tab to the 5st',
|
||||
'tabs.switch-to-sixth': 'Misc: Switch tab to the 6st',
|
||||
'tabs.switch-to-seventh': 'Misc: Switch tab to the 7st',
|
||||
'tabs.switch-to-eighth': 'Misc: Switch tab to the 8st',
|
||||
'tabs.switch-to-ninth': 'Misc: Switch tab to the 9st',
|
||||
'tabs.switch-to-tenth': 'Misc: Switch tab to the 10st',
|
||||
|
||||
// ============================================
|
||||
// # Additional command descriptions
|
||||
// #
|
||||
|
||||
'file.toggle-auto-save': 'File: Toggle Auto Save',
|
||||
'file.import-file': 'File: Import...',
|
||||
'file.export-file': 'File: Export...',
|
||||
'file.zoom': 'Window: Zoom...',
|
||||
'file.check-update': 'MarkText: Check for Updates...',
|
||||
'paragraph.reset-paragraph': 'Paragraph: Transform into Paragraph',
|
||||
'window.change-theme': 'Theme: Change Theme...',
|
||||
'view.text-direction': 'View: Set Text Direction',
|
||||
'docs.user-guide': 'MarkText: End User Guide',
|
||||
'docs.markdown-syntax': 'MarkText: Markdown Syntax Guide'
|
||||
})
|
||||
|
||||
export default id => {
|
||||
return commandDescriptions[id]
|
||||
}
|
@ -4,6 +4,7 @@ import { getCurrentWindow } from '@electron/remote'
|
||||
import bus from '../bus'
|
||||
import { delay, isOsx } from '@/util'
|
||||
import { isUpdatable } from './utils'
|
||||
import getCommandDescriptionById from './descriptions'
|
||||
|
||||
export { default as FileEncodingCommand } from './fileEncoding'
|
||||
export { default as LineEndingCommand } from './lineEnding'
|
||||
@ -38,56 +39,47 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'file.new-tab',
|
||||
description: 'File: New Tab',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::new-untitled-tab', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.new-file',
|
||||
description: 'File: New Window',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-new-editor-window')
|
||||
}
|
||||
}, {
|
||||
id: 'file.open-file',
|
||||
description: 'File: Open file',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-open-file')
|
||||
}
|
||||
}, {
|
||||
id: 'file.open-folder',
|
||||
description: 'File: Open Folder',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-open-folder')
|
||||
}
|
||||
}, {
|
||||
id: 'file.save',
|
||||
description: 'File: Save',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::editor-ask-file-save', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.save-as',
|
||||
description: 'File: Save As...',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::editor-ask-file-save-as', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.print',
|
||||
description: 'File: Print current Tab',
|
||||
execute: async () => {
|
||||
await delay(50)
|
||||
bus.$emit('showExportDialog', 'print')
|
||||
}
|
||||
}, {
|
||||
id: 'file.close-tab',
|
||||
description: 'File: Close current Tab',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::editor-close-tab', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.close-window',
|
||||
description: 'File: Close Window',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-close-window')
|
||||
}
|
||||
@ -95,32 +87,27 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'file.toggle-auto-save',
|
||||
description: 'File: Toggle Auto Save',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-toggle-autosave')
|
||||
}
|
||||
}, {
|
||||
id: 'file.move-file',
|
||||
description: 'File: Move...',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::editor-move-file', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.rename-file',
|
||||
description: 'File: Rename...',
|
||||
execute: async () => {
|
||||
await delay(50)
|
||||
ipcRenderer.emit('mt::editor-rename-file', null)
|
||||
}
|
||||
}, {
|
||||
id: 'file.import-file',
|
||||
description: 'File: Import...',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::cmd-import-file')
|
||||
}
|
||||
}, {
|
||||
id: 'file.export-file',
|
||||
description: 'File: Export...',
|
||||
subcommands: [{
|
||||
id: 'file.export-file-html',
|
||||
description: 'HTML',
|
||||
@ -143,7 +130,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'edit.undo',
|
||||
description: 'Edit: Undo',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('undo', 'undo')
|
||||
@ -151,7 +137,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'edit.redo',
|
||||
description: 'Edit: Redo',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('redo', 'redo')
|
||||
@ -159,7 +144,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'edit.duplicate',
|
||||
description: 'Edit: Duplicate',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('duplicate', 'duplicate')
|
||||
@ -167,7 +151,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'edit.create-paragraph',
|
||||
description: 'Edit: Create Paragraph',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('createParagraph', 'createParagraph')
|
||||
@ -175,7 +158,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'edit.delete-paragraph',
|
||||
description: 'Edit: Delete Paragraph',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('deleteParagraph', 'deleteParagraph')
|
||||
@ -183,7 +165,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'edit.find',
|
||||
description: 'Edit: Find',
|
||||
execute: async () => {
|
||||
await delay(150)
|
||||
bus.$emit('find', 'find')
|
||||
@ -207,14 +188,12 @@ const commands = [
|
||||
// },
|
||||
{
|
||||
id: 'edit.replace',
|
||||
description: 'Edit: Replace',
|
||||
execute: async () => {
|
||||
await delay(150)
|
||||
bus.$emit('replace', 'replace')
|
||||
}
|
||||
}, {
|
||||
id: 'edit.find-in-folder',
|
||||
description: 'Edit: Find in Folder',
|
||||
execute: async () => {
|
||||
await delay(150)
|
||||
ipcRenderer.emit('mt::editor-edit-action', null, 'findInFolder')
|
||||
@ -226,7 +205,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'paragraph.heading-1',
|
||||
description: 'Paragraph: Transform into Heading 1',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 1')
|
||||
@ -234,7 +212,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.heading-2',
|
||||
description: 'Paragraph: Transform into Heading 2',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 2')
|
||||
@ -242,7 +219,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.heading-3',
|
||||
description: 'Paragraph: Transform into Heading 3',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 3')
|
||||
@ -250,7 +226,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.heading-4',
|
||||
description: 'Paragraph: Transform into Heading 4',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 4')
|
||||
@ -258,7 +233,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.heading-5',
|
||||
description: 'Paragraph: Transform into Heading 5',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 5')
|
||||
@ -266,7 +240,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.heading-6',
|
||||
description: 'Paragraph: Transform into Heading 6',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'heading 6')
|
||||
@ -274,7 +247,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.upgrade-heading',
|
||||
description: 'Paragraph: Upgrade Heading',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'upgrade heading')
|
||||
@ -282,7 +254,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.degrade-heading',
|
||||
description: 'Paragraph: Degrade Heading',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'degrade heading')
|
||||
@ -290,7 +261,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.table',
|
||||
description: 'Paragraph: Create Table',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'table')
|
||||
@ -298,7 +268,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.code-fence',
|
||||
description: 'Paragraph: Transform into Code Fence',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'pre')
|
||||
@ -306,7 +275,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.quote-block',
|
||||
description: 'Paragraph: Transform into Quote Block',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'blockquote')
|
||||
@ -314,7 +282,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.math-formula',
|
||||
description: 'Paragraph: Transform into Math Formula',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'mathblock')
|
||||
@ -322,7 +289,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.html-block',
|
||||
description: 'Paragraph: Transform into HTML Block',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'html')
|
||||
@ -330,7 +296,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.order-list',
|
||||
description: 'Paragraph: Transform into Order List',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'ol-bullet')
|
||||
@ -338,7 +303,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.bullet-list',
|
||||
description: 'Paragraph: Transform into Bullet List',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'ul-bullet')
|
||||
@ -346,7 +310,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.task-list',
|
||||
description: 'Paragraph: Transform into Task List',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'ul-task')
|
||||
@ -354,7 +317,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.loose-list-item',
|
||||
description: 'Paragraph: Convert to Loose List Item',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'loose-list-item')
|
||||
@ -362,7 +324,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.paragraph',
|
||||
description: 'Paragraph: Create new Paragraph',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'paragraph')
|
||||
@ -370,7 +331,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.reset-paragraph',
|
||||
description: 'Paragraph: Transform into Paragraph',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'reset-to-paragraph')
|
||||
@ -378,7 +338,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.horizontal-line',
|
||||
description: 'Paragraph: Insert Horizontal Line',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'hr')
|
||||
@ -386,7 +345,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'paragraph.front-matter',
|
||||
description: 'Paragraph: Insert Front Matter',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('paragraph', 'front-matter')
|
||||
@ -401,7 +359,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'format.strong',
|
||||
description: 'Format: Strong',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'strong')
|
||||
@ -409,7 +366,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.emphasis',
|
||||
description: 'Format: Emphasis',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'em')
|
||||
@ -417,7 +373,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.underline',
|
||||
description: 'Format: Underline',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'u')
|
||||
@ -425,7 +380,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.highlight',
|
||||
description: 'Format: Highlight',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'mark')
|
||||
@ -433,7 +387,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.superscript',
|
||||
description: 'Format: Superscript',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'sup')
|
||||
@ -441,7 +394,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.subscript',
|
||||
description: 'Format: Subscript',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'sub')
|
||||
@ -449,7 +401,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.inline-code',
|
||||
description: 'Format: Inline Code',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'inline_code')
|
||||
@ -457,7 +408,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.inline-math',
|
||||
description: 'Format: Inline Math',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'inline_math')
|
||||
@ -465,7 +415,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.strike',
|
||||
description: 'Format: Strike',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'del')
|
||||
@ -473,7 +422,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.hyperlink',
|
||||
description: 'Format: Hyperlink',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'link')
|
||||
@ -481,7 +429,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.image',
|
||||
description: 'Format: Insert Image',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'image')
|
||||
@ -489,7 +436,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'format.clear-format',
|
||||
description: 'Format: Clear Format',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('format', 'clear')
|
||||
@ -502,19 +448,16 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'window.minimize',
|
||||
description: 'Window: Minimize',
|
||||
execute: async () => {
|
||||
getCurrentWindow().minimize()
|
||||
}
|
||||
}, {
|
||||
id: 'window.toggle-always-on-top',
|
||||
description: 'Window: Always on Top',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::window-toggle-always-on-top')
|
||||
}
|
||||
}, {
|
||||
id: 'window.toggle-full-screen',
|
||||
description: 'Window: Toggle Full Screen',
|
||||
execute: async () => {
|
||||
const win = getCurrentWindow()
|
||||
win.setFullScreen(!win.isFullScreen())
|
||||
@ -523,7 +466,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'file.zoom',
|
||||
description: 'Window: Zoom...',
|
||||
shortcut: [(isOsx ? 'Cmd' : 'Ctrl'), 'Scroll'],
|
||||
subcommands: [{
|
||||
id: 'file.zoom-0',
|
||||
@ -584,7 +526,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'window.change-theme',
|
||||
description: 'Theme: Change Theme',
|
||||
subcommands: [{
|
||||
id: 'window.change-theme-light',
|
||||
description: 'Cadmium Light',
|
||||
@ -620,13 +561,11 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'view.source-code-mode',
|
||||
description: 'View: Toggle Source Code Mode',
|
||||
execute: async () => {
|
||||
bus.$emit('view:toggle-view-entry', 'sourceCode')
|
||||
}
|
||||
}, {
|
||||
id: 'view.typewriter-mode',
|
||||
description: 'View: Toggle Typewriter Mode',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('view:toggle-view-entry', 'typewriter')
|
||||
@ -634,7 +573,6 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'view.focus-mode',
|
||||
description: 'View: Focus Mode',
|
||||
execute: async () => {
|
||||
focusEditorAndExecute(
|
||||
() => bus.$emit('view:toggle-view-entry', 'focus')
|
||||
@ -642,13 +580,11 @@ const commands = [
|
||||
}
|
||||
}, {
|
||||
id: 'view.toggle-sidebar',
|
||||
description: 'View: Toggle Sidebar',
|
||||
execute: async () => {
|
||||
bus.$emit('view:toggle-view-layout-entry', 'showSideBar')
|
||||
}
|
||||
}, {
|
||||
id: 'view.toggle-tabbar',
|
||||
description: 'View: Toggle Tabs',
|
||||
execute: async () => {
|
||||
bus.$emit('view:toggle-view-layout-entry', 'showTabBar')
|
||||
}
|
||||
@ -656,7 +592,6 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'view.text-direction',
|
||||
description: 'View: Set Text Direction',
|
||||
subcommands: [{
|
||||
id: 'view.text-direction-ltr',
|
||||
description: 'Left to Right',
|
||||
@ -676,25 +611,21 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'file.preferences',
|
||||
description: 'MarkText: Preferences',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::open-setting-window')
|
||||
}
|
||||
}, {
|
||||
id: 'file.quit',
|
||||
description: 'MarkText: Quit',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::app-try-quit')
|
||||
}
|
||||
}, {
|
||||
id: 'docs.user-guide',
|
||||
description: 'MarkText: End User Guide',
|
||||
execute: async () => {
|
||||
shell.openExternal('https://github.com/marktext/marktext/blob/master/docs/README.md')
|
||||
}
|
||||
}, {
|
||||
id: 'docs.markdown-syntax',
|
||||
description: 'MarkText: Markdown Syntax Guide',
|
||||
execute: async () => {
|
||||
shell.openExternal('https://github.com/marktext/marktext/blob/master/docs/MARKDOWN_SYNTAX.md')
|
||||
}
|
||||
@ -705,13 +636,11 @@ const commands = [
|
||||
|
||||
{
|
||||
id: 'tabs.cycle-forward',
|
||||
description: 'Misc: Cycle Tabs Forward',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::tabs-cycle-right', null)
|
||||
}
|
||||
}, {
|
||||
id: 'tabs.cycle-backward',
|
||||
description: 'Misc: Cycle Tabs Backward',
|
||||
execute: async () => {
|
||||
ipcRenderer.emit('mt::tabs-cycle-left', null)
|
||||
}
|
||||
@ -721,7 +650,6 @@ const commands = [
|
||||
if (isUpdatable()) {
|
||||
commands.push({
|
||||
id: 'file.check-update',
|
||||
description: 'MarkText: Check for Updates',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::check-for-update')
|
||||
}
|
||||
@ -731,11 +659,18 @@ if (isUpdatable()) {
|
||||
if (isOsx) {
|
||||
commands.push({
|
||||
id: 'edit.screenshot',
|
||||
description: 'Edit: Make Screenshot',
|
||||
execute: async () => {
|
||||
ipcRenderer.send('mt::make-screenshot')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Complete all command descriptions.
|
||||
for (const item of commands) {
|
||||
const { id, description } = item
|
||||
if (id && !description) {
|
||||
item.description = getCommandDescriptionById(id)
|
||||
}
|
||||
}
|
||||
|
||||
export default commands
|
||||
|
@ -1005,7 +1005,11 @@ export default {
|
||||
},
|
||||
|
||||
handleSelectAll () {
|
||||
if (this.editor && !this.sourceCode && (this.editor.hasFocus() || this.editor.contentState.selectedTableCells)) {
|
||||
if (this.sourceCode) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.editor && (this.editor.hasFocus() || this.editor.contentState.selectedTableCells)) {
|
||||
this.editor.selectAll()
|
||||
} else {
|
||||
const activeElement = document.activeElement
|
||||
|
@ -247,8 +247,19 @@ export default {
|
||||
},
|
||||
|
||||
handleSelectAll () {
|
||||
if (this.sourceCode && this.editor) {
|
||||
if (!this.sourceCode) {
|
||||
return
|
||||
}
|
||||
|
||||
const { editor } = this
|
||||
if (editor && editor.hasFocus()) {
|
||||
this.editor.execCommand('selectAll')
|
||||
} else {
|
||||
const activeElement = document.activeElement
|
||||
const nodeName = activeElement.nodeName
|
||||
if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') {
|
||||
activeElement.select()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -61,7 +61,7 @@ export default {
|
||||
|
||||
<style>
|
||||
.pref-container {
|
||||
--prefSideBarWidth: 320px;
|
||||
--prefSideBarWidth: 280px;
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
@ -22,9 +22,8 @@
|
||||
|
||||
<script>
|
||||
import { shell } from 'electron'
|
||||
import fontManager from 'fontmanager-redux'
|
||||
|
||||
// Example font objects:
|
||||
// Example of fontmanager-redux objects:
|
||||
// {
|
||||
// path: '/Library/Fonts/Arial.ttf',
|
||||
// postscriptName: 'ArialMT',
|
||||
@ -101,6 +100,8 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// Delay load native library because it's not needed for the editor and causes a delay.
|
||||
const fontManager = require('fontmanager-redux')
|
||||
const { onlyMonospace } = this
|
||||
const buf = fontManager.getAvailableFontsSync()
|
||||
.filter(f => f.family && (!onlyMonospace || (onlyMonospace && f.monospace)))
|
||||
|
@ -0,0 +1,144 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { isEqualAccelerator } from 'common/keybinding'
|
||||
import getCommandDescriptionById from '@/commands/descriptions'
|
||||
import { isOsx } from '@/util'
|
||||
|
||||
const SHORTCUT_TYPE_DEFAULT = 0
|
||||
const SHORTCUT_TYPE_USER = 1
|
||||
|
||||
const getShortcutDescriptionById = id => {
|
||||
const description = getCommandDescriptionById(id)
|
||||
if (!description) {
|
||||
return id
|
||||
}
|
||||
return description
|
||||
}
|
||||
|
||||
export default class KeybindingConfigurator {
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @param {Map<String, String>} defaultKeybindings
|
||||
* @param {Map<String, String>} userKeybindings
|
||||
*/
|
||||
constructor (defaultKeybindings, userKeybindings) {
|
||||
this.defaultKeybindings = defaultKeybindings
|
||||
this.keybindingList = this._buildUiKeybindingList(defaultKeybindings, userKeybindings)
|
||||
this.isDirty = false
|
||||
}
|
||||
|
||||
_buildUiKeybindingList (defaultKeybindings, userKeybindings) {
|
||||
const uiKeybindings = []
|
||||
for (const [id] of defaultKeybindings) {
|
||||
if (!isOsx && id.startsWith('mt.')) {
|
||||
// Skip MarkText menu that is only available on macOS.
|
||||
continue
|
||||
}
|
||||
uiKeybindings.push(this._toUiKeybinding(id, defaultKeybindings, userKeybindings))
|
||||
}
|
||||
uiKeybindings.sort((a, b) => a.description.localeCompare(b.description))
|
||||
return uiKeybindings
|
||||
}
|
||||
|
||||
_toUiKeybinding (id, defaultKeybindings, userKeybindings) {
|
||||
const description = getShortcutDescriptionById(id)
|
||||
const userAccelerator = userKeybindings.get(id)
|
||||
let type = SHORTCUT_TYPE_DEFAULT
|
||||
|
||||
// Overwrite accelerator if key is present (empty string unset old binding).
|
||||
let accelerator
|
||||
if (userAccelerator != null) {
|
||||
type = SHORTCUT_TYPE_USER
|
||||
accelerator = userAccelerator
|
||||
} else {
|
||||
accelerator = defaultKeybindings.get(id)
|
||||
}
|
||||
return { id, description, accelerator, type }
|
||||
}
|
||||
|
||||
getKeybindings () {
|
||||
return this.keybindingList
|
||||
}
|
||||
|
||||
async save () {
|
||||
if (!this.isDirty) {
|
||||
return true
|
||||
}
|
||||
|
||||
const userKeybindings = this._getUserKeybindingMap()
|
||||
const result = await ipcRenderer.invoke('mt::keybinding-save-user-keybindings', userKeybindings)
|
||||
if (result) {
|
||||
this.isDirty = false
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_getUserKeybindingMap () {
|
||||
const userKeybindings = new Map()
|
||||
for (const entry of this.keybindingList) {
|
||||
const { id, accelerator, type } = entry
|
||||
if (type !== SHORTCUT_TYPE_DEFAULT) {
|
||||
userKeybindings.set(id, accelerator)
|
||||
}
|
||||
}
|
||||
return userKeybindings
|
||||
}
|
||||
|
||||
change (id, accelerator) {
|
||||
const entry = this.keybindingList.find(entry => entry.id === id)
|
||||
if (!entry) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (accelerator && this._isDuplicate(accelerator)) {
|
||||
return false
|
||||
}
|
||||
|
||||
entry.accelerator = accelerator
|
||||
entry.type = this._isDefaultBinding(id, accelerator)
|
||||
? SHORTCUT_TYPE_DEFAULT
|
||||
: SHORTCUT_TYPE_USER
|
||||
this.isDirty = true
|
||||
return true
|
||||
}
|
||||
|
||||
unbind (id) {
|
||||
return this.change(id, '')
|
||||
}
|
||||
|
||||
resetToDefault (id) {
|
||||
const accelerator = this.defaultKeybindings.get(id)
|
||||
if (accelerator == null) { // allow empty string
|
||||
return false
|
||||
}
|
||||
return this.change(id, accelerator)
|
||||
}
|
||||
|
||||
async resetAll () {
|
||||
const { defaultKeybindings, keybindingList } = this
|
||||
for (const entry of keybindingList) {
|
||||
const defaultAccelerator = defaultKeybindings.get(entry.id)
|
||||
if (defaultAccelerator) {
|
||||
entry.accelerator = defaultAccelerator
|
||||
} else {
|
||||
entry.accelerator = ''
|
||||
}
|
||||
entry.type = SHORTCUT_TYPE_DEFAULT
|
||||
}
|
||||
this.isDirty = true
|
||||
return this.save()
|
||||
}
|
||||
|
||||
getDefaultAccelerator (id) {
|
||||
return this.defaultKeybindings.get(id)
|
||||
}
|
||||
|
||||
_isDuplicate (accelerator) {
|
||||
return accelerator !== '' && this.keybindingList.findIndex(entry => isEqualAccelerator(entry.accelerator, accelerator)) !== -1
|
||||
}
|
||||
|
||||
_isDefaultBinding (id, accelerator) {
|
||||
return this.defaultKeybindings.get(id) === accelerator
|
||||
}
|
||||
}
|
@ -1,38 +1,168 @@
|
||||
<template>
|
||||
<div class="pref-keybindings">
|
||||
<h4>Key Bindings</h4>
|
||||
<div class="keybinding-info">
|
||||
<span>
|
||||
MarkText shortcuts can be customized by editing a configuration file named <code>keybindings.json</code>.
|
||||
More information how to use custom key bindings can be found <span class="link" @click="openKeybindingsDocumentation">online</span>.
|
||||
All changes require a restart.
|
||||
</span>
|
||||
|
||||
<section class="keybindings">
|
||||
<div class="text">
|
||||
Customize MarkText shortcuts and click on the save button below to apply all changes (requires a restart).
|
||||
All available and default key binding can be found <a class="link" @click="openKeybindingWiki">online</a>.
|
||||
</div>
|
||||
<el-table
|
||||
:data="keybindingList"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="description" label="Description">
|
||||
</el-table-column>
|
||||
<el-table-column prop="accelerator" label="Key Combination" width="220">
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="Options" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="handleEditClick(scope.$index, scope.row)" type="text" size="small" title="Edit">
|
||||
<i class="el-icon-edit"></i>
|
||||
</el-button>
|
||||
<el-button @click="handleResetClick(scope.$index, scope.row)" type="text" size="small" title="Reset">
|
||||
<i class="el-icon-refresh-right"></i>
|
||||
</el-button>
|
||||
<el-button @click="handleUnbindClick(scope.$index, scope.row)" type="text" size="small" title="Unbind">
|
||||
<i class="el-icon-delete"></i>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section>
|
||||
<section class="footer">
|
||||
<separator></separator>
|
||||
<el-button size="medium" @click="openKeybindingsFile">Open keybindings.json</el-button>
|
||||
</div>
|
||||
<el-button size="medium" @click="saveKeybindings">Save</el-button>
|
||||
<el-button size="medium" @click="restoreDefaults">Restore default key bindings</el-button>
|
||||
</section>
|
||||
<section v-if="showDebugTools" class="keyboard-debug">
|
||||
<separator></separator>
|
||||
<div><strong>Debug options:</strong></div>
|
||||
<el-button size="medium" @click="dumpKeyboardInformation">Dump keyboard information</el-button>
|
||||
</section>
|
||||
<key-input-dialog
|
||||
:showWithId="selectedShortcutId"
|
||||
:onCommit="onKeybinding"
|
||||
></key-input-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ipcRenderer, shell } from 'electron'
|
||||
import log from 'electron-log'
|
||||
import { setKeyboardLayout } from '@hfelix/electron-localshortcut'
|
||||
import Compound from '../common/compound'
|
||||
import Separator from '../common/separator'
|
||||
import KeyInputDialog from './key-input-dialog.vue'
|
||||
import KeybindingConfigurator from './KeybindingConfigurator'
|
||||
import notice from '@/services/notification'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Compound,
|
||||
Separator
|
||||
Separator,
|
||||
KeyInputDialog
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
showDebugTools: false,
|
||||
keybindingConfigurator: null,
|
||||
selectedShortcutId: null,
|
||||
keybindingList: []
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
ipcRenderer.invoke('mt::keybinding-get-keyboard-info')
|
||||
.then(({ layout, keymap }) => {
|
||||
// Update the key mapper to prevent problems on non-US keyboards.
|
||||
setKeyboardLayout(layout, keymap)
|
||||
})
|
||||
.catch(error => log.error('Error while loading keyboard information for settings:', error))
|
||||
|
||||
ipcRenderer.invoke('mt::keybinding-get-pref-keybindings')
|
||||
.then(({ defaultKeybindings, userKeybindings }) => {
|
||||
this.keybindingConfigurator = new KeybindingConfigurator(defaultKeybindings, userKeybindings)
|
||||
this.keybindingList = this.keybindingConfigurator.getKeybindings()
|
||||
})
|
||||
.catch(error => log.error('Error while loading keyboard information for settings:', error))
|
||||
|
||||
// Show keyboard debugging tools which has been moved from CLI because we
|
||||
// need an active window on Windows.
|
||||
this.showDebugTools = global.marktext.env.debug
|
||||
},
|
||||
|
||||
unmounted () {
|
||||
this.keybindingList = []
|
||||
this.keybindingConfigurator = null
|
||||
},
|
||||
|
||||
methods: {
|
||||
openKeybindingsDocumentation () {
|
||||
openKeybindingWiki () {
|
||||
shell.openExternal('https://github.com/marktext/marktext/blob/master/docs/KEYBINDINGS.md')
|
||||
},
|
||||
openKeybindingsFile () {
|
||||
ipcRenderer.send('mt::open-keybindings-config')
|
||||
saveKeybindings () {
|
||||
if (this.keybindingConfigurator && this.keybindingList.length > 0) {
|
||||
this.keybindingConfigurator.save()
|
||||
.then(success => {
|
||||
if (!success) {
|
||||
notice.notify({
|
||||
title: 'Failed to save',
|
||||
type: 'error',
|
||||
message: 'An unexpected error occurred while saving.'
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(error => log.error(error))
|
||||
}
|
||||
},
|
||||
restoreDefaults () {
|
||||
this.keybindingConfigurator.resetAll()
|
||||
.then(success => {
|
||||
if (!success) {
|
||||
notice.notify({
|
||||
title: 'Failed to save',
|
||||
type: 'error',
|
||||
message: 'An unexpected error occurred while saving.'
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(error => log.error(error))
|
||||
},
|
||||
handleEditClick (index, entry) {
|
||||
if (index >= 0 && entry) {
|
||||
this.selectedShortcutId = entry.id
|
||||
}
|
||||
},
|
||||
handleResetClick (index, entry) {
|
||||
const { keybindingConfigurator } = this
|
||||
const { id } = entry
|
||||
const success = keybindingConfigurator.resetToDefault(id)
|
||||
if (!success) {
|
||||
this.handleDuplicateShortcut(id, keybindingConfigurator.getDefaultAccelerator(id))
|
||||
}
|
||||
},
|
||||
handleUnbindClick (index, entry) {
|
||||
this.keybindingConfigurator.unbind(entry.id)
|
||||
},
|
||||
onKeybinding (value) {
|
||||
const selectedId = this.selectedShortcutId
|
||||
if (value && selectedId) {
|
||||
const success = this.keybindingConfigurator.change(selectedId, value)
|
||||
if (!success) {
|
||||
this.handleDuplicateShortcut(selectedId, value)
|
||||
}
|
||||
}
|
||||
this.selectedShortcutId = null
|
||||
},
|
||||
handleDuplicateShortcut (id, accelerator) {
|
||||
notice.notify({
|
||||
title: 'Shortcut already in use',
|
||||
type: 'warning',
|
||||
message: `The shortcut "${accelerator}" is already in use. Please unset the shortcut and try again.`
|
||||
})
|
||||
},
|
||||
dumpKeyboardInformation () {
|
||||
ipcRenderer.send('mt::keybinding-debug-dump-keyboard-info')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,10 +170,17 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.pref-keybindings {
|
||||
& .keybinding-info {
|
||||
& .keyboard-debug,
|
||||
& .keybindings {
|
||||
font-size: 14px;
|
||||
margin: 20px 0;
|
||||
color: var(--editorColor);
|
||||
& .link {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
& .keybindings > div.text {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
& .link {
|
||||
color: var(--themeColor);
|
||||
@ -53,4 +190,59 @@ export default {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.el-table, .el-table__expanded-cell {
|
||||
background: var(--editorBgColor);
|
||||
}
|
||||
.el-table button {
|
||||
padding: 2px 2px;
|
||||
margin: 4px 0px;
|
||||
color: var(--themeColor);
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.el-table button:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.el-table button:hover,
|
||||
.el-table button:active {
|
||||
opacity: 0.9;
|
||||
background: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.pref-keybindings .el-table table {
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
.pref-keybindings .el-table th,
|
||||
.pref-keybindings .el-table tr {
|
||||
background: var(--editorBgColor);
|
||||
}
|
||||
.pref-keybindings .el-table th.el-table__cell.is-leaf,
|
||||
.pref-keybindings .el-table th,
|
||||
.pref-keybindings .el-table td {
|
||||
border: none;
|
||||
}
|
||||
.pref-keybindings .el-table th.el-table__cell.is-leaf:last-child,
|
||||
.pref-keybindings .el-table th:last-child,
|
||||
.pref-keybindings .el-table td:last-child {
|
||||
border-right: 1px solid var(--tableBorderColor);
|
||||
}
|
||||
.pref-keybindings .el-table--border::after,
|
||||
.pref-keybindings .el-table--group::after,
|
||||
.pref-keybindings .el-table::before,
|
||||
.pref-keybindings .el-table__fixed-right::before,
|
||||
.pref-keybindings .el-table__fixed::before {
|
||||
background: var(--tableBorderColor);
|
||||
}
|
||||
.pref-keybindings .el-table__body tr.hover-row.current-row>td,
|
||||
.pref-keybindings .el-table__body tr.hover-row.el-table__row--striped.current-row>td,
|
||||
.pref-keybindings .el-table__body tr.hover-row.el-table__row--striped>td,
|
||||
.pref-keybindings .el-table__body tr.hover-row>td {
|
||||
background: var(--selectionColor);
|
||||
}
|
||||
.pref-keybindings .el-table .el-table__cell {
|
||||
padding: 2px 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
239
src/renderer/prefComponents/keybindings/key-input-dialog.vue
Normal file
239
src/renderer/prefComponents/keybindings/key-input-dialog.vue
Normal file
@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<div class="key-input-dialog">
|
||||
<div v-if="showKeyInputDialog" class="input-overlay"></div>
|
||||
<el-dialog
|
||||
:visible.sync="showKeyInputDialog"
|
||||
:show-close="false"
|
||||
:modal="false"
|
||||
@close="cancelKeybinding"
|
||||
custom-class="ag-dialog-table"
|
||||
width="350px"
|
||||
>
|
||||
<div slot="title" class="key-input-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<input
|
||||
tabindex="0"
|
||||
type="text"
|
||||
ref="intputTextbox"
|
||||
v-model="keybindingInputValue"
|
||||
class="input-textbox"
|
||||
@keydown="handleKeyDown"
|
||||
@keyup="handleKeyUp"
|
||||
:placeholder="placeholderText"
|
||||
>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="descriptions">Press Enter to continue or ESC to exit.</div>
|
||||
<div
|
||||
v-show="!isKeybindingValid"
|
||||
class="invalid-keybinding"
|
||||
>
|
||||
Current key combination cannot be bound!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
isCompositionEvent,
|
||||
isValidElectronAccelerator,
|
||||
getAcceleratorFromKeyboardEvent
|
||||
} from '@hfelix/electron-localshortcut'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
this.needCommitOnClose = true
|
||||
this.currentKeybinding = null
|
||||
this.defaultPlaceholderText = 'Press a key combination'
|
||||
return {
|
||||
showKeyInputDialog: false,
|
||||
placeholderText: this.defaultPlaceholderText,
|
||||
isKeybindingValid: true,
|
||||
keybindingInputValue: ''
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
onCommit: Function,
|
||||
showWithId: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
showWithId: function (value, oldValue) {
|
||||
if (value !== oldValue) {
|
||||
if (value) {
|
||||
this.handleShow()
|
||||
} else {
|
||||
this.cancelKeybinding()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleShow () {
|
||||
this.needCommitOnClose = true
|
||||
this.showKeyInputDialog = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.intputTextbox.focus()
|
||||
})
|
||||
},
|
||||
handleDialogClose () {
|
||||
this.currentKeybinding = null
|
||||
this.isKeybindingValid = true
|
||||
this.keybindingInputValue = ''
|
||||
this.showKeyInputDialog = false
|
||||
},
|
||||
handleKeyDown (event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if (isCompositionEvent(event)) {
|
||||
// FIXME: You can still write in the textbox while composition.
|
||||
return
|
||||
} else if (this.isRawKeyCode(event, 'Escape')) {
|
||||
this.cancelKeybinding()
|
||||
return
|
||||
} else if (this.isRawKeyCode(event, 'Enter')) {
|
||||
this.saveKeybinding()
|
||||
return
|
||||
}
|
||||
|
||||
const keybinding = getAcceleratorFromKeyboardEvent(event)
|
||||
this.currentKeybinding = keybinding
|
||||
// Verify whether the given key binding is valid for Electron.
|
||||
this.isKeybindingValid = keybinding.isValid && isValidElectronAccelerator(keybinding.accelerator)
|
||||
this.keybindingInputValue = keybinding.accelerator
|
||||
},
|
||||
handleKeyUp (event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
},
|
||||
cancelKeybinding () {
|
||||
// Don't commit twice if the user clicks on the background.
|
||||
if (this.needCommitOnClose) {
|
||||
this.needCommitOnClose = false
|
||||
this.onCommit(null)
|
||||
this.handleDialogClose()
|
||||
}
|
||||
},
|
||||
saveKeybinding () {
|
||||
if (!this.currentKeybinding) {
|
||||
this.cancelKeybinding()
|
||||
return
|
||||
}
|
||||
|
||||
const { accelerator, isValid } = this.currentKeybinding
|
||||
if (!isValid) {
|
||||
// TODO: Show shake animation on error text.
|
||||
return
|
||||
}
|
||||
|
||||
this.needCommitOnClose = false
|
||||
this.onCommit(accelerator)
|
||||
this.handleDialogClose()
|
||||
},
|
||||
isRawKeyCode (event, keyCode) {
|
||||
const { code, ctrlKey, altKey, shiftKey, metaKey } = event
|
||||
return event && code === keyCode && !ctrlKey && !altKey && !shiftKey && !metaKey
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.key-input-wrapper {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 500px;
|
||||
height: auto;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 8px;
|
||||
margin: 0 auto;
|
||||
margin-top: 8px;
|
||||
box-sizing: border-box;
|
||||
color: var(--editorColor);
|
||||
background: var(--floatBgColor);
|
||||
border: 1px solid var(--floatBorderColor);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 3px 8px 3px var(--floatShadow);
|
||||
z-index: 10000;
|
||||
}
|
||||
.input-wrapper {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: 1px solid var(--inputBgColor);
|
||||
background: var(--inputBgColor);
|
||||
border-radius: 3px;
|
||||
}
|
||||
input.input-textbox {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
margin: 0 10px;
|
||||
font-size: 14px;
|
||||
color: var(--editorColor);
|
||||
background: transparent;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
.footer {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
& .description {
|
||||
margin-top: 2px;
|
||||
}
|
||||
& .invalid-keybinding {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity .2s;
|
||||
}
|
||||
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.input-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: var(--editorColor);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.key-input-dialog .el-dialog,
|
||||
.key-input-dialog .el-dialog.ag-dialog-table {
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
}
|
||||
.key-input-dialog .el-dialog__header {
|
||||
margin-bottom: 20px;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.key-input-dialog .el-dialog__body {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
111
test/unit/specs/match-electron-accelerator.spec.js
Normal file
111
test/unit/specs/match-electron-accelerator.spec.js
Normal file
@ -0,0 +1,111 @@
|
||||
import { isEqualAccelerator } from 'common/keybinding'
|
||||
|
||||
const keys = [
|
||||
'0',
|
||||
'1',
|
||||
'9',
|
||||
'A',
|
||||
'G',
|
||||
'Z',
|
||||
'F1',
|
||||
'F5',
|
||||
'F24',
|
||||
'~',
|
||||
'!',
|
||||
'@',
|
||||
'#',
|
||||
'Plus',
|
||||
'Space',
|
||||
'Tab',
|
||||
'Backspace',
|
||||
'Delete',
|
||||
'Insert',
|
||||
'Return',
|
||||
'Enter',
|
||||
'Up',
|
||||
'Down',
|
||||
'Left',
|
||||
'Right',
|
||||
'Home',
|
||||
'End',
|
||||
'PageUp',
|
||||
'PageDown',
|
||||
'Escape',
|
||||
'Esc',
|
||||
'VolumeUp',
|
||||
'VolumeDown',
|
||||
'VolumeMute',
|
||||
'MediaNextTrack',
|
||||
'MediaPreviousTrack',
|
||||
'MediaStop',
|
||||
'MediaPlayPause',
|
||||
'PrintScreen'
|
||||
]
|
||||
|
||||
const modifiers = [
|
||||
'Command',
|
||||
'Cmd',
|
||||
'Control',
|
||||
'Ctrl',
|
||||
'CommandOrControl',
|
||||
'CmdOrCtrl',
|
||||
'Alt',
|
||||
'Option',
|
||||
'AltGr',
|
||||
'Shift'
|
||||
]
|
||||
|
||||
describe('Test equal with basis keys', () => {
|
||||
it('Match Ctrl+A', () => {
|
||||
expect(isEqualAccelerator('Ctrl+A', 'A+Ctrl')).to.equal(true)
|
||||
})
|
||||
it('Match case insensitive with multiple modifiers', () => {
|
||||
expect(isEqualAccelerator('Ctrl+Alt+A', 'ctrl+alt+a')).to.equal(true)
|
||||
})
|
||||
it('Match case insensitive with multiple modifiers and upper-case letter', () => {
|
||||
expect(isEqualAccelerator('Ctrl+Shift+A', 'ctrl+shift+A')).to.equal(true)
|
||||
})
|
||||
it('Match mixed case with multiple modifiers', () => {
|
||||
expect(isEqualAccelerator('Ctrl+a+shift', 'ctrl+Shift+a')).to.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Test not equal with basis keys', () => {
|
||||
it('Mismatch Ctrl+A', () => {
|
||||
expect(isEqualAccelerator('Ctrl+A', 'A+Ctrl+Alt')).to.equal(false)
|
||||
})
|
||||
it('Mismatch case insensitive with multiple modifiers', () => {
|
||||
expect(isEqualAccelerator('Ctrl+A', 'ctrl+alt+a')).to.equal(false)
|
||||
})
|
||||
it('Mismatch letters only', () => {
|
||||
expect(isEqualAccelerator('a', 'b')).to.equal(false)
|
||||
})
|
||||
it('Mismatch same modifiers but different key', () => {
|
||||
expect(isEqualAccelerator('Ctrl+a+shift', 'ctrl+Shift+b')).to.equal(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Test invalid accelerator', () => {
|
||||
it('Ctrl+', () => {
|
||||
expect(isEqualAccelerator('Ctrl+', 'Ctrl+Plus')).to.equal(false)
|
||||
})
|
||||
it('Ctrl++', () => {
|
||||
expect(isEqualAccelerator('Ctrl++', 'Ctrl+Plus')).to.equal(false)
|
||||
})
|
||||
it('Emtpy accelerator 1', () => {
|
||||
expect(isEqualAccelerator('', 'Ctrl+A')).to.equal(false)
|
||||
})
|
||||
it('Emtpy accelerator 2', () => {
|
||||
expect(isEqualAccelerator('ctrl+Shift+b', '')).to.equal(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Match all', () => {
|
||||
modifiers.forEach(mod =>
|
||||
keys.forEach(key => {
|
||||
it(`Should match ${mod}+${key}`, () => {
|
||||
expect(isEqualAccelerator(`${mod}+${key}`, `${key}+${mod}`)).to.equal(true)
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
484
yarn.lock
484
yarn.lock
@ -80,20 +80,20 @@
|
||||
semver "^6.3.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/core@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf"
|
||||
integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==
|
||||
"@babel/core@^7.16.12":
|
||||
version "7.16.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784"
|
||||
integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.7"
|
||||
"@babel/generator" "^7.16.7"
|
||||
"@babel/generator" "^7.16.8"
|
||||
"@babel/helper-compilation-targets" "^7.16.7"
|
||||
"@babel/helper-module-transforms" "^7.16.7"
|
||||
"@babel/helpers" "^7.16.7"
|
||||
"@babel/parser" "^7.16.7"
|
||||
"@babel/parser" "^7.16.12"
|
||||
"@babel/template" "^7.16.7"
|
||||
"@babel/traverse" "^7.16.7"
|
||||
"@babel/types" "^7.16.7"
|
||||
"@babel/traverse" "^7.16.10"
|
||||
"@babel/types" "^7.16.8"
|
||||
convert-source-map "^1.7.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.2"
|
||||
@ -160,7 +160,7 @@
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.16.7", "@babel/generator@^7.16.8":
|
||||
"@babel/generator@^7.16.8":
|
||||
version "7.16.8"
|
||||
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe"
|
||||
integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==
|
||||
@ -230,6 +230,19 @@
|
||||
"@babel/helper-replace-supers" "^7.16.0"
|
||||
"@babel/helper-split-export-declaration" "^7.16.0"
|
||||
|
||||
"@babel/helper-create-class-features-plugin@^7.16.10":
|
||||
version "7.16.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c"
|
||||
integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.16.7"
|
||||
"@babel/helper-environment-visitor" "^7.16.7"
|
||||
"@babel/helper-function-name" "^7.16.7"
|
||||
"@babel/helper-member-expression-to-functions" "^7.16.7"
|
||||
"@babel/helper-optimise-call-expression" "^7.16.7"
|
||||
"@babel/helper-replace-supers" "^7.16.7"
|
||||
"@babel/helper-split-export-declaration" "^7.16.7"
|
||||
|
||||
"@babel/helper-create-class-features-plugin@^7.16.5":
|
||||
version "7.16.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz#5d1bcd096792c1ebec6249eebc6358eec55d0cad"
|
||||
@ -758,6 +771,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e"
|
||||
integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==
|
||||
|
||||
"@babel/parser@^7.16.10", "@babel/parser@^7.16.12":
|
||||
version "7.16.12"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6"
|
||||
integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==
|
||||
|
||||
"@babel/parser@^7.16.5":
|
||||
version "7.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.6.tgz#8f194828193e8fa79166f34a4b4e52f3e769a314"
|
||||
@ -967,12 +985,12 @@
|
||||
"@babel/helper-create-class-features-plugin" "^7.16.5"
|
||||
"@babel/helper-plugin-utils" "^7.16.5"
|
||||
|
||||
"@babel/plugin-proposal-private-methods@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz#e418e3aa6f86edd6d327ce84eff188e479f571e0"
|
||||
integrity sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==
|
||||
"@babel/plugin-proposal-private-methods@^7.16.11":
|
||||
version "7.16.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50"
|
||||
integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==
|
||||
dependencies:
|
||||
"@babel/helper-create-class-features-plugin" "^7.16.7"
|
||||
"@babel/helper-create-class-features-plugin" "^7.16.10"
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-proposal-private-property-in-object@^7.14.5":
|
||||
@ -1067,6 +1085,13 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.8.0"
|
||||
|
||||
"@babel/plugin-syntax-jsx@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
|
||||
integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
|
||||
@ -1333,6 +1358,17 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-react-jsx@^7.14.5":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4"
|
||||
integrity sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.16.7"
|
||||
"@babel/helper-module-imports" "^7.16.7"
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
"@babel/plugin-syntax-jsx" "^7.16.7"
|
||||
"@babel/types" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-regenerator@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb"
|
||||
@ -1347,10 +1383,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/plugin-transform-runtime@^7.16.8":
|
||||
version "7.16.8"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.8.tgz#3339368701103edae708f0fba9e4bfb70a3e5872"
|
||||
integrity sha512-6Kg2XHPFnIarNweZxmzbgYnnWsXxkx9WQUVk2sksBRL80lBC1RAQV3wQagWxdCHiYHqPN+oenwNIuttlYgIbQQ==
|
||||
"@babel/plugin-transform-runtime@^7.16.10":
|
||||
version "7.16.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.10.tgz#53d9fd3496daedce1dd99639097fa5d14f4c7c2c"
|
||||
integrity sha512-9nwTiqETv2G7xI4RvXHNfpGdr8pAA+Q/YtN3yLK7OoK7n9OibVm/xymJ838a9A6E/IciOLPj82lZk0fW6O4O7w==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.16.7"
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
@ -1419,10 +1455,10 @@
|
||||
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
|
||||
"@babel/helper-plugin-utils" "^7.16.7"
|
||||
|
||||
"@babel/preset-env@^7.16.8":
|
||||
version "7.16.8"
|
||||
resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.8.tgz#e682fa0bcd1cf49621d64a8956318ddfb9a05af9"
|
||||
integrity sha512-9rNKgVCdwHb3z1IlbMyft6yIXIeP3xz6vWvGaLHrJThuEIqWfHb0DNBH9VuTgnDfdbUDhkmkvMZS/YMCtP7Elg==
|
||||
"@babel/preset-env@^7.16.11":
|
||||
version "7.16.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982"
|
||||
integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.16.8"
|
||||
"@babel/helper-compilation-targets" "^7.16.7"
|
||||
@ -1442,7 +1478,7 @@
|
||||
"@babel/plugin-proposal-object-rest-spread" "^7.16.7"
|
||||
"@babel/plugin-proposal-optional-catch-binding" "^7.16.7"
|
||||
"@babel/plugin-proposal-optional-chaining" "^7.16.7"
|
||||
"@babel/plugin-proposal-private-methods" "^7.16.7"
|
||||
"@babel/plugin-proposal-private-methods" "^7.16.11"
|
||||
"@babel/plugin-proposal-private-property-in-object" "^7.16.7"
|
||||
"@babel/plugin-proposal-unicode-property-regex" "^7.16.7"
|
||||
"@babel/plugin-syntax-async-generators" "^7.8.4"
|
||||
@ -1601,6 +1637,22 @@
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.16.10":
|
||||
version "7.16.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f"
|
||||
integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.16.7"
|
||||
"@babel/generator" "^7.16.8"
|
||||
"@babel/helper-environment-visitor" "^7.16.7"
|
||||
"@babel/helper-function-name" "^7.16.7"
|
||||
"@babel/helper-hoist-variables" "^7.16.7"
|
||||
"@babel/helper-split-export-declaration" "^7.16.7"
|
||||
"@babel/parser" "^7.16.10"
|
||||
"@babel/types" "^7.16.8"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.16.5":
|
||||
version "7.16.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.5.tgz#d7d400a8229c714a59b87624fc67b0f1fbd4b2b3"
|
||||
@ -1701,10 +1753,10 @@
|
||||
global-agent "^3.0.0"
|
||||
global-tunnel-ng "^2.7.1"
|
||||
|
||||
"@electron/remote@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@electron/remote/-/remote-2.0.1.tgz#810cbc595a21f0f94641eb2d7e8264063a3f84de"
|
||||
integrity sha512-bGX4/yB2bPZwXm1DsxgoABgH0Cz7oFtXJgkerB8VrStYdTyvhGAULzNLRn9rVmeAuC3VUDXaXpZIlZAZHpsLIA==
|
||||
"@electron/remote@^2.0.4":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@electron/remote/-/remote-2.0.4.tgz#c3dae436aed79d1b8adcefc5a4963c06750ad5d8"
|
||||
integrity sha512-8m2P/d2RH986PmMW5lKygbPEjEYJ7RgCe37Y8DQ1wujKMH6VjmLIB+Y+DP2SA611svCZc58TRSd8FraGvcfGZw==
|
||||
|
||||
"@electron/universal@1.0.5":
|
||||
version "1.0.5"
|
||||
@ -1737,15 +1789,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
|
||||
integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==
|
||||
|
||||
"@hfelix/electron-localshortcut@^3.1.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/@hfelix/electron-localshortcut/-/electron-localshortcut-3.1.1.tgz#97e2f200568bffd5a49b465830b84f76fbc1130d"
|
||||
integrity sha512-0kXNL54CE4d6oaUjZJ0kWzIVhENDp9JB9cFJnREwkhbR+aKvzGKeT8yofmf5tq+cZcoLKyBPchDtJLNDls8j5w==
|
||||
"@hfelix/electron-localshortcut@^4.0.0-rc.1":
|
||||
version "4.0.0-rc.1"
|
||||
resolved "https://registry.yarnpkg.com/@hfelix/electron-localshortcut/-/electron-localshortcut-4.0.0-rc.1.tgz#1d7801c32ddd2ad2785073b920dcd16f24c1e53a"
|
||||
integrity sha512-rRiwMBPJkPe/aAuzjFcjuIokm8VsTTWsCPOHNsjrrLWhOy+/TCiwEmdspCguLt07e23oXMhbMLALE3N3NFJGTg==
|
||||
dependencies:
|
||||
"@hfelix/keyboardevent-from-electron-accelerator" "^1.1.1"
|
||||
debug "^4.0.1"
|
||||
electron-is-accelerator "^0.1.0"
|
||||
keyboardevents-areequal "^0.2.1"
|
||||
debug "^4.3.3"
|
||||
|
||||
"@hfelix/electron-spellchecker@^2.0.0":
|
||||
version "2.0.0"
|
||||
@ -1761,11 +1810,6 @@
|
||||
lru-cache "^6.0.0"
|
||||
p-throttle "^3.1.0"
|
||||
|
||||
"@hfelix/keyboardevent-from-electron-accelerator@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/@hfelix/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-1.1.1.tgz#7e1d4fd913759c381b7919cc7faf4c0c641d457c"
|
||||
integrity sha512-1eVkDSqoRQkF2FrPPia2EZ3310c0TvFKYvSuJbaxHpRKbI6eVHcVGKpmOSDli6Qdn3Bu0h7ozfgMZbAEBD+BLQ==
|
||||
|
||||
"@hfelix/spellchecker@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@hfelix/spellchecker/-/spellchecker-4.1.0.tgz#d569a7adefe43ba154688e4a6cac15303ace53e9"
|
||||
@ -2000,10 +2044,10 @@
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^11.2.0"
|
||||
|
||||
"@playwright/test@^1.17.2":
|
||||
version "1.17.2"
|
||||
resolved "https://registry.npmjs.org/@playwright/test/-/test-1.17.2.tgz#0c67e329a28ffe43a79dc15a0e139dadd9cb250f"
|
||||
integrity sha512-lxauaOlLNddQsgknCDJZEo8spTlSUF7gU4jXf0sUDLFsH/KE4ySe4SOPUGbtw+lCMrUfSbSRz0e7wnw5z78LNA==
|
||||
"@playwright/test@^1.18.1":
|
||||
version "1.18.1"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.18.1.tgz#efaa3aa9c7f8aebeb75cd45fd9737529e9b30fbd"
|
||||
integrity sha512-v6jAM2GpRvf4MUvSLkrAXg101XT9mLu2X2NbCnEoj7GHBXwavDlAJDMwh4Hn8oipDxB6MS6FTcr7opXsIMNwrA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.14.5"
|
||||
"@babel/core" "^7.14.8"
|
||||
@ -2021,20 +2065,23 @@
|
||||
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
|
||||
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.14.5"
|
||||
"@babel/plugin-transform-react-jsx" "^7.14.5"
|
||||
"@babel/preset-typescript" "^7.14.5"
|
||||
babel-plugin-module-resolver "^4.1.0"
|
||||
colors "1.4.0"
|
||||
commander "^8.2.0"
|
||||
debug "^4.1.1"
|
||||
expect "=27.2.5"
|
||||
jest-matcher-utils "=27.2.5"
|
||||
jpeg-js "^0.4.2"
|
||||
json5 "^2.2.0"
|
||||
mime "^2.4.6"
|
||||
minimatch "^3.0.3"
|
||||
ms "^2.1.2"
|
||||
open "^8.3.0"
|
||||
pirates "^4.0.1"
|
||||
pixelmatch "^5.2.1"
|
||||
playwright-core "=1.17.2"
|
||||
playwright-core "=1.18.1"
|
||||
pngjs "^5.0.0"
|
||||
rimraf "^3.0.2"
|
||||
source-map-support "^0.4.18"
|
||||
@ -2572,22 +2619,22 @@
|
||||
"@webassemblyjs/ast" "1.11.1"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webpack-cli/configtest@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043"
|
||||
integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==
|
||||
"@webpack-cli/configtest@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356"
|
||||
integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==
|
||||
|
||||
"@webpack-cli/info@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223"
|
||||
integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==
|
||||
"@webpack-cli/info@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea"
|
||||
integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==
|
||||
dependencies:
|
||||
envinfo "^7.7.3"
|
||||
|
||||
"@webpack-cli/serve@^1.6.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2"
|
||||
integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==
|
||||
"@webpack-cli/serve@^1.6.1":
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe"
|
||||
integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
@ -2841,10 +2888,10 @@ app-builder-bin@3.7.1:
|
||||
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.7.1.tgz#cb0825c5e12efc85b196ac3ed9c89f076c61040e"
|
||||
integrity sha512-ql93vEUq6WsstGXD+SBLSIQw6SNnhbDEM0swzgugytMxLp3rT24Ag/jcC80ZHxiPRTdew1niuR7P3/FCrDqIjw==
|
||||
|
||||
app-builder-lib@22.14.8:
|
||||
version "22.14.8"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.14.8.tgz#37137f45c5768d46a022d49b5577426264d3f19d"
|
||||
integrity sha512-Lg3mvgR45LynhMVwVFIJgIfozaTBrcAJY3sGE3Mq5O7GVwYf0Ucdoi3mc6EqAhiyCerNznKfW9vCeL0E85vIog==
|
||||
app-builder-lib@22.14.13:
|
||||
version "22.14.13"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.14.13.tgz#c1f5b6afc86596357598bb90b69eef06c7c2eeb3"
|
||||
integrity sha512-SufmrtxU+D0Tn948fjEwAOlCN9757UXLkzzTWXMwZKR/5hisvgqeeBepWfphMIE6OkDGz0fbzEhL1P2Pty4XMg==
|
||||
dependencies:
|
||||
"7zip-bin" "~5.1.1"
|
||||
"@develar/schema-utils" "~2.6.5"
|
||||
@ -2852,13 +2899,13 @@ app-builder-lib@22.14.8:
|
||||
"@malept/flatpak-bundler" "^0.4.0"
|
||||
async-exit-hook "^2.0.1"
|
||||
bluebird-lst "^1.0.9"
|
||||
builder-util "22.14.7"
|
||||
builder-util "22.14.13"
|
||||
builder-util-runtime "8.9.2"
|
||||
chromium-pickle-js "^0.2.0"
|
||||
debug "^4.3.2"
|
||||
ejs "^3.1.6"
|
||||
electron-osx-sign "^0.5.0"
|
||||
electron-publish "22.14.7"
|
||||
electron-publish "22.14.13"
|
||||
form-data "^4.0.0"
|
||||
fs-extra "^10.0.0"
|
||||
hosted-git-info "^4.0.2"
|
||||
@ -3105,12 +3152,12 @@ autoprefixer@^10.4.2:
|
||||
picocolors "^1.0.0"
|
||||
postcss-value-parser "^4.2.0"
|
||||
|
||||
axios@^0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
|
||||
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
||||
axios@^0.25.0:
|
||||
version "0.25.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a"
|
||||
integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==
|
||||
dependencies:
|
||||
follow-redirects "^1.14.4"
|
||||
follow-redirects "^1.14.7"
|
||||
|
||||
babel-helper-vue-jsx-merge-props@^2.0.0:
|
||||
version "2.0.3"
|
||||
@ -3152,6 +3199,17 @@ babel-plugin-istanbul@^6.1.1:
|
||||
istanbul-lib-instrument "^5.0.4"
|
||||
test-exclude "^6.0.0"
|
||||
|
||||
babel-plugin-module-resolver@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2"
|
||||
integrity sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==
|
||||
dependencies:
|
||||
find-babel-config "^1.2.0"
|
||||
glob "^7.1.6"
|
||||
pkg-up "^3.1.0"
|
||||
reselect "^4.0.0"
|
||||
resolve "^1.13.1"
|
||||
|
||||
babel-plugin-polyfill-corejs2@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd"
|
||||
@ -3466,10 +3524,10 @@ builder-util-runtime@8.9.2:
|
||||
debug "^4.3.2"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util@22.14.7:
|
||||
version "22.14.7"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.14.7.tgz#bb445f6102ccab4e4fdc8dd57de9dda9bb672666"
|
||||
integrity sha512-M8ql8WPW/P9UKsF00YZjiP5h29MYrJ3svJx5suszC5EGwIdAztIhFyXoXKI3hPtDaR5b6EoWD9nLa5/Gr+QToQ==
|
||||
builder-util@22.14.13:
|
||||
version "22.14.13"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.14.13.tgz#41b5b7b4ee53aff4e09cc007fb144522598f3ce6"
|
||||
integrity sha512-oePC/qrrUuerhmH5iaCJzPRAKlSBylrhzuAJmRQClTyWnZUv6jbaHh+VoHMbEiE661wrj2S2aV7/bQh12cj1OA==
|
||||
dependencies:
|
||||
"7zip-bin" "~5.1.1"
|
||||
"@types/debug" "^4.1.6"
|
||||
@ -3659,15 +3717,16 @@ cfonts@^2.10.0:
|
||||
chalk "^4.1.2"
|
||||
window-size "^1.1.1"
|
||||
|
||||
chai@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49"
|
||||
integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==
|
||||
chai@^4.3.6:
|
||||
version "4.3.6"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"
|
||||
integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==
|
||||
dependencies:
|
||||
assertion-error "^1.1.0"
|
||||
check-error "^1.0.2"
|
||||
deep-eql "^3.0.1"
|
||||
get-func-name "^2.0.0"
|
||||
loupe "^2.3.1"
|
||||
pathval "^1.1.1"
|
||||
type-detect "^4.0.5"
|
||||
|
||||
@ -3787,6 +3846,21 @@ chokidar@^3.5.1, chokidar@^3.5.2:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
chokidar@^3.5.3:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
@ -3968,10 +4042,10 @@ code-point-at@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
|
||||
codemirror@^5.65.0:
|
||||
version "5.65.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.0.tgz#50344359393579f526ca53797e510ff75477117f"
|
||||
integrity sha512-gWEnHKEcz1Hyz7fsQWpK7P0sPI2/kSkRX2tc7DFA6TmZuDN75x/1ejnH/Pn8adYKrLEA1V2ww6L00GudHZbSKw==
|
||||
codemirror@^5.65.1:
|
||||
version "5.65.1"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.1.tgz#5988a812c974c467f964bcc1a00c944e373de502"
|
||||
integrity sha512-s6aac+DD+4O2u1aBmdxhB7yz2XU7tG3snOyQ05Kxifahz7hoxnfxIRHxiCSEv3TUC38dIVH8G+lZH9UWSfGQxA==
|
||||
|
||||
collection-visit@^1.0.0:
|
||||
version "1.0.0"
|
||||
@ -4020,7 +4094,7 @@ colors@1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
|
||||
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
|
||||
|
||||
colors@1.4.0, colors@^1.1.2, colors@^1.3.3:
|
||||
colors@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||
@ -4266,10 +4340,10 @@ copy-descriptor@^0.1.0:
|
||||
resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
|
||||
|
||||
copy-webpack-plugin@^10.2.0:
|
||||
version "10.2.0"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.2.0.tgz#24c2d256953a55400a1ec66be4e0eccd1c4ae958"
|
||||
integrity sha512-my6iXII95c78w14HzYCNya5TlJYa44lOppAge5GSTMM1SyDxNsVGCJvhP4/ld6snm8lzjn3XOonMZD6s1L86Og==
|
||||
copy-webpack-plugin@^10.2.1:
|
||||
version "10.2.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.2.1.tgz#115a41f913070ac236a1b576066204cbf35341a1"
|
||||
integrity sha512-nr81NhCAIpAWXGCK5thrKmfCQ6GDY0L5RN0U+BnIn/7Us55+UCex5ANNsNKmIVtDRnk0Ecf+/kzp9SUVrrBMLg==
|
||||
dependencies:
|
||||
fast-glob "^3.2.7"
|
||||
glob-parent "^6.0.1"
|
||||
@ -5124,7 +5198,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.0.1, debug@^4.1.0:
|
||||
debug@4, debug@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
@ -5152,7 +5226,7 @@ debug@^3.2.7:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.1, debug@~4.3.1, debug@~4.3.2:
|
||||
debug@^4.1.1, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||
@ -5414,13 +5488,13 @@ dir-glob@^3.0.1:
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
dmg-builder@22.14.8:
|
||||
version "22.14.8"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.14.8.tgz#97c5265ca712a707f0d598777606cb7ef711c46d"
|
||||
integrity sha512-Dui12ofMfFLoqMMPgU60OgUU1tG8orWkYIa+zmen6I74VO1b+ell+Fkcu95jlX7JiLyMSuhzmUcfBnCc4NTCaw==
|
||||
dmg-builder@22.14.13:
|
||||
version "22.14.13"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.14.13.tgz#cc613f3c18e889b8777d525991fd52f50a564f8c"
|
||||
integrity sha512-xNOugB6AbIRETeU2uID15sUfjdZZcKdxK8xkFnwIggsM00PJ12JxpLNPTjcRoUnfwj3WrPjilrO64vRMwNItQg==
|
||||
dependencies:
|
||||
app-builder-lib "22.14.8"
|
||||
builder-util "22.14.7"
|
||||
app-builder-lib "22.14.13"
|
||||
builder-util "22.14.13"
|
||||
builder-util-runtime "8.9.2"
|
||||
fs-extra "^10.0.0"
|
||||
iconv-lite "^0.6.2"
|
||||
@ -5594,11 +5668,16 @@ domino@^2.1.6:
|
||||
resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe"
|
||||
integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==
|
||||
|
||||
dompurify@2.3.4, dompurify@^2.3.4:
|
||||
dompurify@2.3.4:
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6"
|
||||
integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ==
|
||||
|
||||
dompurify@^2.3.5:
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.5.tgz#c83ed5a3ae5ce23e52efe654ea052ffb358dd7e3"
|
||||
integrity sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==
|
||||
|
||||
domready@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz#91f252e597b65af77e745ae24dd0185d5e26d58c"
|
||||
@ -5695,17 +5774,17 @@ ejs@^3.1.6:
|
||||
dependencies:
|
||||
jake "^10.6.1"
|
||||
|
||||
electron-builder@^22.14.8:
|
||||
version "22.14.8"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.14.8.tgz#f6d253700b1cf81c6c4132daefac4b12a3046c74"
|
||||
integrity sha512-vfujO+XJiNI9mnppePEvukjqDvBu0n3mKtP0AgEgfQkB0JL3zh1qcWS/BpvB6SRjK6CoFZnOyyLrepcdtlhi7A==
|
||||
electron-builder@^22.14.13:
|
||||
version "22.14.13"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.14.13.tgz#fd40564685cf5422a8f8d667940af3d3776f4fb8"
|
||||
integrity sha512-3fgLxqF2TXVKiUPeg74O4V3l0l3j7ERLazo8sUbRkApw0+4iVAf2BJkHsHMaXiigsgCoEzK/F4/rB5rne/VAnw==
|
||||
dependencies:
|
||||
"@types/yargs" "^17.0.1"
|
||||
app-builder-lib "22.14.8"
|
||||
builder-util "22.14.7"
|
||||
app-builder-lib "22.14.13"
|
||||
builder-util "22.14.13"
|
||||
builder-util-runtime "8.9.2"
|
||||
chalk "^4.1.1"
|
||||
dmg-builder "22.14.8"
|
||||
dmg-builder "22.14.13"
|
||||
fs-extra "^10.0.0"
|
||||
is-ci "^3.0.0"
|
||||
lazy-val "^1.0.5"
|
||||
@ -5723,20 +5802,10 @@ electron-devtools-installer@^3.2.0:
|
||||
tslib "^2.1.0"
|
||||
unzip-crx-3 "^0.2.0"
|
||||
|
||||
electron-is-accelerator@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
|
||||
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
|
||||
|
||||
electron-is-accelerator@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.2.0.tgz#8768feb2eb64ded6bcb98936853a4a6dcf6bfb46"
|
||||
integrity sha512-jml8EDK0x1xuPCr8ZWr+tuCL9RwfR4lee+WhLID2WZ0ygGSlnkumF6K1zw05CgnkDvHuKhFV6/NrSDI87QWAfA==
|
||||
|
||||
electron-log@^4.4.4:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.npmjs.org/electron-log/-/electron-log-4.4.4.tgz#df893ae9ae8c21781a585eea50ce7836ac3e0fe7"
|
||||
integrity sha512-jcNtrVmKXG+CHchLo/jnjjQ9K4/ORguWD23H2nqApTwisQ4Qo3IRQtLiorubajX0Uxg76Xm/Yt+eNfQMoHVr5w==
|
||||
electron-log@^4.4.5:
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.4.5.tgz#5fcfd0c2dc5fbda915ee0a9d802705dc57930786"
|
||||
integrity sha512-Cfa2CKnwBhlUfIl/qr2GF5SCqfoA9yPBqTJ6/wPs+PEn36M2+EZ3RpGSaOhYQ1BZpolL1CWyeu3gMG8epLl3Ng==
|
||||
|
||||
electron-osx-sign@^0.5.0:
|
||||
version "0.5.0"
|
||||
@ -5750,31 +5819,31 @@ electron-osx-sign@^0.5.0:
|
||||
minimist "^1.2.0"
|
||||
plist "^3.0.1"
|
||||
|
||||
electron-publish@22.14.7:
|
||||
version "22.14.7"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.14.7.tgz#5fb3a4278fdb7873c5a282152b909fe9814a4102"
|
||||
integrity sha512-sqZX/64k0B7sQeaDzFDE6m7r2zOtFgdmWAFnkv10bLlbHagkH9AkwwcjiGBpIto7mUBp89ntL7Ij5QFvldqI4Q==
|
||||
electron-publish@22.14.13:
|
||||
version "22.14.13"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.14.13.tgz#8b71e6975af8cc6ac5b21f293ade23f8704047c7"
|
||||
integrity sha512-0oP3QiNj3e8ewOaEpEJV/o6Zrmy2VarVvZ/bH7kyO/S/aJf9x8vQsKVWpsdmSiZ5DJEHgarFIXrnO0ZQf0P9iQ==
|
||||
dependencies:
|
||||
"@types/fs-extra" "^9.0.11"
|
||||
builder-util "22.14.7"
|
||||
builder-util "22.14.13"
|
||||
builder-util-runtime "8.9.2"
|
||||
chalk "^4.1.1"
|
||||
fs-extra "^10.0.0"
|
||||
lazy-val "^1.0.5"
|
||||
mime "^2.5.2"
|
||||
|
||||
electron-rebuild@^3.2.5:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-3.2.5.tgz#a9e82b4259aac33ad449f6959de68ded2c5679f8"
|
||||
integrity sha512-U9dKi10V9w/BdIVB8a8dTKYLK3Q1d2WZ+Yo5qfM3XX/O4jI7KpnwgvWgGoVv0jTWPC2NlebF00ffWS/8NfUAtA==
|
||||
electron-rebuild@^3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-3.2.7.tgz#0f56c1cc99a6fec0a5b990532283c2a8c838c19b"
|
||||
integrity sha512-WvaW1EgRinDQ61khHFZfx30rkPQG5ItaOT0wrI7iJv9A3SbghriQGfZQfHZs25fWLBe6/vkv05LOqg6aDw6Wzw==
|
||||
dependencies:
|
||||
"@malept/cross-spawn-promise" "^2.0.0"
|
||||
colors "^1.3.3"
|
||||
chalk "^4.0.0"
|
||||
debug "^4.1.1"
|
||||
detect-libc "^1.0.3"
|
||||
fs-extra "^10.0.0"
|
||||
got "^11.7.0"
|
||||
lzma-native "^8.0.1"
|
||||
lzma-native "^8.0.5"
|
||||
node-abi "^3.0.0"
|
||||
node-api-version "^0.1.4"
|
||||
node-gyp "^8.4.0"
|
||||
@ -5823,10 +5892,10 @@ electron-window-state@^5.0.3:
|
||||
jsonfile "^4.0.0"
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
electron@^15.3.4:
|
||||
version "15.3.4"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-15.3.4.tgz#811e8872f4500b88ad49e005cbe8f93e10676f6d"
|
||||
integrity sha512-GLTE+UEKw1pJehkgpLgXtsHhYqSPp6skSNY1bxnY3dDYBrsPlP3nTEO9YQY2p4eHk+uxFVTXOVy5afcu9fIZ9A==
|
||||
electron@^15.3.6:
|
||||
version "15.3.6"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-15.3.6.tgz#19b9aee1e063b1983b3d7f535567d90e0e1b4d04"
|
||||
integrity sha512-mOOTcZH/Vlq9GP3B8G3aMvZQ4eZyCjUZZpLccABqsPyLUMEixcdx750DQ7M+iHYyo0BWxj/JuHblzQXgNnPkfg==
|
||||
dependencies:
|
||||
"@electron/get" "^1.13.0"
|
||||
"@types/node" "^14.6.2"
|
||||
@ -6157,10 +6226,10 @@ eslint-plugin-standard@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5"
|
||||
integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==
|
||||
|
||||
eslint-plugin-vue@^8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.2.0.tgz#b404bc10e3f43b2b7aad4ebb3b38090a58040202"
|
||||
integrity sha512-cLIdTuOAMXyHeQ4drYKcZfoyzdwdBpH279X8/N0DgmotEI9yFKb5O/cAgoie/CkQZCH/MOmh0xw/KEfS90zY2A==
|
||||
eslint-plugin-vue@^8.4.0:
|
||||
version "8.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.4.0.tgz#16e59b356386b4428fb7d886b6d8ee5df2bbc09d"
|
||||
integrity sha512-Ga96QRG8GA9AyzKtEDxqYRCMt/VJM4SLkcNmm4FvUiFBE4jpaBr25unRBi9iVmHLYhA9EZ/4I+jD8n1vfWzyAA==
|
||||
dependencies:
|
||||
eslint-utils "^3.0.0"
|
||||
natural-compare "^1.4.0"
|
||||
@ -6678,6 +6747,14 @@ finalhandler@1.1.2, finalhandler@~1.1.2:
|
||||
statuses "~1.5.0"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
find-babel-config@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2"
|
||||
integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==
|
||||
dependencies:
|
||||
json5 "^0.5.1"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
find-cache-dir@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
|
||||
@ -6763,10 +6840,10 @@ follow-redirects@^1.0.0:
|
||||
dependencies:
|
||||
debug "^3.0.0"
|
||||
|
||||
follow-redirects@^1.14.4:
|
||||
version "1.14.5"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
|
||||
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
|
||||
follow-redirects@^1.14.7:
|
||||
version "1.14.7"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
||||
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
|
||||
|
||||
fontmanager-redux@^1.1.0:
|
||||
version "1.1.0"
|
||||
@ -8200,10 +8277,10 @@ isexe@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
iso-639-1@^2.1.11:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.11.tgz#a928a7c71025321258bd46e03ae85e49ded5dbdc"
|
||||
integrity sha512-WDF2XWfw1GuPvjn3YEn1+gFGF+72ZltVcjNhaWwmgvveN+rTy3XzWYwgIp/Y8CSZYclNvJ4Vqeh5byubiXCzPw==
|
||||
iso-639-1@^2.1.12:
|
||||
version "2.1.12"
|
||||
resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.12.tgz#3893075f50506e98e6243398a5d83ea0f6355524"
|
||||
integrity sha512-XuThg6XyPBj4RpXtsLbgbJPww6cQeSoiVQWJprM72f1ZTEV/1oeTMzU+dUY+SMPkHfIM5CfaliR4veTVtdXRKg==
|
||||
|
||||
isobject@^2.0.0, isobject@^2.1.0:
|
||||
version "2.1.0"
|
||||
@ -8460,6 +8537,11 @@ json-stringify-safe@^5.0.1:
|
||||
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
json5@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
|
||||
|
||||
json5@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
|
||||
@ -8551,12 +8633,12 @@ karma-sourcemap-loader@^0.3.8:
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
|
||||
karma-spec-reporter@0.0.32:
|
||||
version "0.0.32"
|
||||
resolved "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz#2e9c7207ea726771260259f82becb543209e440a"
|
||||
integrity sha1-LpxyB+pyZ3EmAln4K+y1QyCeRAo=
|
||||
karma-spec-reporter@0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.33.tgz#5b2712c3eaff7ae50dbd6ad4e5fb59befd740a96"
|
||||
integrity sha512-xRVevDUkiIVhKbDQ3CmeGEpyzA4b3HeVl95Sx5yJAvurpdKUSYF6ZEbQOqKJ7vrtDniABV1hyFez9KX9+7ruBA==
|
||||
dependencies:
|
||||
colors "^1.1.2"
|
||||
colors "1.4.0"
|
||||
|
||||
karma-webpack@^5.0.0:
|
||||
version "5.0.0"
|
||||
@ -8567,10 +8649,10 @@ karma-webpack@^5.0.0:
|
||||
minimatch "^3.0.4"
|
||||
webpack-merge "^4.1.5"
|
||||
|
||||
karma@^6.3.11:
|
||||
version "6.3.11"
|
||||
resolved "https://registry.npmjs.org/karma/-/karma-6.3.11.tgz#2c2fb09f1a9f52e1a0739adeedace2a68d4c0d34"
|
||||
integrity sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ==
|
||||
karma@^6.3.12:
|
||||
version "6.3.12"
|
||||
resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.12.tgz#fe6347f027385fc16da1a9bb87d766e2d25981c6"
|
||||
integrity sha512-qwIG+oB2YmHx4hjvYSRMNzL3YWAJ9baHaLAxiP7biFNkfpwYTUTtPck0joFpucalNLzMr+7z/FX1uY/kl8DV9A==
|
||||
dependencies:
|
||||
body-parser "^1.19.0"
|
||||
braces "^3.0.2"
|
||||
@ -8611,11 +8693,6 @@ keyboard-layout@^2.0.17:
|
||||
event-kit "^2.0.0"
|
||||
nan "^2.13.2"
|
||||
|
||||
keyboardevents-areequal@^0.2.1:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194"
|
||||
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
|
||||
|
||||
keypress@0.1.x:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a"
|
||||
@ -8944,6 +9021,13 @@ longest@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
||||
integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
|
||||
|
||||
loupe@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.1.tgz#a2e1192c9f452e4e85089766da10ac8288383947"
|
||||
integrity sha512-EN1D3jyVmaX4tnajVlfbREU4axL647hLec1h/PXAb8CPDMJiYitcWF2UeLVNttRqaIqQs4x+mRvXf+d+TlDrCA==
|
||||
dependencies:
|
||||
get-func-name "^2.0.0"
|
||||
|
||||
lower-case-first@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
|
||||
@ -8995,10 +9079,10 @@ lru-cache@^6.0.0:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lzma-native@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lzma-native/-/lzma-native-8.0.1.tgz#8569e2f88de461a9a2469ac9d8183637c387d682"
|
||||
integrity sha512-Ryr9X3yDVZhRYOxR8QhUBCNe6GdEfy9BvFDIFtUvEkocvSvnrYt9lRm6FR1z0eQn0QSMenrgrDIJRMgUf9zsKQ==
|
||||
lzma-native@^8.0.5:
|
||||
version "8.0.6"
|
||||
resolved "https://registry.yarnpkg.com/lzma-native/-/lzma-native-8.0.6.tgz#3ea456209d643bafd9b5d911781bdf0b396b2665"
|
||||
integrity sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==
|
||||
dependencies:
|
||||
node-addon-api "^3.1.0"
|
||||
node-gyp-build "^4.2.1"
|
||||
@ -9240,10 +9324,10 @@ mimic-response@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
||||
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
|
||||
|
||||
mini-css-extract-plugin@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.5.1.tgz#af8c7c40d08251f165ac3e046a5cae9d2c1a58c8"
|
||||
integrity sha512-CRC6E2yedNjfOA3nQjpqAkpnranxhxmilhBPYtldnXcPT/QZb3aJFzvt0pp8W1jhuLR/E0zDa+QEHuC/HhhaLQ==
|
||||
mini-css-extract-plugin@^2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.5.3.tgz#c5c79f9b22ce9b4f164e9492267358dbe35376d9"
|
||||
integrity sha512-YseMB8cs8U/KCaAGQoqYmfUuhhGW0a9p9XvWXrxVOkE3/IiISTLw4ALNt7JR5B2eYauFM+PQGSbXMDmVbR7Tfw==
|
||||
dependencies:
|
||||
schema-utils "^4.0.0"
|
||||
|
||||
@ -9310,7 +9394,7 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
minizlib@^2.0.0, minizlib@^2.1.1:
|
||||
minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
|
||||
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
|
||||
@ -9466,6 +9550,11 @@ napi-build-utils@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
||||
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
|
||||
|
||||
native-keymap@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-3.1.1.tgz#edecdc763129eb97754c0651e8f7da89a2b78958"
|
||||
integrity sha512-q6I3VBGW0dMxTvL2gXWkkl8Ofdlt56RxlPL/lknA8HjgXCpZ/esukuZGV+sGS1xif1muTM3gTnv2PGf4SxHovA==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
@ -10228,10 +10317,10 @@ pkg-up@^3.1.0:
|
||||
dependencies:
|
||||
find-up "^3.0.0"
|
||||
|
||||
playwright-core@=1.17.2:
|
||||
version "1.17.2"
|
||||
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.17.2.tgz#916254fa8fb3eb76c160b5c2e06bc979d6ec2cf8"
|
||||
integrity sha512-TCYIt2UNHvqGxvD79bBjBv9osDLAH1gn7AZD5kRpMNQJG6BAmJt8B4Ek8fzdKmCQOnHf9ASJmcYRszoIZxcdVA==
|
||||
playwright-core@=1.18.1:
|
||||
version "1.18.1"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.18.1.tgz#a5cf3f212d10692382e2acd1f7bc8c9ff9bbb849"
|
||||
integrity sha512-NALGl8R1GHzGLlhUApmpmfh6M1rrrPcDTygWvhTbprxwGB9qd/j9DRwyn4HTQcUB6o0/VOpo46fH9ez3+D/Rog==
|
||||
dependencies:
|
||||
commander "^8.2.0"
|
||||
debug "^4.1.1"
|
||||
@ -10250,12 +10339,12 @@ playwright-core@=1.17.2:
|
||||
yauzl "^2.10.0"
|
||||
yazl "^2.5.1"
|
||||
|
||||
playwright@^1.17.2:
|
||||
version "1.17.2"
|
||||
resolved "https://registry.npmjs.org/playwright/-/playwright-1.17.2.tgz#918b9a7e43ac8640fa3e2162ce0cb8b395c55fb7"
|
||||
integrity sha512-u1HZmVoeLCLptNcpuOyp5KfBzsdsLxE9CReK82i/p8j5i7EPqtY3fX77SMHqDGeO7tLBSYk2a6eFDVlQfSSANg==
|
||||
playwright@^1.18.1:
|
||||
version "1.18.1"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.18.1.tgz#45c2ca6ee25c44e336985de9b51955727b5f17cf"
|
||||
integrity sha512-8EaX9EtbtAoMq5tnzIsoA3b/V86V/6Mq2skuOU4qEw+5OVxs1lwesDwmjy/RVU1Qfx5UuwSQzhp45wyH22oa+A==
|
||||
dependencies:
|
||||
playwright-core "=1.17.2"
|
||||
playwright-core "=1.18.1"
|
||||
|
||||
plist@^3.0.1:
|
||||
version "3.0.1"
|
||||
@ -11119,6 +11208,11 @@ requires-port@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
reselect@^4.0.0:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6"
|
||||
integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==
|
||||
|
||||
resize-observer-polyfill@^1.5.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
@ -11151,7 +11245,7 @@ resolve-url@^0.2.1:
|
||||
resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||
|
||||
resolve@^1.1.10:
|
||||
resolve@^1.1.10, resolve@^1.13.1:
|
||||
version "1.22.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
||||
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
||||
@ -11626,10 +11720,10 @@ snabbdom-to-html@^7.0.0:
|
||||
object-assign "^4.1.0"
|
||||
parse-sel "^1.0.0"
|
||||
|
||||
snabbdom@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/snabbdom/-/snabbdom-3.2.0.tgz#8ea6b2517739a7d9ca82df3f181d052adf1ca5ad"
|
||||
integrity sha512-UWyfm8WbaFmbmYLC33pe5fawBfExhynkMDoZqQ8ehlHDwkxrgIOpWhKf5PaacLUW1n+Uwu5N5HND6mESU7cMlw==
|
||||
snabbdom@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f"
|
||||
integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ==
|
||||
|
||||
snake-case@^2.1.0:
|
||||
version "2.1.0"
|
||||
@ -13343,15 +13437,15 @@ webpack-bundle-analyzer@^4.5.0:
|
||||
sirv "^1.0.7"
|
||||
ws "^7.3.1"
|
||||
|
||||
webpack-cli@^4.9.1:
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
|
||||
integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==
|
||||
webpack-cli@^4.9.2:
|
||||
version "4.9.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d"
|
||||
integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==
|
||||
dependencies:
|
||||
"@discoveryjs/json-ext" "^0.5.0"
|
||||
"@webpack-cli/configtest" "^1.1.0"
|
||||
"@webpack-cli/info" "^1.4.0"
|
||||
"@webpack-cli/serve" "^1.6.0"
|
||||
"@webpack-cli/configtest" "^1.1.1"
|
||||
"@webpack-cli/info" "^1.4.1"
|
||||
"@webpack-cli/serve" "^1.6.1"
|
||||
colorette "^2.0.14"
|
||||
commander "^7.0.0"
|
||||
execa "^5.0.0"
|
||||
@ -13432,15 +13526,15 @@ webpack-merge@^5.7.3, webpack-merge@^5.8.0:
|
||||
clone-deep "^4.0.1"
|
||||
wildcard "^2.0.0"
|
||||
|
||||
webpack-sources@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260"
|
||||
integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==
|
||||
webpack-sources@^3.2.3:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@^5.66.0:
|
||||
version "5.66.0"
|
||||
resolved "https://registry.npmjs.org/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb"
|
||||
integrity sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg==
|
||||
webpack@^5.67.0:
|
||||
version "5.67.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.67.0.tgz#cb43ca2aad5f7cc81c4cd36b626e6b819805dbfd"
|
||||
integrity sha512-LjFbfMh89xBDpUMgA1W9Ur6Rn/gnr2Cq1jjHFPo4v6a79/ypznSYbAyPgGhwsxBtMIaEmDD1oJoA7BEYw/Fbrw==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.0"
|
||||
"@types/estree" "^0.0.50"
|
||||
@ -13465,7 +13559,7 @@ webpack@^5.66.0:
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.1.3"
|
||||
watchpack "^2.3.1"
|
||||
webpack-sources "^3.2.2"
|
||||
webpack-sources "^3.2.3"
|
||||
|
||||
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
|
||||
version "0.7.4"
|
||||
|
Loading…
Reference in New Issue
Block a user