upgrade: adopt V8.21.3 (V8.13→8.21.3: P5 SFTP/S3, P6 multilingual, editor overhaul, enterprise hardening)
Overlay ~150 upstream items onto our V8.12 base, preserving trade-pro
theme, registry tests, and design docs. Re-applied our patch set
(discovery/env_for/blocks.css/type-mapping/theme_color/frontend entries,
test_theme_pro_v3 mods) — all anchors survived upstream evolution.
New platform enhancement (fixes upgrade-introduced regression):
multilingual.site_locale now honors settings_json.locale, plus
PUT /api/i18n/sites/{id}/locale — standalone English sites get
<html lang='en'> under the V8.15 locale-rewrite pipeline.
compose: adopt V8.21.3 (image 8.21.3-dev.1, /api/ready probes, MySQL/S3
env) with project name pinned to siteforge-v8-10 (data volumes).
Tests: 356 passed / 11 failed — all 11 confirmed pre-existing in
pristine V8.21.3 on this host (10 upstream Windows env + our build test
now green after locale fix). Patch registry updated in plan doc.
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,52 @@
|
||||
'use strict';(()=>{
|
||||
const menu=document.querySelector('[data-pro-menu]'); const nav=document.querySelector('#pro-navigation');
|
||||
if(menu&&nav){menu.addEventListener('click',()=>{const open=menu.getAttribute('aria-expanded')!=='true';menu.setAttribute('aria-expanded',String(open));nav.classList.toggle('is-open',open);menu.setAttribute('aria-label',open?'关闭导航':'打开导航');});}
|
||||
// Drawer navigation. The same markup is used across the four professional themes.
|
||||
const mobileNav=document.querySelector('#pro-navigation');
|
||||
let drawerBackdrop=null,drawerClose=null,returnFocus=null;
|
||||
if(menu&&mobileNav){
|
||||
const originalParent=mobileNav.parentNode,originalNext=mobileNav.nextSibling;
|
||||
const heading=document.createElement('div');heading.className='sf-drawer-header';
|
||||
const title=document.createElement('strong');title.textContent='网站导航';
|
||||
drawerClose=document.createElement('button');drawerClose.type='button';drawerClose.className='sf-drawer-close';drawerClose.textContent='×';drawerClose.setAttribute('aria-label','关闭网站导航');
|
||||
heading.append(title,drawerClose);mobileNav.prepend(heading);
|
||||
drawerBackdrop=document.createElement('div');drawerBackdrop.className='sf-mobile-drawer-backdrop';drawerBackdrop.hidden=false;document.body.append(drawerBackdrop);
|
||||
function setDrawer(open,focusBack=true){
|
||||
const isMobile=window.matchMedia('(max-width:1024px)').matches;
|
||||
open=Boolean(open&&isMobile);
|
||||
if(open){returnFocus=document.activeElement;document.body.append(mobileNav);}
|
||||
else if(mobileNav.parentNode!==originalParent){if(originalNext&&originalNext.parentNode===originalParent)originalParent.insertBefore(mobileNav,originalNext);else originalParent.append(mobileNav);}
|
||||
mobileNav.classList.toggle('is-open',open);drawerBackdrop.classList.toggle('is-open',open);
|
||||
document.body.classList.toggle('sf-drawer-open',open);
|
||||
menu.setAttribute('aria-expanded',String(open));menu.setAttribute('aria-label',open?'关闭导航':'打开导航');
|
||||
mobileNav.setAttribute('aria-hidden',String(!open&&isMobile));
|
||||
if('inert' in mobileNav)mobileNav.inert=!open&&isMobile;
|
||||
if(open)drawerClose.focus();
|
||||
else if(focusBack&&returnFocus instanceof HTMLElement){returnFocus.focus();returnFocus=null;}
|
||||
}
|
||||
// Replace the old inline-expansion listener: use capture to stop the old listener.
|
||||
menu.addEventListener('click',e=>{if(!window.matchMedia('(max-width:1024px)').matches)return;e.stopImmediatePropagation();setDrawer(!mobileNav.classList.contains('is-open'));},true);
|
||||
drawerClose.addEventListener('click',()=>setDrawer(false));
|
||||
drawerBackdrop.addEventListener('click',()=>setDrawer(false));
|
||||
document.querySelectorAll('[data-mobile-open-menu]').forEach(b=>b.addEventListener('click',()=>setDrawer(true)));
|
||||
mobileNav.addEventListener('click',e=>{if(e.target.closest('a'))setDrawer(false,false)});
|
||||
document.addEventListener('keydown',e=>{
|
||||
if(e.key==='Escape'&&mobileNav.classList.contains('is-open')){e.preventDefault();setDrawer(false);}
|
||||
if(e.key!=='Tab'||!mobileNav.classList.contains('is-open'))return;
|
||||
const els=[...mobileNav.querySelectorAll('button:not([disabled]),a[href]')].filter(el=>el.getClientRects().length&&!el.closest('[hidden]'));
|
||||
if(!els.length)return;const first=els[0],last=els[els.length-1];
|
||||
if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();}
|
||||
else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();}
|
||||
});
|
||||
window.matchMedia('(max-width:1024px)').addEventListener('change',()=>setDrawer(false,false));
|
||||
if('inert' in mobileNav&&window.matchMedia('(max-width:1024px)').matches)mobileNav.inert=true;
|
||||
// Do not strand catalogue links when the old mobile mega-button is hidden.
|
||||
const megaLinks=document.querySelectorAll('[data-pro-mega] a');
|
||||
if(megaLinks.length){const wrap=document.createElement('div');wrap.className='sf-drawer-extra';const h=document.createElement('strong');h.textContent='更多分类与系列';wrap.append(h);
|
||||
[...megaLinks].slice(0,20).forEach(a=>{const clone=a.cloneNode(true);wrap.append(clone);});mobileNav.append(wrap);}
|
||||
}
|
||||
const tabbar=document.querySelector('[data-mobile-tabs]');
|
||||
if(tabbar){tabbar.style.setProperty('--sf-mobile-tab-count',String(tabbar.children.length));}
|
||||
const megaButton=document.querySelector('[data-pro-catalog]'), mega=document.querySelector('[data-pro-mega]');
|
||||
if(megaButton&&mega){function setMega(open){mega.hidden=!open;mega.classList.toggle('is-open',open);megaButton.setAttribute('aria-expanded',String(open));}
|
||||
megaButton.addEventListener('click',()=>setMega(mega.hidden));
|
||||
|
||||
Reference in New Issue
Block a user