├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── icons ├── mac │ └── app.icns ├── png │ ├── 1024x1024.png │ ├── 128x128.png │ ├── 16x16.png │ ├── 24x24.png │ ├── 256x256.png │ ├── 32x32.png │ ├── 48x48.png │ ├── 512x512.png │ ├── 64x64.png │ └── 96x96.png └── win │ └── app.ico ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── icon.png │ ├── style.scss │ └── theme.scss ├── background.ts ├── components │ ├── EditaroUpdateNotification.vue │ └── Preferences.vue ├── lib │ ├── languages.ts │ └── theme │ │ ├── dark-grad.ts │ │ ├── dark.ts │ │ ├── light-grad.ts │ │ ├── light.ts │ │ ├── themes.ts │ │ └── vscode.ts ├── main.ts ├── shims-monaco-vim.d.ts ├── shims-tsx.d.ts ├── shims-vue.d.ts ├── store.ts └── updator.ts ├── tsconfig.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: ['plugin:vue/essential', '@vue/prettier', '@vue/typescript'], 7 | rules: { 8 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 9 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 10 | quotes: ['error', 'single'], 11 | 'prettier/prettier': [ 12 | 'error', 13 | { 14 | trailingComma: 'es5', 15 | singleQuote: true, 16 | semi: false, 17 | }, 18 | ], 19 | }, 20 | parserOptions: { 21 | parser: 'typescript-eslint-parser', 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | 23 | #Electron-builder output 24 | /dist_electron -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kosuge Kazuya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dddraft(deprecated) 2 | 3 | チャットとかの下書き専用テキストエディタ 4 | 5 | **dddraft は [editaro](https://github.com/kkosuge/editaro) に変わりました。** 6 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/app'], 3 | } 4 | -------------------------------------------------------------------------------- /icons/mac/app.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/mac/app.icns -------------------------------------------------------------------------------- /icons/png/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/1024x1024.png -------------------------------------------------------------------------------- /icons/png/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/128x128.png -------------------------------------------------------------------------------- /icons/png/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/16x16.png -------------------------------------------------------------------------------- /icons/png/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/24x24.png -------------------------------------------------------------------------------- /icons/png/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/256x256.png -------------------------------------------------------------------------------- /icons/png/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/32x32.png -------------------------------------------------------------------------------- /icons/png/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/48x48.png -------------------------------------------------------------------------------- /icons/png/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/512x512.png -------------------------------------------------------------------------------- /icons/png/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/64x64.png -------------------------------------------------------------------------------- /icons/png/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/png/96x96.png -------------------------------------------------------------------------------- /icons/win/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/icons/win/app.ico -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dddraft", 3 | "version": "0.2.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "build:electron": "vue-cli-service build:electron", 10 | "postinstall": "electron-builder install-app-deps", 11 | "serve:electron": "vue-cli-service serve:electron" 12 | }, 13 | "dependencies": { 14 | "monaco-editor": "0.14.3", 15 | "monaco-vim": "^0.0.7", 16 | "node-sass": "^4.9.3", 17 | "pretty-checkbox": "^3.0.3", 18 | "sass-loader": "^7.1.0", 19 | "vue": "^2.5.17", 20 | "vue-class-component": "^6.0.0", 21 | "vue-property-decorator": "^7.0.0" 22 | }, 23 | "devDependencies": { 24 | "@vue/cli-plugin-babel": "^3.0.4", 25 | "@vue/cli-plugin-eslint": "^3.0.4", 26 | "@vue/cli-plugin-typescript": "^3.0.4", 27 | "@vue/cli-service": "^3.0.4", 28 | "@vue/eslint-config-prettier": "^3.0.4", 29 | "@vue/eslint-config-typescript": "^3.0.4", 30 | "electron": "^2.0.2", 31 | "typescript": "^3.0.0", 32 | "vue-cli-plugin-electron-builder": "^1.0.0-rc.3", 33 | "vue-template-compiler": "^2.5.17" 34 | }, 35 | "main": "dist_electron/bundled/background.js", 36 | "build": { 37 | "mac": { 38 | "icon": "icons/mac/app.icns" 39 | }, 40 | "win": { 41 | "icon": "icons/win/app.ico" 42 | }, 43 | "linux": { 44 | "icon": "icons/png" 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | <% if (BASE_URL === './') { %> 11 | 12 | <% } %> 13 | <% if (VUE_APP_NODE_MODULES_PATH !== "false") { %> 14 | 17 | <% } %> 18 | 19 | 20 | 21 | 22 | dddraft 23 | 24 | 25 | 26 | 29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 192 | -------------------------------------------------------------------------------- /src/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkosuge/dddraft/8dca35b074d4e44e3ddc779cda0b2a341ba7804d/src/assets/icon.png -------------------------------------------------------------------------------- /src/assets/style.scss: -------------------------------------------------------------------------------- 1 | @import "~pretty-checkbox/src/pretty-checkbox.scss"; 2 | @import "./theme.scss"; 3 | 4 | $title-bar-height: 22px; 5 | 6 | html, 7 | body { 8 | height: 100%; 9 | } 10 | 11 | body { 12 | margin: 0; 13 | background: #1e1e1e; 14 | } 15 | 16 | #app { 17 | font-family: 'Avenir', Helvetica, Arial, sans-serif; 18 | -webkit-font-smoothing: antialiased; 19 | color: #2c3e50; 20 | height: 100%; 21 | text-align: left; 22 | } 23 | 24 | .draggable-title-bar { 25 | z-index: 1000; 26 | position: fixed; 27 | top: 0; 28 | left: 0; 29 | height: $title-bar-height; 30 | width: 100%; 31 | -webkit-app-region: drag; 32 | } 33 | 34 | .main { 35 | position: relative; 36 | height: 100%; 37 | } 38 | 39 | .nav-bar { 40 | z-index: 1000; 41 | position: fixed; 42 | bottom: 0; 43 | left: 0; 44 | height: 22px; 45 | width: 100%; 46 | -webkit-app-region: drag; 47 | } 48 | 49 | .editor-wrapper { 50 | width: 100%; 51 | height: 100%; 52 | } 53 | 54 | #editor { 55 | padding-top: 22px; 56 | height: calc(100vh - 67px); 57 | } 58 | 59 | .nav-bar { 60 | display: flex; 61 | justify-content: flex-end; 62 | font-size: 12px; 63 | line-height: 22px; 64 | 65 | &-left { 66 | margin-left: 6px; 67 | display: flex; 68 | } 69 | 70 | &-right { 71 | margin-left: auto; 72 | display: flex; 73 | } 74 | 75 | &-item { 76 | margin-left: 10px; 77 | } 78 | 79 | &-item-checkbox { 80 | margin-left: 2px; 81 | cursor: pointer; 82 | user-select: none; 83 | } 84 | 85 | .pretty { 86 | padding-top: 4px; 87 | margin-left: 4px; 88 | } 89 | 90 | .pretty .state label:before { 91 | top: 3px; 92 | } 93 | 94 | .pretty .state label:after { 95 | top: 3px; 96 | } 97 | 98 | select { 99 | -webkit-appearance: none; 100 | appearance: none; 101 | border-radius: 0; 102 | border: 0; 103 | margin: 0; 104 | padding: 2px 4px; 105 | background: none transparent; 106 | border-radius: 4px; 107 | box-sizing: content-box; 108 | } 109 | 110 | .nav-bar-item-checkbox { 111 | margin-left: 12px; 112 | } 113 | } 114 | 115 | .preferences { 116 | position: fixed; 117 | top: $title-bar-height; 118 | left: 0; 119 | right: 0; 120 | bottom: 22px; 121 | z-index: 1001; 122 | font-size: 12px; 123 | padding: 12px 24px; 124 | 125 | .header { 126 | display: flex; 127 | justify-content: space-between; 128 | } 129 | 130 | h1 { 131 | font-weight: 100; 132 | font-size: 24px; 133 | margin: 0 0 12px 0; 134 | } 135 | } 136 | 137 | .close { 138 | opacity: 0.6; 139 | display: inline-block; 140 | width: 32px; 141 | height: 32px; 142 | position: relative; 143 | } 144 | 145 | .close:hover { 146 | opacity: 1; 147 | } 148 | 149 | .close:before, 150 | .close:after { 151 | position: absolute; 152 | left: 15px; 153 | content: ' '; 154 | height: 33px; 155 | width: 2px; 156 | background-color: #333; 157 | } 158 | 159 | .close:before { 160 | transform: rotate(45deg); 161 | } 162 | 163 | .close:after { 164 | transform: rotate(-45deg); 165 | } 166 | 167 | .vim-status-bar { 168 | white-space: nowrap; 169 | 170 | > span { 171 | margin-left: 2px; 172 | 173 | &:first-child { 174 | margin-left: 0; 175 | } 176 | } 177 | 178 | input[type="text"] { 179 | background: transparent; 180 | outline: 0; 181 | border-style: none; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/assets/theme.scss: -------------------------------------------------------------------------------- 1 | $theme-colors: ( 2 | title-bar: ( 3 | light: linear-gradient(to top, #cccccc 0%, #d6d6d6 1px, #ebebeb 100%), 4 | dark: #333 5 | ), 6 | border: ( 7 | light: #ddd, 8 | dark: #454545 9 | ), 10 | nav-bar: ( 11 | light: linear-gradient(to top, #cccccc 0%, #d6d6d6 1px, #ebebeb 100%), 12 | dark: #333, 13 | vscode: #0077d5, 14 | dark-grad: linear-gradient(to right, rgb(84, 51, 255), rgb(0, 171, 255), rgb(48, 217, 239)), 15 | light-grad: linear-gradient(to right, rgb(84, 51, 255), rgb(0, 171, 255), rgb(48, 217, 239)) 16 | ), 17 | nav-bar-text: ( 18 | light: #333, 19 | dark: #c1c1c1, 20 | vscode: #fff 21 | ), 22 | preferences: ( 23 | light: #fff, 24 | dark: #222, 25 | vscode: #222 26 | ), 27 | preferences-text: ( 28 | light: #333, 29 | dark: #fff, 30 | vscode: #fff 31 | ) 32 | ); 33 | 34 | @function theme-color($key: "base", $variant: "base") { 35 | $map: map-get($theme-colors, $key); 36 | 37 | @return map-get($map, $variant); 38 | } 39 | 40 | .theme-light { 41 | .draggable-title-bar { 42 | background: theme-color(title-bar, light); 43 | } 44 | 45 | .nav-bar { 46 | color: theme-color(nav-bar-text, light); 47 | background: theme-color(nav-bar, light); 48 | border-top: 1px solid theme-color(border, light); 49 | 50 | select { 51 | color: theme-color(nav-bar-text, light); 52 | } 53 | } 54 | 55 | .preferences { 56 | background-color: theme-color(preferences, light); 57 | color: theme-color(preferences-text, light); 58 | } 59 | 60 | .vim-status-bar { 61 | color: theme-color(nav-bar-text, light); 62 | 63 | input { 64 | color: theme-color(nav-bar-text, light); 65 | } 66 | } 67 | } 68 | 69 | .theme-dark { 70 | .draggable-title-bar { 71 | background: theme-color(title-bar, dark); 72 | } 73 | 74 | .nav-bar { 75 | color: theme-color(nav-bar-text, dark); 76 | background: theme-color(nav-bar, dark); 77 | border-top: 1px solid theme-color(border, dark); 78 | 79 | select { 80 | color: theme-color(nav-bar-text, dark); 81 | } 82 | } 83 | 84 | .preferences { 85 | background-color: theme-color(preferences, dark); 86 | color: theme-color(preferences-text, dark); 87 | } 88 | 89 | .close:before, 90 | .close:after { 91 | background-color: theme-color(preferences-text, dark); 92 | } 93 | 94 | .vim-status-bar { 95 | color: theme-color(nav-bar-text, dark); 96 | 97 | input { 98 | color: theme-color(nav-bar-text, dark); 99 | } 100 | } 101 | } 102 | 103 | 104 | .theme-vscode { 105 | .draggable-title-bar { 106 | background: theme-color(title-bar, dark); 107 | } 108 | 109 | .nav-bar { 110 | color: theme-color(nav-bar-text, vscode); 111 | background: theme-color(nav-bar, vscode); 112 | border-top: 1px solid theme-color(border, dark); 113 | 114 | select { 115 | color: theme-color(nav-bar-text, vscode); 116 | } 117 | } 118 | 119 | .preferences { 120 | background-color: theme-color(preferences, vscode); 121 | color: theme-color(preferences-text, vscode); 122 | } 123 | 124 | .close:before, 125 | .close:after { 126 | background-color: theme-color(preferences-text, vscode); 127 | } 128 | 129 | .vim-status-bar { 130 | color: theme-color(nav-bar-text, vscode); 131 | 132 | input { 133 | color: theme-color(nav-bar-text, vscode); 134 | } 135 | } 136 | } 137 | 138 | .theme-dark-grad { 139 | .draggable-title-bar { 140 | background: theme-color(title-bar, dark); 141 | } 142 | 143 | .nav-bar { 144 | color: theme-color(nav-bar-text, vscode); 145 | background: theme-color(nav-bar, dark-grad); 146 | border-top: 1px solid theme-color(border, dark); 147 | 148 | select { 149 | color: theme-color(nav-bar-text, vscode); 150 | } 151 | } 152 | 153 | .preferences { 154 | background-color: theme-color(preferences, dark); 155 | color: theme-color(preferences-text, dark); 156 | } 157 | 158 | .close:before, 159 | .close:after { 160 | background-color: theme-color(preferences-text, dark); 161 | } 162 | 163 | .vim-status-bar { 164 | color: theme-color(nav-bar-text, vscode); 165 | 166 | input { 167 | color: theme-color(nav-bar-text, vscode); 168 | } 169 | } 170 | } 171 | 172 | .theme-light-grad { 173 | .draggable-title-bar { 174 | background: theme-color(title-bar, light); 175 | } 176 | 177 | .nav-bar { 178 | color: theme-color(nav-bar-text, dark); 179 | background: theme-color(nav-bar, light-grad); 180 | border-top: 1px solid theme-color(border, light); 181 | 182 | select { 183 | color: theme-color(nav-bar-text, dark); 184 | } 185 | } 186 | 187 | .preferences { 188 | background-color: theme-color(preferences, light); 189 | color: theme-color(preferences-text, light); 190 | } 191 | 192 | .vim-status-bar { 193 | color: theme-color(nav-bar-text, dark); 194 | 195 | input { 196 | color: theme-color(nav-bar-text, dark); 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /src/background.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { 4 | app, 5 | protocol, 6 | BrowserWindow, 7 | ipcMain, 8 | clipboard, 9 | shell, 10 | Menu, 11 | } from 'electron' 12 | import * as path from 'path' 13 | import { format as formatUrl } from 'url' 14 | import { 15 | createProtocol, 16 | installVueDevtools, 17 | } from 'vue-cli-plugin-electron-builder/lib' 18 | import './updator' 19 | 20 | const isDevelopment = process.env.NODE_ENV !== 'production' 21 | if (isDevelopment) { 22 | // Don't load any native (external) modules until the following line is run: 23 | require('module').globalPaths.push(process.env.NODE_MODULES_PATH) 24 | } 25 | // global reference to mainWindow (necessary to prevent window from being garbage collected) 26 | let mainWindow: any 27 | 28 | // Standard scheme must be registered before the app is ready 29 | protocol.registerStandardSchemes(['app'], { secure: true }) 30 | function createMainWindow() { 31 | const window = new BrowserWindow({ 32 | width: 600, 33 | height: 400, 34 | titleBarStyle: 'hidden', 35 | alwaysOnTop: false, 36 | }) 37 | 38 | if (isDevelopment) { 39 | // Load the url of the dev server if in development mode 40 | window.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string) 41 | //if (!process.env.IS_TEST) window.webContents.openDevTools() 42 | } else { 43 | createProtocol('app') 44 | // Load the index.html when not in development 45 | window.loadURL( 46 | formatUrl({ 47 | pathname: path.join(__dirname, 'index.html'), 48 | protocol: 'file', 49 | slashes: true, 50 | }) 51 | ) 52 | } 53 | 54 | window.on('closed', () => { 55 | mainWindow = null 56 | }) 57 | 58 | window.webContents.on('devtools-opened', () => { 59 | window.focus() 60 | setImmediate(() => { 61 | window.focus() 62 | }) 63 | }) 64 | 65 | window.webContents.on('new-window', (event, url) => { 66 | event.preventDefault() 67 | shell.openExternal(url) 68 | }) 69 | 70 | // Menus 71 | const menuTemplate: any[] = [] 72 | 73 | if (process.platform === 'darwin') { 74 | menuTemplate.push( 75 | { 76 | label: app.getName(), 77 | submenu: [ 78 | { 79 | label: 'Preferences', 80 | accelerator: 'CmdOrCtrl+,', 81 | click: () => { 82 | if (mainWindow) mainWindow.webContents.send('preferences') 83 | }, 84 | }, 85 | { 86 | type: 'separator', 87 | }, 88 | { 89 | role: 'quit', 90 | }, 91 | ], 92 | }, 93 | { 94 | label: 'View', 95 | submenu: [ 96 | { 97 | label: 'Reload', 98 | accelerator: 'Command+R', 99 | click: function() { 100 | mainWindow.reload() 101 | }, 102 | }, 103 | { 104 | label: 'Close', 105 | accelerator: 'Command+W', 106 | click: function() { 107 | mainWindow.close() 108 | }, 109 | }, 110 | { 111 | label: 'Toggle Full Screen', 112 | accelerator: 'Ctrl+Command+F', 113 | click: function() { 114 | mainWindow.setFullScreen(!mainWindow.isFullScreen()) 115 | }, 116 | }, 117 | { 118 | label: 'Toggle Developer Tools', 119 | accelerator: 'Alt+Command+I', 120 | click: function() { 121 | mainWindow.toggleDevTools() 122 | }, 123 | }, 124 | ], 125 | } 126 | ) 127 | } 128 | 129 | Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate)) 130 | 131 | return window 132 | } 133 | 134 | // quit application when all windows are closed 135 | app.on('window-all-closed', () => { 136 | // on macOS it is common for applications to stay open until the user explicitly quits 137 | if (process.platform !== 'darwin') { 138 | app.quit() 139 | } 140 | }) 141 | 142 | app.on('activate', () => { 143 | // on macOS it is common to re-create a window even after all windows have been closed 144 | if (mainWindow === null) { 145 | mainWindow = createMainWindow() 146 | } 147 | }) 148 | 149 | // create main BrowserWindow when electron is ready 150 | app.on('ready', async () => { 151 | if (isDevelopment && !process.env.IS_TEST) { 152 | // Install Vue Devtools 153 | await installVueDevtools() 154 | } 155 | mainWindow = createMainWindow() 156 | }) 157 | 158 | ipcMain.on('alwaysOnTop', (event: any, arg: boolean) => { 159 | mainWindow.setAlwaysOnTop(arg) 160 | }) 161 | 162 | // Command|Ctrl + C でのコピー時に text/html のデータをクリップボードに書き込まないようにしたいため 163 | // setTimeout を挟まないと、レンダラープロセス側のデータが採用されてしまう 164 | ipcMain.on('copy', (event: any, arg: string) => { 165 | setTimeout(() => { 166 | clipboard.writeText(arg) 167 | }, 200) 168 | }) 169 | -------------------------------------------------------------------------------- /src/components/EditaroUpdateNotification.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 16 | 35 | -------------------------------------------------------------------------------- /src/components/Preferences.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 61 | 62 | 72 | -------------------------------------------------------------------------------- /src/lib/languages.ts: -------------------------------------------------------------------------------- 1 | const languages = [ 2 | { text: 'Markdown', value: 'markdown' }, 3 | { text: 'Plain Text', value: 'text' }, 4 | { text: 'YAML', value: 'yaml' }, 5 | { text: 'Batch', value: 'bat' }, 6 | { text: 'HTML', value: 'html' }, 7 | { text: 'XML', value: 'xml' }, 8 | { text: 'Dockerfile', value: 'dockerfile' }, 9 | { text: 'Javascript', value: 'javascript' }, 10 | { text: 'TypeScript', value: 'typescript' }, 11 | { text: 'Ruby', value: 'ruby' }, 12 | { text: 'Go', value: 'go' }, 13 | { text: 'CSS', value: 'css' }, 14 | { text: 'LESS', value: 'less' }, 15 | { text: 'SCSS', value: 'scss' }, 16 | { text: 'Solidity', value: 'solidity' }, 17 | { text: 'MySQL', value: 'mysql' }, 18 | { text: 'pgSQL', value: 'pgsql' }, 19 | { text: 'PHP', value: 'php' }, 20 | { text: 'PowerShell', value: 'powershell' }, 21 | ] 22 | 23 | export default languages 24 | -------------------------------------------------------------------------------- /src/lib/theme/dark-grad.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor' 2 | 3 | monaco.editor.defineTheme('dark-grad', { 4 | base: 'vs-dark', 5 | inherit: true, 6 | rules: [], 7 | colors: { 8 | 'editorGutter.background': '#333', 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /src/lib/theme/dark.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor' 2 | 3 | monaco.editor.defineTheme('dark', { 4 | base: 'vs-dark', 5 | inherit: true, 6 | rules: [], 7 | colors: { 8 | 'editorGutter.background': '#333', 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /src/lib/theme/light-grad.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor' 2 | 3 | monaco.editor.defineTheme('light-grad', { 4 | base: 'vs', 5 | inherit: true, 6 | rules: [], 7 | colors: { 8 | 'editorGutter.background': '#ddd', 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /src/lib/theme/light.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor' 2 | 3 | monaco.editor.defineTheme('light', { 4 | base: 'vs', 5 | inherit: true, 6 | rules: [], 7 | colors: { 8 | 'editorGutter.background': '#ddd', 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /src/lib/theme/themes.ts: -------------------------------------------------------------------------------- 1 | const themes = [ 2 | { text: 'VSCode', value: 'vscode' }, 3 | { text: 'Dark Gradient', value: 'dark-grad' }, 4 | { text: 'Light Gradient', value: 'light-grad' }, 5 | { text: 'Dark', value: 'dark' }, 6 | { text: 'Light', value: 'light' }, 7 | ] 8 | 9 | export default themes 10 | -------------------------------------------------------------------------------- /src/lib/theme/vscode.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor' 2 | 3 | monaco.editor.defineTheme('vscode', { 4 | base: 'vs-dark', 5 | inherit: true, 6 | rules: [], 7 | colors: { 8 | 'editorGutter.background': '#333', 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import store from './store' 4 | 5 | Vue.config.productionTip = false 6 | 7 | store.load() 8 | 9 | Vue.mixin({ 10 | data() { 11 | return { 12 | sharedState: store.state, 13 | } 14 | }, 15 | }) 16 | 17 | Vue.sharedState = store.state 18 | 19 | new Vue({ 20 | render: h => h(App), 21 | }).$mount('#app') 22 | 23 | declare module 'vue/types/vue' { 24 | interface Vue { 25 | sharedState: typeof store.state 26 | } 27 | 28 | interface VueConstructor { 29 | sharedState: typeof store.state 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/shims-monaco-vim.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'monaco-vim' { 2 | import * as monaco from 'monaco-editor' 3 | export function initVimMode(editor: monaco.editor.IStandaloneCodeEditor, statusbarNode?: HTMLElement | null, StatusBarClass?: any): any; 4 | } -------------------------------------------------------------------------------- /src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /src/store.ts: -------------------------------------------------------------------------------- 1 | function get(key: string, defaultValue: T): T 2 | function get(key: string): T | undefined 3 | function get(key: string, defaultValue?: T): T | undefined { 4 | try { 5 | const item = localStorage.getItem(key) 6 | if (item) { 7 | return JSON.parse(item) 8 | } else { 9 | return defaultValue 10 | } 11 | } catch (err) { 12 | return defaultValue 13 | } 14 | } 15 | 16 | function set(key: string, value: any) { 17 | localStorage.setItem(key, JSON.stringify(value)) 18 | } 19 | 20 | export interface SharedState { 21 | theme: string 22 | vimModeEnabled: boolean 23 | showPreferences: boolean 24 | } 25 | 26 | const state: SharedState = { 27 | theme: 'dark-grad', 28 | vimModeEnabled: false, 29 | showPreferences: false, 30 | } 31 | 32 | export default { 33 | state, 34 | 35 | load() { 36 | state.theme = get('theme', state.theme) 37 | state.vimModeEnabled = get('vimModeEnabled', state.vimModeEnabled) 38 | }, 39 | 40 | commit( 41 | key: K, 42 | value: SharedState[K], 43 | persist: boolean = false 44 | ) { 45 | if (persist) { 46 | set(key, value) 47 | } 48 | 49 | state[key] = value 50 | }, 51 | } 52 | -------------------------------------------------------------------------------- /src/updator.ts: -------------------------------------------------------------------------------- 1 | import { app, autoUpdater, dialog } from 'electron' 2 | 3 | const isProduction = process.env.NODE_ENV === 'production' 4 | 5 | if (isProduction) { 6 | autoUpdater.on('error', err => console.log(err)) 7 | autoUpdater.on('checking-for-update', () => 8 | console.log('checking-for-update') 9 | ) 10 | autoUpdater.on('update-available', () => console.log('update-available')) 11 | autoUpdater.on('update-not-available', () => 12 | console.log('update-not-available') 13 | ) 14 | 15 | autoUpdater.on('update-downloaded', () => { 16 | console.log('update-downloaded') 17 | const dialogIndex = dialog.showMessageBox({ 18 | message: 'アップデートあり', 19 | detail: '再起動してインストールできます。', 20 | buttons: ['再起動', '後で'], 21 | }) 22 | if (dialogIndex === 0) { 23 | autoUpdater.quitAndInstall() 24 | } 25 | }) 26 | 27 | const server = 'https://hazel-server-xxghwkeqyz.now.sh' 28 | const feed = `${server}/update/${process.platform}/${app.getVersion()}` 29 | autoUpdater.setFeedURL({ url: feed }) 30 | autoUpdater.checkForUpdates() 31 | } 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "types": [ 15 | "webpack-env" 16 | ], 17 | "paths": { 18 | "@/*": [ 19 | "src/*" 20 | ] 21 | }, 22 | "lib": [ 23 | "esnext", 24 | "dom", 25 | "dom.iterable", 26 | "scripthost" 27 | ] 28 | }, 29 | "include": [ 30 | "src/**/*.ts", 31 | "src/**/*.tsx", 32 | "src/**/*.vue", 33 | "tests/**/*.ts", 34 | "tests/**/*.tsx" 35 | ], 36 | "exclude": [ 37 | "node_modules" 38 | ] 39 | } 40 | --------------------------------------------------------------------------------