MediaWiki:Common.js: различия между версиями

Нет описания правки
Нет описания правки
Строка 747: Строка 747:
}
}
// Для "Шаблон:CheckboxCreator"
// Для "Шаблон:CheckboxCreator"
function initCheckboxCreator() {
function initCheckboxCreatorOptimized() {
var containers = document.querySelectorAll('.js-checkbox-generator');
var containers = document.getElementsByClassName('js-checkbox-generator');


function parseBool(v) {
function parseBool(v) {
if (v === undefined || v === null) return false;
if (v === true) return true;
v = String(v).trim().toLowerCase();
if (v === false || v === undefined || v === null) return false;
return v === '1' || v === 'true' || v === 'yes' || v === 'checked';
var s = String(v).trim().toLowerCase();
return s === '1' || s === 'true' || s === 'yes' || s === 'checked';
}
}


function makeCheckbox(container, spec) {
function escHtml(s) {
var input = document.createElement('input');
return String(s === undefined || s === null ? '' : s)
input.type = 'checkbox';
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
 
var HTML_BATCH_THRESHOLD = 200;
 
for (var ci = 0; ci < containers.length; ci++) {
var container = containers[ci];
 
if (container.getAttribute('data-checkbox-initialized') === '1') {
continue;
}
 
var defaultCls = container.getAttribute('data-cbox-class') || '';
var itemsRaw = container.getAttribute('data-cbox-items');
 
if (itemsRaw) {
var arr = null;
try {
arr = JSON.parse(itemsRaw);
} catch (e) {
container.setAttribute('data-checkbox-initialized', '1');
continue;
}
 
if (!Array.isArray(arr) || arr.length === 0) {
container.setAttribute('data-checkbox-initialized', '1');
continue;
}


if (spec.cls) input.className = spec.cls;
if (arr.length >= HTML_BATCH_THRESHOLD) {
if (spec.name) input.name = spec.name;
var html = '';
if (spec.id) input.id = spec.id;
for (var i = 0; i < arr.length; i++) {
if (spec.checked) input.checked = true;
var it = arr[i];
if (spec.disabled) input.disabled = true;
var label = '';
var cls = defaultCls;
var checked = false;
var name = '';
var id = '';
var disabled = false;


var label = document.createElement('label');
if (typeof it === 'string' || typeof it === 'number') {
if (spec.id) label.htmlFor = spec.id;
label = it;
label.textContent = spec.label || '';
} else if (typeof it === 'object' && it !== null) {
label = it.label || '';
cls = (it["class"] || it.cls || defaultCls);
checked = parseBool(it.checked);
name = it.name || '';
id = it.id || '';
disabled = parseBool(it.disabled);
}


var wrapper = document.createElement('span');
html += '<span class="js-checkbox-gen-item">';
wrapper.className = 'js-checkbox-gen-item';
html += '<input type="checkbox"';
if (cls) html += ' class="' + escHtml(cls) + '"';
if (name) html += ' name="' + escHtml(name) + '"';
if (id) html += ' id="' + escHtml(id) + '"';
if (checked) html += ' checked';
if (disabled) html += ' disabled';
html += '>';
html += '<label';
if (id) html += ' for="' + escHtml(id) + '"';
html += '>' + escHtml(label) + '</label>';
html += '</span>';
}
container.insertAdjacentHTML('beforeend', html);
} else {
var frag = document.createDocumentFragment();
for (var j = 0; j < arr.length; j++) {
var item = arr[j];
var labelText = '';
var itemCls = defaultCls;
var itemChecked = false;
var itemName = '';
var itemId = '';
var itemDisabled = false;


wrapper.appendChild(input);
if (typeof item === 'string' || typeof item === 'number') {
wrapper.appendChild(label);
labelText = item;
} else if (typeof item === 'object' && item !== null) {
labelText = item.label || '';
itemCls = (item["class"] || item.cls || defaultCls);
itemChecked = parseBool(item.checked);
itemName = item.name || '';
itemId = item.id || '';
itemDisabled = parseBool(item.disabled);
}


container.appendChild(wrapper);
var wrapper = document.createElement('span');
}
wrapper.className = 'js-checkbox-gen-item';


containers.forEach(function(container) {
var input = document.createElement('input');
if (container.dataset.checkboxInitialized === '1') return;
input.type = 'checkbox';
if (itemCls) input.className = itemCls;
if (itemName) input.name = itemName;
if (itemId) input.id = itemId;
if (itemChecked) input.checked = true;
if (itemDisabled) input.disabled = true;


var itemsRaw = container.dataset.cboxItems;
var labelEl = document.createElement('label');
if (itemId) labelEl.htmlFor = itemId;
labelEl.textContent = labelText;


if (itemsRaw) {
wrapper.appendChild(input);
try {
wrapper.appendChild(labelEl);
var arr = JSON.parse(itemsRaw);
frag.appendChild(wrapper);
if (Array.isArray(arr)) {
arr.forEach(function(it) {
if (typeof it === 'string') {
makeCheckbox(container, {
label: it,
cls: container.dataset.cboxClass || ''
});
} else if (typeof it === 'object') {
makeCheckbox(container, {
label: it.label || '',
cls: it["class"] || container.dataset.cboxClass || '',
checked: parseBool(it.checked),
name: it.name || '',
id: it.id || '',
disabled: parseBool(it.disabled)
});
}
});
}
}
} catch (e) {}
container.appendChild(frag);
}
} else {
} else {
makeCheckbox(container, {
var singleLabel = container.getAttribute('data-cbox-label') || '';
label: container.dataset.cboxLabel || '',
var singleCls = container.getAttribute('data-cbox-class') || '';
cls: container.dataset.cboxClass || '',
var singleChecked = parseBool(container.getAttribute('data-cbox-checked'));
checked: parseBool(container.dataset.cboxChecked),
var singleName = container.getAttribute('data-cbox-name') || '';
name: container.dataset.cboxName || '',
var singleId = container.getAttribute('data-cbox-id') || '';
id: container.dataset.cboxId || '',
var singleDisabled = parseBool(container.getAttribute('data-cbox-disabled'));
disabled: parseBool(container.dataset.cboxDisabled)
 
});
var w = document.createElement('span');
w.className = 'js-checkbox-gen-item';
var inp = document.createElement('input');
inp.type = 'checkbox';
if (singleCls) inp.className = singleCls;
if (singleName) inp.name = singleName;
if (singleId) inp.id = singleId;
if (singleChecked) inp.checked = true;
if (singleDisabled) inp.disabled = true;
 
var lab = document.createElement('label');
if (singleId) lab.htmlFor = singleId;
lab.textContent = singleLabel;
 
w.appendChild(inp);
w.appendChild(lab);
container.appendChild(w);
}
}


container.dataset.checkboxInitialized = '1';
container.setAttribute('data-checkbox-initialized', '1');
});
}
}
}
// Привязка expand/collapse к чекбоксу по id
// Привязка expand/collapse к чекбоксу по id
function registerCheckboxExpander(checkboxId, options) {
function registerCheckboxExpander(checkboxId, options) {
    options = options || {};
options = options || {};
    // если нужно — использовать только expand (по умолчанию false = делаем и collapse)
// если нужно — использовать только expand (по умолчанию false = делаем и collapse)
    var onlyExpand = !!options.onlyExpand;
var onlyExpand = !!options.onlyExpand;


    var checkbox = document.getElementById(checkboxId);
var checkbox = document.getElementById(checkboxId);
    if (!checkbox) {
if (!checkbox) {
        // Если чекбокс ещё не на странице — попробуем навесить через делегирование (MutationObserver опционально)
// Если чекбокс ещё не на странице — попробуем навесить через делегирование (MutationObserver опционально)
        console.warn('registerCheckboxExpander: checkbox not found by id:', checkboxId);
console.warn('registerCheckboxExpander: checkbox not found by id:', checkboxId);
        return;
return;
    }
}


    function expandAll() {
function expandAll() {
        var collapsed = document.querySelectorAll('.mw-collapsed');
var collapsed = document.querySelectorAll('.mw-collapsed');
        for (var i = 0; i < collapsed.length; i++) {
for (var i = 0; i < collapsed.length; i++) {
            collapsed[i].classList.remove('mw-collapsed');
collapsed[i].classList.remove('mw-collapsed');
        }
}


        var togglesCollapsed = document.querySelectorAll('.mw-collapsible-toggle-collapsed');
var togglesCollapsed = document.querySelectorAll('.mw-collapsible-toggle-collapsed');
        for (var j = 0; j < togglesCollapsed.length; j++) {
for (var j = 0; j < togglesCollapsed.length; j++) {
            togglesCollapsed[j].classList.remove('mw-collapsible-toggle-collapsed');
togglesCollapsed[j].classList.remove('mw-collapsible-toggle-collapsed');
            togglesCollapsed[j].classList.add('mw-collapsible-toggle-expanded');
togglesCollapsed[j].classList.add('mw-collapsible-toggle-expanded');
        }
}


        var contents = document.querySelectorAll('.mw-collapsible-content');
var contents = document.querySelectorAll('.mw-collapsible-content');
        for (var k = 0; k < contents.length; k++) {
for (var k = 0; k < contents.length; k++) {
            if (contents[k].style && contents[k].style.display) {
if (contents[k].style && contents[k].style.display) {
                contents[k].style.removeProperty('display');
contents[k].style.removeProperty('display');
            }
}
        }
}
    }
}


    function collapseAll() {
function collapseAll() {
        var collapsibleContainers = document.querySelectorAll('.mw-collapsible');
var collapsibleContainers = document.querySelectorAll('.mw-collapsible');
        for (var i = 0; i < collapsibleContainers.length; i++) {
for (var i = 0; i < collapsibleContainers.length; i++) {
            var el = collapsibleContainers[i];
var el = collapsibleContainers[i];
            if (!el.classList.contains('mw-collapsed')) el.classList.add('mw-collapsed');
if (!el.classList.contains('mw-collapsed')) el.classList.add('mw-collapsed');
        }
}


        var togglesExpanded = document.querySelectorAll('.mw-collapsible-toggle-expanded');
var togglesExpanded = document.querySelectorAll('.mw-collapsible-toggle-expanded');
        for (var j = 0; j < togglesExpanded.length; j++) {
for (var j = 0; j < togglesExpanded.length; j++) {
            togglesExpanded[j].classList.remove('mw-collapsible-toggle-expanded');
togglesExpanded[j].classList.remove('mw-collapsible-toggle-expanded');
            togglesExpanded[j].classList.add('mw-collapsible-toggle-collapsed');
togglesExpanded[j].classList.add('mw-collapsible-toggle-collapsed');
        }
}


        var contents = document.querySelectorAll('.mw-collapsible-content');
var contents = document.querySelectorAll('.mw-collapsible-content');
        for (var k = 0; k < contents.length; k++) {
for (var k = 0; k < contents.length; k++) {
            contents[k].style.setProperty('display', 'none', 'important');
contents[k].style.setProperty('display', 'none', 'important');
        }
}
    }
}


    checkbox.addEventListener('change', function (e) {
checkbox.addEventListener('change', function (e) {
        if (checkbox.checked) {
if (checkbox.checked) {
            try { expandAll(); } catch (err) { console.error(err); }
try { expandAll(); } catch (err) { console.error(err); }
        } else {
} else {
            if (!onlyExpand) {
if (!onlyExpand) {
                try { collapseAll(); } catch (err) { console.error(err); }
try { collapseAll(); } catch (err) { console.error(err); }
            }
}
        }
}
    });
});


    if (checkbox.checked) {
if (checkbox.checked) {
        try { expandAll(); } catch (err) { console.error(err); }
try { expandAll(); } catch (err) { console.error(err); }
    }
}
}
}
const currentPageTitle = document.title;
const currentPageTitle = document.title;