From 3f00dba93746eba69beb3b72daefcf07c59ad49b Mon Sep 17 00:00:00 2001 From: Jiiks Date: Tue, 7 Aug 2018 12:48:50 +0300 Subject: [PATCH] Devtool modules --- .gitignore | 1 + client/src/builtin/BuiltinModule.js | 36 +++++++++++++ client/src/builtin/ReactDevtoolsModule.js | 51 +++++++++++++++++++ client/src/builtin/VueDevToolsModule.js | 51 +++++++++++++++++++ client/src/builtin/builtin.js | 2 + client/src/data/user.settings.default.json | 14 +++++ client/src/index.js | 4 +- .../ext/plugins/Doubleclick Edit/config.json | 17 +++++++ tests/ext/plugins/Doubleclick Edit/index.js | 27 ++++++++++ 9 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 client/src/builtin/BuiltinModule.js create mode 100644 client/src/builtin/ReactDevtoolsModule.js create mode 100644 client/src/builtin/VueDevToolsModule.js create mode 100644 tests/ext/plugins/Doubleclick Edit/config.json create mode 100644 tests/ext/plugins/Doubleclick Edit/index.js diff --git a/.gitignore b/.gitignore index 19c52db0..b7f2ac85 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ tests/data user.config.json /.vs /npm-debug.log +/tests/ext/extensions diff --git a/client/src/builtin/BuiltinModule.js b/client/src/builtin/BuiltinModule.js new file mode 100644 index 00000000..297d6895 --- /dev/null +++ b/client/src/builtin/BuiltinModule.js @@ -0,0 +1,36 @@ +/** + * BetterDiscord Builtin Module Base + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import { Settings } from 'modules'; + +export default class BuiltinModule { + + constructor() { + this._settingUpdated = this._settingUpdated.bind(this); + if (this.enabled) this.enabled = this.enabled.bind(this); + if (this.disabled) this.disabled = this.disabled.bind(this); + } + + init() { + this.setting.on('setting-updated', this._settingUpdated); + if (this.setting.value && this.enabled) this.enabled(); + } + + get setting() { + return Settings.getSetting(...this.settingPath); + } + + _settingUpdated(e) { + const { value } = e; + if (value === true && this.enabled) this.enabled(e); + if (value === false && this.disabled) this.disabled(e); + } + +} diff --git a/client/src/builtin/ReactDevtoolsModule.js b/client/src/builtin/ReactDevtoolsModule.js new file mode 100644 index 00000000..fc3558f8 --- /dev/null +++ b/client/src/builtin/ReactDevtoolsModule.js @@ -0,0 +1,51 @@ +/** + * BetterDiscord React Devtools Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import electron from 'electron'; +import path from 'path'; + +import BuiltinModule from './BuiltinModule'; + +import { Globals } from 'modules'; +import { Toasts } from 'ui'; + +export default new class ReactDevtoolsModule extends BuiltinModule { + + constructor() { + super(); + this.devToolsOpened = this.devToolsOpened.bind(this); + } + + get settingPath() { + return ['core', 'advanced', 'react-devtools']; + } + + enabled(e) { + electron.remote.BrowserWindow.getAllWindows()[0].webContents.on('devtools-opened', this.devToolsOpened); + } + + disabled(e) { + electron.remote.BrowserWindow.removeDevToolsExtension('React Developer Tools'); + electron.remote.BrowserWindow.getAllWindows()[0].webContents.on('devtools-opened', this.devToolsOpened); + } + + devToolsOpened() { + electron.remote.BrowserWindow.removeDevToolsExtension('React Developer Tools'); + electron.webFrame.registerURLSchemeAsPrivileged('chrome-extension'); + const v = electron.remote.BrowserWindow.addDevToolsExtension(path.resolve(Globals.getPath('ext'), 'extensions', 'rdt')); + if (v !== undefined) { + Toasts.success(v + ' Installed'); + return; + } else { + Toasts.error('React Developer Tools install failed'); + } + + } +} diff --git a/client/src/builtin/VueDevToolsModule.js b/client/src/builtin/VueDevToolsModule.js new file mode 100644 index 00000000..9a23c24f --- /dev/null +++ b/client/src/builtin/VueDevToolsModule.js @@ -0,0 +1,51 @@ +/** + * BetterDiscord Vue Devtools Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import electron from 'electron'; +import path from 'path'; + +import BuiltinModule from './BuiltinModule'; + +import { Globals } from 'modules'; +import { Toasts } from 'ui'; + +export default new class VueDevtoolsModule extends BuiltinModule { + + constructor() { + super(); + this.devToolsOpened = this.devToolsOpened.bind(this); + } + + get settingPath() { + return ['core', 'advanced', 'vue-devtools']; + } + + enabled(e) { + electron.remote.BrowserWindow.getAllWindows()[0].webContents.on('devtools-opened', this.devToolsOpened); + } + + disabled(e) { + electron.remote.BrowserWindow.removeDevToolsExtension('Vue.js devtools'); + electron.remote.BrowserWindow.getAllWindows()[0].webContents.on('devtools-opened', this.devToolsOpened); + } + + devToolsOpened() { + electron.remote.BrowserWindow.removeDevToolsExtension('Vue.js devtools'); + electron.webFrame.registerURLSchemeAsPrivileged('chrome-extension'); + const v = electron.remote.BrowserWindow.addDevToolsExtension(path.resolve(Globals.getPath('ext'), 'extensions', 'vdt')); + if (v !== undefined) { + Toasts.success(v + ' Installed'); + return; + } else { + Toasts.error('Vue.js devtools install failed'); + } + + } +} diff --git a/client/src/builtin/builtin.js b/client/src/builtin/builtin.js index a6ecf8d7..7bc3287a 100644 --- a/client/src/builtin/builtin.js +++ b/client/src/builtin/builtin.js @@ -1 +1,3 @@ export { default as EmoteModule } from './EmoteModule'; +export { default as ReactDevtoolsModule } from './ReactDevtoolsModule'; +export { default as VueDevtoolsModule } from './VueDevToolsModule'; diff --git a/client/src/data/user.settings.default.json b/client/src/data/user.settings.default.json index cfe23ae5..58a1226a 100644 --- a/client/src/data/user.settings.default.json +++ b/client/src/data/user.settings.default.json @@ -63,6 +63,20 @@ "text": "Ignore content manager errors", "hint": "Only when starting Discord. It gets annoying when you're reloading Discord often and have plugins that are meant to fail.", "value": false + }, + { + "id": "react-devtools", + "type": "bool", + "text": "React Developer Tools", + "hint": "Enable/Disable React developer tools", + "value": false + }, + { + "id": "vue-devtools", + "type": "bool", + "text": "Vue Developer Tools", + "hint": "Enable/Disable Vue developer tools", + "value": false } ] }, diff --git a/client/src/index.js b/client/src/index.js index faab97ae..df0b60e6 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -12,7 +12,7 @@ import { DOM, BdUI, BdMenu, Modals, Reflection, Toasts } from 'ui'; import BdCss from './styles/index.scss'; import { Events, CssEditor, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, WebpackModules, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity } from 'modules'; import { ClientLogger as Logger, ClientIPC, Utils } from 'common'; -import { EmoteModule } from 'builtin'; +import { EmoteModule, ReactDevtoolsModule, VueDevtoolsModule } from 'builtin'; import electron from 'electron'; import path from 'path'; @@ -73,6 +73,8 @@ class BetterDiscord { async init() { try { + ReactDevtoolsModule.init(); + VueDevtoolsModule.init(); await Database.init(); await Settings.loadSettings(); await ModuleManager.initModules(); diff --git a/tests/ext/plugins/Doubleclick Edit/config.json b/tests/ext/plugins/Doubleclick Edit/config.json new file mode 100644 index 00000000..c6bfa681 --- /dev/null +++ b/tests/ext/plugins/Doubleclick Edit/config.json @@ -0,0 +1,17 @@ +{ + "info": { + "id": "doubleclick-edit", + "name": "Doubleclick Edit", + "authors": [ + { + "name": "Jiiks", + "discord_id": "81388395867156480", + "github_username": "Jiiks", + "twitter_username": "Jiiksi" + } + ], + "version": 1.0, + "description": "Edit messages by double clicking them. This is a v1 fix" + }, + "main": "index.js" +} diff --git a/tests/ext/plugins/Doubleclick Edit/index.js b/tests/ext/plugins/Doubleclick Edit/index.js new file mode 100644 index 00000000..8766c249 --- /dev/null +++ b/tests/ext/plugins/Doubleclick Edit/index.js @@ -0,0 +1,27 @@ +module.exports = (Plugin, Api, Vendor) => { + + return class extends Plugin { + onStart() { + document.addEventListener('dblclick', this.handler); + return true; + } + + onStop() { + document.removeEventListener('dblclick', this.handler); + return true; + } + + handler(e) { + const message = e.target.closest('[class^=messageCozy]') || e.target.closest('[class^=messageCompact]'); + if (!message) return; + const btn = message.querySelector('[class^=buttonContainer] [class^=button-]'); + if (!btn) return; + btn.click(); + const popup = document.querySelector('[class^=container][role=menu]'); + if (!popup) return; + const rii = popup[Object.keys(popup).find(k => k.startsWith('__reactInternal'))]; + if (!rii || !rii.memoizedProps || !rii.memoizedProps.children || !rii.memoizedProps.children[1] || !rii.memoizedProps.children[1].props || !rii.memoizedProps.children[1].props.onClick) return; + rii.memoizedProps.children[1].props.onClick(); + } + } +}