-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[4.1] Keyboard Shortcuts Plugin Setup #7
[4.1] Keyboard Shortcuts Plugin Setup #7
Conversation
console.log(e); | ||
// On Press CTRL + S | ||
if ( | ||
(window.navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(window.navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)
Common code put in common place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update it. Thank you
@Krshivam25 List all the shortcuts and keymap you are going to implement here |
|
I will try to implement in a smart way like: You know everything going to have similar info like:
So, why not make a common function which will automatically map register all the events; LIke: // Optional callback function From database you going to have a mapping like:
a list of mapping
|
@Krshivam25 I will suggest you implement the Inject your function to the global window object of
The function should take the following properties like
Every time you will run It will maintain event data in global window object or somewhere else data structure This will help other third-party developers to use this API in their extensions directly I guess this is enough information |
|
||
// Then map shortcuts | ||
window.Joomla.shortcutsEvent.map(( {actionButton, selector} ) => { | ||
let splitArr = actionButton.split(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actionButton.split();
-> actionButton.split('+');
2 things which are needed for the plugin Add the needed SQL Statements to the update scripts at https://github.com/joomla-projects/gsoc21_accessibility/tree/4.1-dev/administrator/components/com_admin/sql/updates And the needed SQL Statements for the installation sql scripts https://github.com/joomla-projects/gsoc21_accessibility/tree/4.1-dev/installation/sql |
Co-authored-by: Harald Leithner <[email protected]>
Please rename the js file to '.es6.js' and make sure you read the read me file in the build directory (you are skipping cs amongst other things) |
For reference you might find a previous attempt at this plugin useful joomla/joomla-cms#24152 |
Also for reference and my experience creating joomla/joomla-cms#24152 the hotkeys you have chosen will not work with firefox as they are already being used |
Some more help here:
class JoomlaShortcuts {
constructor() {
if (!Joomla) {
throw new Error('Joomla API is not properly initialised');
}
const defaultOptions = {
apply: {
keyEvent: 'meta+alt+s',
selector: 'joomla-toolbar-button button.button-apply'
},
new :{
keyEvent: 'meta+alt+n',
selector: 'joomla-toolbar-button button.button-new'
},
save :{
keyEvent: 'meta+alt+w',
selector: 'joomla-toolbar-button button.button-save'
},
saveNew: {
keyEvent: 'meta+shift+alt+w',
selector: 'joomla-toolbar-button button.button-save-new'
},
help :{
keyEvent: 'meta+alt+h',
selector: 'joomla-toolbar-button button.button-help'
},
cancel :{
keyEvent: 'meta+alt+q',
selector: 'joomla-toolbar-button button.button-cancel'
},
copy: {
keyEvent: 'meta+shift+alt+c',
selector: 'joomla-toolbar-button button.button-button-copy'
}
};
const phpOptions = Joomla.getOptions('joomla-shortcut-keys', {});
let options;
try {
options = JSON.parse(phpOptions);
if (options === false) {
options = [];
}
} catch (e) {
options = [];
}
this.options = [ ...defaultOptions, ...options ];
// Bindings
this.execCommand = this.execCommand.bind(this);
this.handleKeyPressEvent = this.handleKeyPressEvent.bind(this);
document.addEventListener('keydown', this.handleKeyPressEvent, false);
try {
tinyMCE.activeEditor.on('keydown', function (e) {
handleKeyPressEvent(e);
});
} catch (e) {}
}
execCommand(event, selector, prevent) {
let actionBtn = document.querySelector(selector);
if (actionBtn) {
if (prevent) {
event.preventDefault();
}
actionBtn.click();
}
}
handleKeyPressEvent(e) {
this.options.map(({ actionButton, selector }) => {
let splitArr = actionButton.split('+');
// meta+shift+alt+c => [meta, shift, alt, c]
let lastKey = actionButton.charAt(actionButton.length -1);
if (e.key.toLowerCase() == lastKey) {
this.execCommand(e, selector);
}
});
if (navigator.platform.match('Mac') ? e.metaKey : e.altKey) {
// On Press ALT + S
let keyChar = e.key.toLowerCase();
Object.values(this.options).map((option) => {
if (keyChar === option.keyEvent.slice(-1))
this.execCommand(e, option.selector);
});
}
}
}
new JoomlaShortcuts(); |
BTW from an architecture point of view I would introduce a new PHP event fired on the toolbar button rendering stage and tight the plugin to that event. The point is that the key events will essentially execute the same logic of that button so things are getting simpler also on the PHP side (you cannot |
@Krshivam25 can you sync this to the 4.1-dev branch please then drone should hopefully work |
@dgrammatiko Hi, glad you are here :) We need some help in javascript approach |
Please review and fix all the code style issues reported by drone. |
I activated our CI system for this repo yesterday, you know have the checks at the bottom with a link to the result. for example here: https://ci.joomla.org/joomla-projects/gsoc21_accessibility/9/1/6 please check the phpcs part and fix all errors reported. thanks |
@Krshivam25 may I give you some clear steps here to help you finish your task sooner?
{
apply: {
keyEvent: 'meta+alt+s',
selector: 'joomla-toolbar-button button.button-apply'
},
new :{
keyEvent: 'meta+alt+n',
selector: 'joomla-toolbar-button button.button-new'
},
save :{
keyEvent: 'meta+alt+w',
selector: 'joomla-toolbar-button button.button-save'
},
saveNew: {
keyEvent: 'meta+shift+alt+w',
selector: 'joomla-toolbar-button button.button-save-new'
},
help :{
keyEvent: 'meta+alt+h',
selector: 'joomla-toolbar-button button.button-help'
},
cancel :{
keyEvent: 'meta+alt+q',
selector: 'joomla-toolbar-button button.button-cancel'
},
copy: {
keyEvent: 'meta+shift+alt+c',
selector: 'joomla-toolbar-button button.button-button-copy'
}
}
Hope this gives you a better guideline |
Instead of setting in the PHP pass the data from PHP to client-side using the API. This what it means right? @dgrammatiko |
@Krshivam25 please read my comment #7 (comment) the first 3 bullets explain how you can pass data from PHP to JS. You have to familiarise yourself with this concept in order to control the behaviour of the javascript without hardcoding things. |
Added $document->addScriptOptions() created a data structure for all the keyboard-shortcuts
@Krshivam25 You correctly pass the data from PHP to JS Since you are defining the object I would suggest you to be more verbatim, eg [
'button_apply' => [
'keyEvent' => 'meta+alt+s',
'selector' => 'joomla-toolbar-button button.button-apply'
]
] you can be more specific: [
'button_apply' => [
'keyEvent' => 's',
'hasMeta' => true,
'hasAlt' => true,
'hasShift' => false,
'selector' => 'joomla-toolbar-button button.button-apply'
]
] This way in your JS you can simply check against the object instead of splitting the string to discover the possible states of alt,meta,shift. |
OK some more help: Factory::getDocument()->addScriptOptions(
'joomla-shortcut-keys',
[
'button_apply' => [
'keyEvent' => 's',
'hasShift' => false,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-apply'
],
'button_new' => [
'keyEvent' => 'n',
'hasShift' => false,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-new'
],
'button_save' => [
'keyEvent' => 'w',
'hasShift' => false,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-save'
],
'button_saveNew' => [
'keyEvent' => 'w',
'hasShift' => true,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-save-new'
],
'button_help' => [
'keyEvent' => 'x',
'hasShift' => false,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-help'
],
'button_cancel' => [
'keyEvent' => 'q',
'hasShift' => false,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-cancel'
],
'button_copy' => [
'keyEvent' => 'c',
'hasShift' => true,
'hasAlt' => true,
'hasControl' => true,
'selector' => 'joomla-toolbar-button button.button-button-copy'
]
]
); And this in the JS: class JoomlaShortcuts {
constructor() {
if (!Joomla) {
throw new Error('Joomla API is not properly initialised');
}
const phpOptions = Joomla.getOptions('joomla-shortcut-keys', {});
if (!Object.keys(phpOptions).length) {
return;
}
this.options = phpOptions;
// Toolbar buttons are Custom Element Childs, so we have to wait for them to initialize
customElements.whenDefined('joomla-toolbar-button').then(
Object.values(this.options).map((option) => {
option.element = document.querySelector(option.selector);
})
);
// Bindings
this.execCommand = this.execCommand.bind(this);
this.handleKeyPressEvent = this.handleKeyPressEvent.bind(this);
document.addEventListener('keypress', this.handleKeyPressEvent, false);
try {
// eslint-disable-next-line
tinyMCE.activeEditor.on('keydown', function (e) {
handleKeyPressEvent(e);
});
} catch (e) {}
}
execCommand(event, element, prevent) {
if (prevent) {
event.preventDefault();
}
element.click();
}
handleKeyPressEvent(e) {
Object.values(this.options).map((option) => {
if (
option.keyEvent=== e.key.toLowerCase()
&& option.hasShift === e.shiftKey
&& option.hasControl === e.ctrlKey
&& option.hasAlt === (e.metaKey || e.altKey) ? true : false
&& option.element
) {
this.execCommand(e, option.element);
}
});
}
}
new JoomlaShortcuts(); You still have to enable keys per each toolbar button |
|
||
if ($this->app->isClient('administrator')) | ||
{ | ||
$wa = $this->app->getDocument()->getWebAssetManager(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you really need to study the Web Assets: https://docs.joomla.org/J4.x:Web_Assets
$this->app->getDocument()->addScriptOptions('system-shortcut', $shortcut);
$this->app->getDocument()->getWebAssetManager()->registerAndUseScript('shortcut', 'plg_system_shortcut/shortcut.js', [], ['type' => 'module'], ['core']);
The purpose of this PR is to commit all the changes and commits made. Admin and Mentors can review the changes and provide their valuable feedback.
Documents: https://docs.google.com/document/d/1a2GtsQA-iqAkJcjt5zupyEbJBDBvHfv-kz96L2lZ2_w/edit?usp=sharing
Result After PR: All the features get enabled with keyboard via keyboard shortcuts.
Example: Buttons can be operated with keyboard shortcuts.
Temporary File for Shortcuts Suggestion: https://docs.google.com/document/d/1l-ypFwa_c9Se-jDKZLs0ncK1PRcMPXfJI9i0Uc2Nebw/edit?usp=sharing
Main components to develop :
screen-capture.5.mp4
Summary of changes: