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,71 @@
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "com_modules",
"version": "4.0.0",
"description": "Joomla CMS",
"license": "GPL-2.0-or-later",
"assets": [
{
"name": "com_modules.admin-module-edit-assignment",
"type": "script",
"uri": "com_modules/admin-module-edit_assignment.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
},
"version": "46aaab"
},
{
"name": "com_modules.admin-module-edit",
"type": "script",
"uri": "com_modules/admin-module-edit.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
},
"version": "ec6c86"
},
{
"name": "com_modules.admin-module-search",
"type": "script",
"uri": "com_modules/admin-module-search.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
},
"version": "3fa723"
},
{
"name": "com_modules.admin-modules-modal",
"type": "script",
"uri": "com_modules/admin-modules-modal.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
},
"deprecated": true,
"deprecatedMsg": "Use postMessage() directly or with help of [modal-content-select] asset. To post the modal selection.",
"version": "b32f29"
},
{
"name": "com_modules.admin-select-modal",
"type": "script",
"uri": "com_modules/admin-select-modal.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
},
"version": "a917b8"
}
]
}

View File

@ -0,0 +1,120 @@
/**
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
Joomla = window.Joomla || {};
(Joomla => {
Joomla.submitbutton = task => {
if (task === 'module.cancel' || document.formvalidator.isValid(document.getElementById('module-form'))) {
Joomla.submitform(task, document.getElementById('module-form'));
const options = Joomla.getOptions('module-edit');
if (window.self !== window.top) {
if (window.parent.viewLevels) {
const updPosition = document.getElementById('jform_position').value;
const updTitle = document.getElementById('jform_title').value;
const updMenus = document.querySelector('#jform_assignment').value;
const updStatus = document.querySelector('#jform_published').value;
const updAccess = document.querySelector('#jform_access').value;
const tmpMenu = window.parent.document.getElementById(`menus-${options.itemId}`);
const tmpRow = window.parent.document.getElementById(`tr-${options.itemId}`);
const tmpStatus = window.parent.document.getElementById(`status-${options.itemId}`);
window.parent.inMenus = [];
window.parent.numMenus = [].slice.call(document.querySelectorAll('input[name="jform[assigned][]"]')).length;
[].slice.call(document.querySelectorAll('input[name="jform[assigned][]"]')).forEach(element => {
if (updMenus > 0) {
if (element.checked) {
window.parent.inMenus.push(parseInt(element.value, 10));
}
}
if (updMenus < 0) {
if (!element.checked) {
window.parent.inMenus.push(parseInt(element.value, 10));
}
}
});
if (updMenus === '-') {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-danger">${Joomla.Text._('JNO')}</span>`);
if (!tmpRow.classList.contains('no') || tmpRow.classList.length === 0) {
tmpRow.classList.add('no');
}
}
if (parseInt(updMenus, 10) === 0) {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-info">${Joomla.Text._('JALL')}</span>`);
if (tmpRow.classList.contains('no')) {
tmpRow.classList.remove('no');
}
}
if (parseInt(updMenus, 10) > 0) {
if (window.parent.inMenus.indexOf(window.parent.menuId) >= 0) {
if (window.parent.numMenus === window.parent.inMenus.length) {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-info">${Joomla.Text._('JALL')}</span>`);
if (tmpRow.classList.contains('no') || tmpRow.classList.length === 0) {
tmpRow.classList.remove('no');
}
} else {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-success">${Joomla.Text._('JYES')}</span>`);
if (tmpRow.classList.contains('no')) {
tmpRow.classList.remove('no');
}
}
}
if (window.parent.inMenus.indexOf(window.parent.menuId) < 0) {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-danger">${Joomla.Text._('JNO')}</span>`);
if (!tmpRow.classList.contains('no')) {
tmpRow.classList.add('no');
}
}
}
if (parseInt(updMenus, 10) < 0) {
if (window.parent.inMenus.indexOf(window.parent.menuId) >= 0) {
if (window.parent.numMenus === window.parent.inMenus.length) {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-info">${Joomla.Text._('JALL')}</span>`);
if (tmpRow.classList.contains('no')) {
tmpRow.classList.remove('no');
}
} else {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-success">${Joomla.Text._('JYES')}</span>`);
if (tmpRow.classList.contains('no')) {
tmpRow.classList.remove('no');
}
}
}
if (window.parent.inMenus.indexOf(window.parent.menuId) < 0) {
tmpMenu.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-danger">${Joomla.Text._('JNO')}</span>`);
if (!tmpRow.classList.contains('no') || tmpRow.classList.length === 0) {
tmpRow.classList.add('no');
}
}
}
if (parseInt(updStatus, 10) === 1) {
tmpStatus.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-success">${Joomla.Text._('JYES')}</span>`);
if (tmpRow.classList.contains('unpublished')) {
tmpRow.classList.remove('unpublished');
}
}
if (parseInt(updStatus, 10) === 0) {
tmpStatus.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-danger">${Joomla.Text._('JNO')}</span>`);
if (!tmpRow.classList.contains('unpublished') || tmpRow.classList.length === 0) {
tmpRow.classList.add('unpublished');
}
}
if (parseInt(updStatus, 10) === -2) {
tmpStatus.innerHTML = Joomla.sanitizeHtml(`<span class="badge bg-secondary">${Joomla.Text._('JTRASHED')}</span>`);
if (!tmpRow.classList.contains('unpublished') || tmpRow.classList.length === 0) {
tmpRow.classList.add('unpublished');
}
}
if (document.formvalidator.isValid(document.getElementById('module-form'))) {
window.parent.document.querySelector(`#title-${options.itemId}`).innerText = updTitle;
window.parent.document.querySelector(`#position-${options.itemId}`).innerText = updPosition;
window.parent.document.querySelector(`#access-${options.itemId}`).innerHTML = Joomla.sanitizeHtml(window.parent.viewLevels[updAccess]);
}
}
if (task !== 'module.apply') {
window.parent.Joomla.Modal.getCurrent().close();
}
}
}
};
})(Joomla);

View File

@ -0,0 +1 @@
Joomla=window.Joomla||{},(n=>{n.submitbutton=e=>{if("module.cancel"===e||document.formvalidator.isValid(document.getElementById("module-form"))){n.submitform(e,document.getElementById("module-form"));const s=n.getOptions("module-edit");if(window.self!==window.top){if(window.parent.viewLevels){const e=document.getElementById("jform_position").value,t=document.getElementById("jform_title").value,a=document.querySelector("#jform_assignment").value,i=document.querySelector("#jform_published").value,o=document.querySelector("#jform_access").value,l=window.parent.document.getElementById(`menus-${s.itemId}`),d=window.parent.document.getElementById(`tr-${s.itemId}`),c=window.parent.document.getElementById(`status-${s.itemId}`);window.parent.inMenus=[],window.parent.numMenus=[].slice.call(document.querySelectorAll('input[name="jform[assigned][]"]')).length,[].slice.call(document.querySelectorAll('input[name="jform[assigned][]"]')).forEach((n=>{a>0&&n.checked&&window.parent.inMenus.push(parseInt(n.value,10)),a<0&&(n.checked||window.parent.inMenus.push(parseInt(n.value,10)))})),"-"===a&&(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-danger">${n.Text._("JNO")}</span>`),d.classList.contains("no")&&0!==d.classList.length||d.classList.add("no")),0===parseInt(a,10)&&(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-info">${n.Text._("JALL")}</span>`),d.classList.contains("no")&&d.classList.remove("no")),parseInt(a,10)>0&&(window.parent.inMenus.indexOf(window.parent.menuId)>=0&&(window.parent.numMenus===window.parent.inMenus.length?(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-info">${n.Text._("JALL")}</span>`),(d.classList.contains("no")||0===d.classList.length)&&d.classList.remove("no")):(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-success">${n.Text._("JYES")}</span>`),d.classList.contains("no")&&d.classList.remove("no"))),window.parent.inMenus.indexOf(window.parent.menuId)<0&&(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-danger">${n.Text._("JNO")}</span>`),d.classList.contains("no")||d.classList.add("no"))),parseInt(a,10)<0&&(window.parent.inMenus.indexOf(window.parent.menuId)>=0&&(window.parent.numMenus===window.parent.inMenus.length?(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-info">${n.Text._("JALL")}</span>`),d.classList.contains("no")&&d.classList.remove("no")):(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-success">${n.Text._("JYES")}</span>`),d.classList.contains("no")&&d.classList.remove("no"))),window.parent.inMenus.indexOf(window.parent.menuId)<0&&(l.innerHTML=n.sanitizeHtml(`<span class="badge bg-danger">${n.Text._("JNO")}</span>`),d.classList.contains("no")&&0!==d.classList.length||d.classList.add("no"))),1===parseInt(i,10)&&(c.innerHTML=n.sanitizeHtml(`<span class="badge bg-success">${n.Text._("JYES")}</span>`),d.classList.contains("unpublished")&&d.classList.remove("unpublished")),0===parseInt(i,10)&&(c.innerHTML=n.sanitizeHtml(`<span class="badge bg-danger">${n.Text._("JNO")}</span>`),d.classList.contains("unpublished")&&0!==d.classList.length||d.classList.add("unpublished")),-2===parseInt(i,10)&&(c.innerHTML=n.sanitizeHtml(`<span class="badge bg-secondary">${n.Text._("JTRASHED")}</span>`),d.classList.contains("unpublished")&&0!==d.classList.length||d.classList.add("unpublished")),document.formvalidator.isValid(document.getElementById("module-form"))&&(window.parent.document.querySelector(`#title-${s.itemId}`).innerText=t,window.parent.document.querySelector(`#position-${s.itemId}`).innerText=e,window.parent.document.querySelector(`#access-${s.itemId}`).innerHTML=n.sanitizeHtml(window.parent.viewLevels[o]))}"module.apply"!==e&&window.parent.Joomla.Modal.getCurrent().close()}}}})(Joomla);

Binary file not shown.

View File

@ -0,0 +1,30 @@
/**
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
(() => {
const onChange = value => {
if (value === '-' || parseInt(value, 10) === 0) {
document.getElementById('menuselect-group').classList.add('hidden');
} else {
document.getElementById('menuselect-group').classList.remove('hidden');
}
};
const onBoot = () => {
const element = document.getElementById('jform_assignment');
if (element) {
// Initialise the state
onChange(element.value);
// Check for changes in the state
element.addEventListener('change', ({
target
}) => {
onChange(target.value);
});
}
document.removeEventListener('DOMContentLoaded', onBoot);
};
document.addEventListener('DOMContentLoaded', onBoot);
})();

View File

@ -0,0 +1 @@
(()=>{const e=e=>{"-"===e||0===parseInt(e,10)?document.getElementById("menuselect-group").classList.add("hidden"):document.getElementById("menuselect-group").classList.remove("hidden")},t=()=>{const n=document.getElementById("jform_assignment");n&&(e(n.value),n.addEventListener("change",(({target:t})=>{e(t.value)}))),document.removeEventListener("DOMContentLoaded",t)};document.addEventListener("DOMContentLoaded",t)})();

View File

@ -0,0 +1,103 @@
/**
* @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
/**
* Add a keyboard event listener to the Select a Module Type search element.
*
* IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking
* (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler
* because the browser is guaranteed to execute it only after the DOM content has loaded, the
* whole point of it being deferred.
*
* The search box has a keyboard handler that fires every time you press a keyboard button or send
* a keypress with a touch / virtual keyboard. We then iterate all module type cards and check if
* the plain text (HTML stripped out) representation of the module title or description partially
* matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide
* the module.
*
* This way we limit the displayed modules only to those searched.
*
* This feature follows progressive enhancement. The search box is hidden by default and only
* displayed when this JavaScript here executes. Furthermore, session storage is only used if it
* is available in the browser. That's a bit of a pain but makes sure things won't break in older
* browsers.
*
* Furthermore and to facilitate the user experience we auto-focus the search element which has a
* suitable title so that non-sighted users are not startled. This way we address both UX concerns
* and accessibility.
*
* Finally, the search string is saved into session storage on the assumption that the user is
* probably going to be creating multiple instances of the same module, one after another, as is
* typical when building a new Joomla! site.
*/
// Make sure the element exists i.e. a template override has not removed it.
const elSearch = document.getElementById('comModulesSelectSearch');
const elSearchContainer = document.getElementById('comModulesSelectSearchContainer');
const elSearchHeader = document.getElementById('comModulesSelectTypeHeader');
const elSearchResults = document.getElementById('comModulesSelectResultsContainer');
const alertElement = document.querySelector('.modules-alert');
const elCards = [].slice.call(document.querySelectorAll('.comModulesSelectCard'));
if (elSearch && elSearchContainer) {
// Add the keyboard event listener which performs the live search in the cards
elSearch.addEventListener('keyup', event => {
/** @type {KeyboardEvent} event */
const partialSearch = event.target.value;
let hasSearchResults = false;
// Save the search string into session storage
if (typeof sessionStorage !== 'undefined') {
sessionStorage.setItem('Joomla.com_modules.new.search', partialSearch);
}
// Iterate all the module cards
elCards.forEach(card => {
// First remove the class which hide the module cards
card.classList.remove('d-none');
// An empty search string means that we should show everything
if (!partialSearch) {
return;
}
const cardHeader = card.querySelector('.new-module-title');
const cardBody = card.querySelector('.new-module-caption');
const title = cardHeader ? cardHeader.textContent : '';
const description = cardBody ? cardBody.textContent : '';
// If the module title and description dont match add a class to hide it.
if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) {
card.classList.add('d-none');
} else {
hasSearchResults = true;
}
});
if (hasSearchResults || !partialSearch) {
alertElement.classList.add('d-none');
elSearchHeader.classList.remove('d-none');
elSearchResults.classList.remove('d-none');
} else {
alertElement.classList.remove('d-none');
elSearchHeader.classList.add('d-none');
elSearchResults.classList.add('d-none');
}
});
// For reasons of progressive enhancement the search box is hidden by default.
elSearchContainer.classList.remove('d-none');
// Focus the just show element
elSearch.focus();
try {
if (typeof sessionStorage !== 'undefined') {
// Load the search string from session storage
elSearch.value = sessionStorage.getItem('Joomla.com_modules.new.search') || '';
// Trigger the keyboard handler event manually to initiate the search
elSearch.dispatchEvent(new KeyboardEvent('keyup'));
}
} catch (e) {
// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :(
}
}

