first commit

This commit is contained in:
2025-06-17 11:53:18 +02:00
commit 9f0f7ba12b
8804 changed files with 1369176 additions and 0 deletions

View File

@ -0,0 +1,156 @@
((document, Joomla) => {
if (!Joomla) {
throw new Error('Joomla API is not properly initialised');
}
/* global hotkeys */
Joomla.addShortcut = (hotkey, callback) => {
hotkeys(hotkey, 'joomla', event => {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
callback.call();
});
};
Joomla.addClickShortcut = (hotkey, selector) => {
Joomla.addShortcut(hotkey, () => {
const element = document.querySelector(selector);
if (element) {
element.click();
}
});
};
Joomla.addFocusShortcut = (hotkey, selector) => {
Joomla.addShortcut(hotkey, () => {
const element = document.querySelector(selector);
if (element) {
element.focus();
}
});
};
Joomla.addLinkShortcut = (hotkey, selector) => {
Joomla.addShortcut(hotkey, () => {
window.location.href = selector;
});
};
const setShortcutFilter = () => {
hotkeys.filter = event => {
const target = event.target || event.srcElement;
const {
tagName
} = target;
// Checkboxes should not block a shortcut event
if (target.type === 'checkbox') {
return true;
}
// Default hotkeys filter behavior
return !(target.isContentEditable || tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA');
};
};
const startupShortcuts = () => {
hotkeys('J', event => {
// If we're already in the scope, it's a normal shortkey
if (hotkeys.getScope() === 'joomla') {
return;
}
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
hotkeys.setScope('joomla');
// Leave the scope after x milliseconds
setTimeout(() => {
hotkeys.setScope(false);
}, Joomla.getOptions('plg_system_shortcut.timeout', 2000));
});
};
const addOverviewHint = () => {
const mainContainer = document.querySelector('.com_cpanel .container-main');
if (mainContainer) {
const containerElement = document.createElement('section');
containerElement.className = 'content pt-4';
containerElement.insertAdjacentHTML('beforeend', Joomla.Text._('PLG_SYSTEM_SHORTCUT_OVERVIEW_HINT'));
mainContainer.appendChild(containerElement);
}
};
const initOverviewModal = options => {
const dlItems = new Map();
Object.values(options).forEach(value => {
if (!value.shortcut || !value.title) {
return;
}
let titles = [];
if (dlItems.has(value.shortcut)) {
titles = dlItems.get(value.shortcut);
titles.push(value.title);
} else {
titles = [value.title];
}
dlItems.set(value.shortcut, titles);
});
let dl = '<dl>';
dlItems.forEach((titles, shortcut) => {
dl += '<div>';
dl += '<dt class="d-inline-block"><kbd>J</kbd>';
shortcut.split('+').forEach(key => {
dl += ` ${Joomla.Text._('PLG_SYSTEM_SHORTCUT_THEN')} <kbd>${key.trim()}</kbd>`;
});
dl += '</dt>';
titles.forEach(title => {
dl += `<dd class="d-inline-block ms-1">${title}</dd>`;
});
dl += '</div>';
});
dl += '</dl>';
const modal = `
<div class="modal fade" id="shortcutOverviewModal" tabindex="-1" role="dialog" data-bs-backdrop="static" aria-labelledby="shortcutOverviewModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 id="shortcutOverviewModalLabel" class="modal-title">
${Joomla.Text._('PLG_SYSTEM_SHORTCUT_OVERVIEW_TITLE')}
</h3>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="${Joomla.Text._('JCLOSE')}"></button>
</div>
<div class="modal-body p-3">
<p>${Joomla.Text._('PLG_SYSTEM_SHORTCUT_OVERVIEW_DESC')}</p>
<div class="mb-3">
${dl}
</div>
</div>
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modal);
const bootstrapModal = new bootstrap.Modal(document.getElementById('shortcutOverviewModal'), {
keyboard: true,
backdrop: true
});
hotkeys('X', 'joomla', () => bootstrapModal.show());
};
document.addEventListener('DOMContentLoaded', () => {
const options = Joomla.getOptions('plg_system_shortcut.shortcuts');
Object.values(options).forEach(value => {
if (!value.shortcut || !value.selector) {
return;
}
if (value.selector.startsWith('/') || value.selector.startsWith('http://') || value.selector.startsWith('www.')) {
Joomla.addLinkShortcut(value.shortcut, value.selector);
} else if (value.selector.includes('input')) {
Joomla.addFocusShortcut(value.shortcut, value.selector);
} else {
Joomla.addClickShortcut(value.shortcut, value.selector);
}
});
// Show hint and overview on logged in backend only (not login page)
if (document.querySelector('nav')) {
initOverviewModal(options);
addOverviewHint();
}
setShortcutFilter();
startupShortcuts();
});
})(document, Joomla);

View File

@ -0,0 +1 @@
((t,e)=>{if(!e)throw new Error("Joomla API is not properly initialised");e.addShortcut=(t,e)=>{hotkeys(t,"joomla",(t=>{t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),e.call()}))},e.addClickShortcut=(o,s)=>{e.addShortcut(o,(()=>{const e=t.querySelector(s);e&&e.click()}))},e.addFocusShortcut=(o,s)=>{e.addShortcut(o,(()=>{const e=t.querySelector(s);e&&e.focus()}))},e.addLinkShortcut=(t,o)=>{e.addShortcut(t,(()=>{window.location.href=o}))};t.addEventListener("DOMContentLoaded",(()=>{const o=e.getOptions("plg_system_shortcut.shortcuts");Object.values(o).forEach((t=>{t.shortcut&&t.selector&&(t.selector.startsWith("/")||t.selector.startsWith("http://")||t.selector.startsWith("www.")?e.addLinkShortcut(t.shortcut,t.selector):t.selector.includes("input")?e.addFocusShortcut(t.shortcut,t.selector):e.addClickShortcut(t.shortcut,t.selector))})),t.querySelector("nav")&&((o=>{const s=new Map;Object.values(o).forEach((t=>{if(!t.shortcut||!t.title)return;let e=[];s.has(t.shortcut)?(e=s.get(t.shortcut),e.push(t.title)):e=[t.title],s.set(t.shortcut,e)}));let a="<dl>";s.forEach(((t,o)=>{a+="<div>",a+='<dt class="d-inline-block"><kbd>J</kbd>',o.split("+").forEach((t=>{a+=` ${e.Text._("PLG_SYSTEM_SHORTCUT_THEN")} <kbd>${t.trim()}</kbd>`})),a+="</dt>",t.forEach((t=>{a+=`<dd class="d-inline-block ms-1">${t}</dd>`})),a+="</div>"})),a+="</dl>";const c=`\n <div class="modal fade" id="shortcutOverviewModal" tabindex="-1" role="dialog" data-bs-backdrop="static" aria-labelledby="shortcutOverviewModalLabel" aria-hidden="true">\n <div class="modal-dialog" role="document">\n <div class="modal-content">\n <div class="modal-header">\n <h3 id="shortcutOverviewModalLabel" class="modal-title">\n ${e.Text._("PLG_SYSTEM_SHORTCUT_OVERVIEW_TITLE")}\n </h3>\n <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="${e.Text._("JCLOSE")}"></button>\n </div>\n <div class="modal-body p-3">\n <p>${e.Text._("PLG_SYSTEM_SHORTCUT_OVERVIEW_DESC")}</p>\n <div class="mb-3">\n ${a}\n </div>\n </div>\n </div>\n </div>\n </div>\n `;t.body.insertAdjacentHTML("beforeend",c);const d=new bootstrap.Modal(t.getElementById("shortcutOverviewModal"),{keyboard:!0,backdrop:!0});hotkeys("X","joomla",(()=>d.show()))})(o),(()=>{const o=t.querySelector(".com_cpanel .container-main");if(o){const s=t.createElement("section");s.className="content pt-4",s.insertAdjacentHTML("beforeend",e.Text._("PLG_SYSTEM_SHORTCUT_OVERVIEW_HINT")),o.appendChild(s)}})()),hotkeys.filter=t=>{const e=t.target||t.srcElement,{tagName:o}=e;return"checkbox"===e.type||!(e.isContentEditable||"INPUT"===o||"SELECT"===o||"TEXTAREA"===o)},hotkeys("J",(t=>{"joomla"!==hotkeys.getScope()&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),hotkeys.setScope("joomla"),setTimeout((()=>{hotkeys.setScope(!1)}),e.getOptions("plg_system_shortcut.timeout",2e3)))}))}))})(document,Joomla);

Binary file not shown.