Изменения документа App
Редактировал(а) A1MTestAdmin 2026/10/17 17:15
От версии 35.1
отредактировано A1MTestAdmin
на 2026/10/17 09:11
на 2026/10/17 09:11
Изменить комментарий:
К данной версии нет комментариев
К версии 38.1
отредактировано A1MTestAdmin
на 2026/10/17 17:15
на 2026/10/17 17:15
Изменить комментарий:
К данной версии нет комментариев
Сводка
-
Свойства страницы (2 изменено, 0 добавлено, 0 удалено)
-
Объекты (0 изменено, 1 добавлено, 0 удалено)
Подробности
- Свойства страницы
-
- Название
-
... ... @@ -1,1 +1,1 @@ 1 -A 1M1 +App - Содержимое
-
... ... @@ -1,6 +1,19 @@ 1 1 {{velocity}} 2 -#set($discard = $xwiki.ssx.use('A1M.Style')) 3 -#set($discard = $xwiki.jsx.use('A1M.Style')) 2 +#set($discard = $xwiki.ssx.use('A1M.App')) 3 +#set($discard = $xwiki.jsx.use('A1M.App')) 4 +## Keep the existing protected workflow renderer and replace its legacy overview slot. 5 +#set($rendered = $xwiki.getDocument('A1M.Renderer').getRenderedContent()) 6 +#set($legacyPanel = '<section class="panel"><div class="panel-head">01–03 · Основополагающие направления</div>') 7 +#set($start = $rendered.indexOf($legacyPanel)) 8 +#if($start >= 0) 9 + #set($end = $rendered.indexOf('</section>', $start) + 10) 10 + #set($before = $rendered.substring(0, $start)) 11 + #set($after = $rendered.substring($end)) 12 + #set($panel = $xwiki.getDocument('A1M.FoundationPanel').getRenderedContent()) 13 + #set($rendered = $before + $panel + $after) 14 +#end 15 +{{html clean="false" wiki="false"}} 16 +$rendered 17 +{{/html}} 4 4 {{/velocity}} 5 5 6 -{{a1m/}}
- XWiki.JavaScriptExtension[0]
-
- name
-
... ... @@ -1,0 +1,1 @@ 1 +A1M interface 1.0.1 - code
-
... ... @@ -1,0 +1,76 @@ 1 +/* A1M native JavaScript skin extension. No requests, storage or application data cache. */ 2 +(() => { 3 + 'use strict'; 4 + function enhance() { 5 + const shell = document.querySelector('.a1m-shell'); 6 + if (!shell || shell.dataset.interfaceVersion === '1.0.1') return; 7 + shell.dataset.interfaceVersion = '1.0.1'; 8 + const labels = { 9 + priority: 'По приоритету', title: 'По названию', updated: 'По дате изменения', 10 + relevance: 'По релевантности', asc: 'По возрастанию', desc: 'По убыванию' 11 + }; 12 + shell.querySelectorAll('select[name=sort] option,select[name=direction] option').forEach(option => { 13 + if (labels[option.value]) option.textContent = labels[option.value]; 14 + }); 15 + const current = new URL(window.location.href); 16 + const section = current.searchParams.get('section') || ''; 17 + shell.querySelectorAll('.side nav a').forEach(link => { 18 + const destination = new URL(link.href, window.location.href); 19 + if (destination.pathname === current.pathname && (destination.searchParams.get('section') || '') === section) { 20 + link.setAttribute('aria-current', 'page'); 21 + } 22 + }); 23 + // Every option was already filtered by server-side permissions. Only replace its control. 24 + const select = shell.querySelector('.filters select[name=theme][multiple]'); 25 + if (select) { 26 + const originalLabel = select.closest('label'); 27 + const fieldset = document.createElement('fieldset'); 28 + fieldset.className = 'theme-options'; 29 + const legend = document.createElement('legend'); 30 + legend.textContent = 'Тематика · можно выбрать несколько'; 31 + fieldset.append(legend); 32 + select.hidden = true; 33 + select.setAttribute('aria-hidden', 'true'); 34 + select.tabIndex = -1; 35 + const checkboxes = []; 36 + const options = Array.from(select.options); 37 + for (const option of options.filter(item => item.value)) { 38 + const label = document.createElement('label'); 39 + const checkbox = document.createElement('input'); 40 + checkbox.type = 'checkbox'; 41 + checkbox.checked = option.selected; 42 + checkbox.addEventListener('change', () => { 43 + option.selected = checkbox.checked; 44 + const empty = options.find(item => !item.value); 45 + if (empty) empty.selected = !checkboxes.some(item => item.checked); 46 + }); 47 + checkboxes.push(checkbox); 48 + label.append(checkbox, document.createTextNode(option.textContent)); 49 + fieldset.append(label); 50 + } 51 + const reset = document.createElement('button'); 52 + reset.type = 'button'; 53 + reset.textContent = 'Все темы'; 54 + reset.addEventListener('click', () => { 55 + options.forEach(option => { option.selected = !option.value; }); 56 + checkboxes.forEach(checkbox => { checkbox.checked = false; }); 57 + }); 58 + fieldset.append(reset, select); 59 + originalLabel.replaceWith(fieldset); 60 + } 61 + shell.querySelectorAll('.panel-head').forEach(header => { 62 + header.setAttribute('role', 'heading'); 63 + header.setAttribute('aria-level', '2'); 64 + }); 65 + // Keep the intended destination even when a login starts directly from a record. 66 + const login = shell.querySelector('a[href*="/bin/login/"]'); 67 + if (login) { 68 + const target = new URL(login.href, window.location.href); 69 + target.searchParams.set('xredirect', current.pathname + current.search); 70 + login.href = target.pathname + target.search; 71 + } 72 + } 73 + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', enhance, { once: true }); 74 + else enhance(); 75 +})(); 76 + - use
-
... ... @@ -1,0 +1,1 @@ 1 +onDemand - parse
-
... ... @@ -1,0 +1,1 @@ 1 +Нет - cache
-
... ... @@ -1,0 +1,1 @@ 1 +default