View File

@ -0,0 +1 @@
const elSearch=document.getElementById("comModulesSelectSearch"),elSearchContainer=document.getElementById("comModulesSelectSearchContainer"),elSearchHeader=document.getElementById("comModulesSelectTypeHeader"),elSearchResults=document.getElementById("comModulesSelectResultsContainer"),alertElement=document.querySelector(".modules-alert"),elCards=[].slice.call(document.querySelectorAll(".comModulesSelectCard"));if(elSearch&&elSearchContainer){elSearch.addEventListener("keyup",(e=>{const t=e.target.value;let o=!1;"undefined"!=typeof sessionStorage&&sessionStorage.setItem("Joomla.com_modules.new.search",t),elCards.forEach((e=>{if(e.classList.remove("d-none"),!t)return;const l=e.querySelector(".new-module-title"),s=e.querySelector(".new-module-caption"),n=l?l.textContent:"",a=s?s.textContent:"";n&&!n.toLowerCase().includes(t.toLowerCase())&&a&&!a.toLowerCase().includes(t.toLowerCase())?e.classList.add("d-none"):o=!0})),o||!t?(alertElement.classList.add("d-none"),elSearchHeader.classList.remove("d-none"),elSearchResults.classList.remove("d-none")):(alertElement.classList.remove("d-none"),elSearchHeader.classList.add("d-none"),elSearchResults.classList.add("d-none"))})),elSearchContainer.classList.remove("d-none"),elSearch.focus();try{"undefined"!=typeof sessionStorage&&(elSearch.value=sessionStorage.getItem("Joomla.com_modules.new.search")||"",elSearch.dispatchEvent(new KeyboardEvent("keyup")))}catch(e){}}

Binary file not shown.

View File

@ -0,0 +1,45 @@
/**
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
(() => {
// Use a JoomlaExpectingPostMessage flag to be able to distinct legacy methods
if (window.parent.JoomlaExpectingPostMessage) {
return;
}
// Assign listener for click event (for single module id insertion)
document.querySelectorAll('.js-module-insert').forEach(element => {
element.addEventListener('click', event => {
event.preventDefault();
const modid = event.target.getAttribute('data-module');
const editor = event.target.getAttribute('data-editor');
// Use the API
if (window.parent.Joomla && window.parent.Joomla.editors && window.parent.Joomla.editors.instances && Object.prototype.hasOwnProperty.call(window.parent.Joomla.editors.instances, editor)) {
window.parent.Joomla.editors.instances[editor].replaceSelection(`{loadmoduleid ${modid}}`);
}
if (window.parent.Joomla.Modal) {
window.parent.Joomla.Modal.getCurrent().close();
}
});
});
// Assign listener for click event (for position insertion)
document.querySelectorAll('.js-position-insert').forEach(element => {
element.addEventListener('click', event => {
event.preventDefault();
const position = event.target.getAttribute('data-position');
const editor = event.target.getAttribute('data-editor');
// Use the API
if (window.Joomla && window.Joomla.editors && Joomla.editors.instances && Object.prototype.hasOwnProperty.call(window.parent.Joomla.editors.instances, editor)) {
window.parent.Joomla.editors.instances[editor].replaceSelection(`{loadposition ${position}}`);
}
if (window.parent.Joomla.Modal) {
window.parent.Joomla.Modal.getCurrent().close();
}
});
});
})();

View File

@ -0,0 +1 @@
window.parent.JoomlaExpectingPostMessage||(document.querySelectorAll(".js-module-insert").forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault();const e=t.target.getAttribute("data-module"),o=t.target.getAttribute("data-editor");window.parent.Joomla&&window.parent.Joomla.editors&&window.parent.Joomla.editors.instances&&Object.prototype.hasOwnProperty.call(window.parent.Joomla.editors.instances,o)&&window.parent.Joomla.editors.instances[o].replaceSelection(`{loadmoduleid ${e}}`),window.parent.Joomla.Modal&&window.parent.Joomla.Modal.getCurrent().close()}))})),document.querySelectorAll(".js-position-insert").forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault();const e=t.target.getAttribute("data-position"),o=t.target.getAttribute("data-editor");window.Joomla&&window.Joomla.editors&&Joomla.editors.instances&&Object.prototype.hasOwnProperty.call(window.parent.Joomla.editors.instances,o)&&window.parent.Joomla.editors.instances[o].replaceSelection(`{loadposition ${e}}`),window.parent.Joomla.Modal&&window.parent.Joomla.Modal.getCurrent().close()}))})));

Binary file not shown.

View File

@ -0,0 +1,32 @@
/**
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
(document => {
document.addEventListener('DOMContentLoaded', () => {
const elems = document.querySelectorAll('#new-modules-list a.select-link');
elems.forEach(elem => {
elem.addEventListener('click', ({
currentTarget,
target
}) => {
let targetElem = currentTarget;
// There is some bug with events in iframe where currentTarget is "null"
// => prevent this here by bubble up
if (!targetElem) {
targetElem = target;
if (targetElem && !targetElem.classList.contains('select-link')) {
targetElem = targetElem.parentNode;
}
}
const functionName = targetElem.getAttribute('data-function');
if (functionName && typeof window.parent[functionName] === 'function') {
window.parent[functionName](targetElem);
}
});
});
});
})(document);

View File

@ -0,0 +1 @@
(t=>{t.addEventListener("DOMContentLoaded",(()=>{t.querySelectorAll("#new-modules-list a.select-link").forEach((t=>{t.addEventListener("click",(({currentTarget:t,target:e})=>{let n=t;n||(n=e,n&&!n.classList.contains("select-link")&&(n=n.parentNode));const a=n.getAttribute("data-function");a&&"function"==typeof window.parent[a]&&window.parent[a](n)}))}))}))})(document);

Binary file not shown.