From 9ed41ac298273be13713a4847bb5659734506657 Mon Sep 17 00:00:00 2001 From: ken Date: Wed, 23 Sep 2026 20:06:48 +0800 Subject: [PATCH] up --- assets/javascripts/app.js | 476 ++++++++++++++++-- assets/stylesheets/template/base/_global.scss | 11 +- .../template/modules/ad_banner.scss | 2 + .../template/modules/archives.scss | 4 +- .../template/modules/event_news.scss | 1 - .../stylesheets/template/modules/video.scss | 6 +- modules/ad_banner/_ad_banner_widget2.html.erb | 53 +- modules/announcement/annc_index18.html.erb | 2 +- modules/announcement/annc_index19.html.erb | 4 +- modules/announcement/annc_index5.html.erb | 4 +- modules/announcement/annc_index6.html.erb | 4 +- .../event_news_mod/event_news_index5.html.erb | 2 +- .../event_news_mod/event_news_index6.html.erb | 2 +- .../event_news_mod/event_news_index7.html.erb | 2 +- modules/member/member_index2.html.erb | 2 +- modules/member/member_index3.html.erb | 2 +- modules/member/member_index5.html.erb | 2 +- modules/member/member_index7.html.erb | 2 +- modules/member/member_index8.html.erb | 2 +- modules/universal_table/index3.html.erb | 5 +- modules/video_pro/video_pro_index4.html.erb | 4 +- .../web_resource/_web_res_widget8.html.erb | 3 +- modules/web_resource/web_res_index1.html.erb | 2 +- modules/web_resource/web_res_index2.html.erb | 2 +- 24 files changed, 518 insertions(+), 81 deletions(-) diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js index 34ac7bb..0838207 100644 --- a/assets/javascripts/app.js +++ b/assets/javascripts/app.js @@ -515,20 +515,28 @@ }); //播放驗證碼語音 $(function () { - $('.ask-question') - .find('.controls button.fas.fa-volume-up') - .each(function () { - const $btn = $(this); + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); + var label = isEn ? 'Play Captcha Voice' : '播放驗證碼語音'; - // 已經補過就不重複處理 - if ($btn.attr('aria-label')) return; + $('.ask-question') + .find('.controls button.fas.fa-volume-up') + .each(function () { + var $btn = $(this); - $btn.attr({ - 'aria-label': '播放驗證碼語音', - 'aria-controls': 'captcha_audio', - 'role': 'button' - }); - }); + $btn.attr({ + 'aria-label': label, + 'title': label, + 'aria-controls': 'captcha_audio', + 'role': 'button' + }); + + // ✅ 同步更新 sr-only 文字(若有) + var $sr = $btn.find('.sr-only'); + if ($sr.length > 0) { + $sr.text(label); + } + }); }); //刪除td的id @@ -899,7 +907,7 @@ var isLinkImage = $parentA.length > 0 && $parentA.text().replace(/\u00a0/g, '').trim() === ""; // --- 1. 處理「裝飾性圖片」標註 --- - if (currentAlt === "announcement image" || currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片" || currentAlt === "這是一張圖片" || currentTitle === "這是一張圖片") { + if (currentAlt === "announcement image" || currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片" || currentAlt === "這是一張圖片" || currentTitle === "這是一張圖片"||currentAlt === "This is a image" ||currentTitle === "This is a image"){ $img.attr('alt', ''); $img.removeAttr('title'); return; @@ -2118,27 +2126,68 @@ $(function() { }); //rucaptcha-image $(document).ready(function () { - $('.rucaptcha-image').removeAttr('onload'); - - // 檢查是否已插入過 - if (!$('#captcha_audio').length) { - const audioButton = $(` - - `); - - const audio = $(''); - - $('.rucaptcha-image').after(audioButton, audio); + function fixCaptchaImgA11y() { + setTimeout(function () { + // ✅ 先確認頁面上真的有驗證碼圖片,再往下執行 + if (!$('.rucaptcha-image').length) return; + + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); + + var i18n = { + alt: isEn ? 'Captcha image, click to refresh' : '驗證碼圖片,點擊可更換', + title: isEn ? 'Captcha image, click to refresh' : '驗證碼圖片,點擊可更換', + label: isEn ? 'Click to refresh captcha' : '點擊更換驗證碼', + audioBtn: isEn ? 'Play captcha audio' : '播放驗證碼語音', + audioSrc: isEn ? '/rucaptcha/?format=wav&locale=en' : '/rucaptcha/?format=wav&locale=zh_tw' + }; + + var $captchaImg = $('.rucaptcha-image'); + + // ✅ 移除 onload + $captchaImg.removeAttr('onload'); + + // ✅ 補上有意義的 alt、role、tabindex、title + $captchaImg.attr({ + 'alt': i18n.alt, + 'title': i18n.title, + 'role': 'button', + 'tabindex': '0', + 'aria-label': i18n.label + }); + + // ✅ Enter / Space 觸發更換驗證碼 + $captchaImg.off('keydown.captchaA11y').on('keydown.captchaA11y', function (e) { + if (e.which === 13 || e.which === 32) { + e.preventDefault(); + $(this).trigger('click'); + } + }); + + // ✅ 插入語音按鈕和 audio(若還沒插入過) + if (!$('#captcha_audio').length) { + var $audioButton = $( + '' + ); + + var $audio = $(''); + + $captchaImg.after($audioButton, $audio); + } + + }, 500); } + + fixCaptchaImgA11y(); }); //萬用表格searchbtn2 @@ -3313,5 +3362,366 @@ $(document).ready(function () { $(document).ready(function () { setTimeout(fixCarouselImagesA11y, 500); }); +//會員tab邏輯 +$(document).ready(function () { + setTimeout(function () { + $('.dtr-control').removeAttr('tabindex'); + }, 500); +}); +function fixTabKeyboardNav() { + setTimeout(function () { + var $tablist = $('.member-plugins[role="tablist"]'); + var $tabs = $tablist.find('a[role="tab"]'); + + // 初始化 roving tabindex 和 aria-selected + $tabs.each(function (i) { + var $tab = $(this); + var isActive = $tab.closest('li').hasClass('active'); + $tab.attr({ + 'tabindex': isActive ? '0' : '-1', + 'aria-selected': isActive ? 'true' : 'false' + }); + }); + + // 方向鍵切換頁籤 + $tabs.on('keydown', function (e) { + var $current = $(this); + var currentIndex = $tabs.index($current); + var $target; + + if (e.keyCode === 39 || e.keyCode === 40) { + // 右鍵或下鍵:下一個 + e.preventDefault(); + $target = $tabs.eq((currentIndex + 1) % $tabs.length); + } else if (e.keyCode === 37 || e.keyCode === 38) { + // 左鍵或上鍵:上一個 + e.preventDefault(); + $target = $tabs.eq((currentIndex - 1 + $tabs.length) % $tabs.length); + } else if (e.keyCode === 36) { + // Home:第一個 + e.preventDefault(); + $target = $tabs.first(); + } else if (e.keyCode === 35) { + // End:最後一個 + e.preventDefault(); + $target = $tabs.last(); + } else { + return; + } + + // 更新 roving tabindex 和 aria-selected + $tabs.attr({ 'tabindex': '-1', 'aria-selected': 'false' }); + $target.attr({ 'tabindex': '0', 'aria-selected': 'true' }); + $target.focus().trigger('click'); + }); + + // 點擊頁籤時同步更新狀態 + $tabs.on('click', function () { + $tabs.attr({ 'tabindex': '-1', 'aria-selected': 'false' }); + $(this).attr({ 'tabindex': '0', 'aria-selected': 'true' }); + }); + + }, 500); +} +$(document).ready(function () { + fixTabKeyboardNav(); +}); +function removeBareUrlLinks() { + setTimeout(function() { + $('.dataTables_wrapper a').each(function() { + var $a = $(this); + var text = $a.text().trim(); + + if (/^https?:\/\//i.test(text)) { + $a.replaceWith(text); + } + }); + }, 500); +} +$(document).ready(function() { + removeBareUrlLinks(); +}); +//麵包屑無障礙 +$(document).ready(function () { + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); + + var navLabel = isEn ? 'Breadcrumb navigation' : '麵包屑導覽'; + + $('.widget-breadcrumb .breadcrumb li:last-child a').attr('aria-current', 'page'); + + $('.widget-breadcrumb .breadcrumb').each(function () { + if (!$(this).closest('nav').length) { + $(this).wrap(''); + } + }); +}); +//gallery view +function fixGalleryViewLinkA11y() { + $('a.btn.view').each(function () { + var $a = $(this); + + $a.find('span').each(function () { + var $span = $(this); + + // 避免重複處理 + if ($span.hasClass('sr-only')) return; + + var style = $span.attr('style') || ''; + if (style.indexOf('display: none') !== -1 || style.indexOf('display:none') !== -1) { + $span.removeAttr('style').addClass('sr-only'); + } + }); + + $a.find('i, svg').attr('aria-hidden', 'true'); + }); +} +$(document).ready(function () { + // 比 fixAccessibilityAll 的 800ms 晚,確保最後執行 + setTimeout(fixGalleryViewLinkA11y, 2000); +}); +//會員 +$(function() { + function fixMemberAcademicLinkA11y() { + setTimeout(function() { + $('.i-member-item').each(function() { + var $item = $(this); + + // ✅ 取得該成員的姓名 + var memberName = $item.find('.member-data-value-name a').text().trim(); + if (!memberName) return; + + // ✅ 找到學術歷程連結,補上包含姓名的 title + $item.find('.member-data-value-11 a').each(function() { + var $a = $(this); + var currentTitle = $a.attr('title') || ''; + + // ✅ 移除舊的開窗字串,組合新 title + var titleWithoutWindow = currentTitle + .replace('另開新視窗前往', '') + .replace('在新視窗開啟', '') + .replace('在本視窗開啟', '') + .trim(); + + var isNewWindow = $a.attr('target') === '_blank'; + var windowText = isNewWindow ? ' 在新視窗開啟' : ' 在本視窗開啟'; + + $a.attr('title', memberName + ' ' + titleWithoutWindow + windowText); + }); + }); + }, 500); + } + + fixMemberAcademicLinkA11y(); +}); +//中英切換紐 class用lang-switch +$(function() { + $('.lang-switch').on('click', function(e) { + e.preventDefault(); + + var path = window.location.pathname; + var search = window.location.search; + var newUrl; + + // 首頁用 ?locale= 判斷 + if (search.includes('locale=en')) { + newUrl = '/?locale=zh_tw'; + } else if (search.includes('locale=zh_tw')) { + newUrl = '/?locale=en'; + // 內頁用路徑判斷 + } else if (path.startsWith('/en')) { + newUrl = path.replace(/^\/en/, '/zh_tw'); + } else if (path.startsWith('/zh_tw')) { + newUrl = path.replace(/^\/zh_tw/, '/en'); + } else { + newUrl = '/?locale=zh_tw'; + } + + window.location.href = newUrl; + }); +}); + //banner英文 + $(function() { + function fixBannerA11yByLang() { + setTimeout(function() { + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); + + var i18n = { + playControls: isEn ? 'Playback Controls' : '播放控制選項', + resume: isEn ? 'Play' : '繼續播放', + pause: isEn ? 'Pause' : '暫停播放', + prev: isEn ? 'Previous' : '上一張', + next: isEn ? 'Next' : '下一張', + slide: isEn ? 'Slide' : '第', + slideUnit: isEn ? '' : ' 張投影片' + }; + + $('.w-ba-banner').each(function() { + var $banner = $(this); + + // ✅ 播放控制選項 radiogroup label + $banner.find('.controlplay').attr('aria-label', i18n.playControls); + + // ✅ 繼續播放按鈕 + $banner.find('.resume-slide').attr({ + 'aria-label': i18n.resume, + 'title': i18n.resume + }); + $banner.find('.resume-slide p').text(i18n.resume); + + // ✅ 暫停播放按鈕 + $banner.find('.pause-slide').attr({ + 'aria-label': i18n.pause, + 'title': i18n.pause + }); + $banner.find('.pause-slide p').text(i18n.pause); + + // ✅ 上一張按鈕 + $banner.find('.prev-button').attr('aria-label', i18n.prev); + + // ✅ 下一張按鈕 + $banner.find('.next-button').attr('aria-label', i18n.next); + + // ✅ Pager 按鈕 + var $slides = $banner.find('.w-ba-banner__slide'); + $banner.find('.banner-pager button').each(function(index) { + var slideTitle = $slides.eq(index).data('cycle-title') || ''; + var ariaLabel = isEn + ? i18n.slide + ' ' + (index + 1) + (slideTitle ? ' ' + slideTitle : '') + : i18n.slide + (index + 1) + i18n.slideUnit + (slideTitle ? ' ' + slideTitle : ''); + $(this).attr({ + 'aria-label': ariaLabel, + 'title': ariaLabel + }); + }); + }); + + // ✅ Cycle2 初始化後也重新處理 Pager(因為 pager 是動態產生的) + $('.w-ba-banner .cycle-slideshow').on('cycle-post-initialize cycle-after', function() { + var $banner = $(this).closest('.w-ba-banner'); + var $slides = $banner.find('.w-ba-banner__slide'); + $banner.find('.banner-pager button').each(function(index) { + var slideTitle = $slides.eq(index).data('cycle-title') || ''; + var ariaLabel = isEn + ? i18n.slide + ' ' + (index + 1) + (slideTitle ? ' ' + slideTitle : '') + : i18n.slide + (index + 1) + i18n.slideUnit + (slideTitle ? ' ' + slideTitle : ''); + $(this).attr({ + 'aria-label': ariaLabel, + 'title': ariaLabel + }); + }); + }); + + }, 800); + } + + fixBannerA11yByLang(); + }); +//bannercontrolplay +$(function() { + function fixBannerPlayPauseA11y() { + setTimeout(function() { + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); + + var i18n = { + resume: isEn ? 'Play' : '繼續播放', + pause: isEn ? 'Pause' : '暫停播放' + }; + + $('.w-ba-banner').each(function() { + var $banner = $(this); + var $controlplay = $banner.find('.controlplay'); + + // ✅ 把 radiogroup 改為一般容器 + $controlplay.removeAttr('role aria-label'); + + // ✅ 繼續播放按鈕 + var $resume = $banner.find('.resume-slide'); + $resume + .attr('role', 'button') + .attr('aria-pressed', $resume.hasClass('active') ? 'true' : 'false') + .attr('aria-label', i18n.resume) + .attr('title', i18n.resume) + .removeAttr('aria-checked aria-live'); + + // ✅ 暫停播放按鈕 + var $pause = $banner.find('.pause-slide'); + $pause + .attr('role', 'button') + .attr('aria-pressed', $pause.hasClass('active') ? 'true' : 'false') + .attr('aria-label', i18n.pause) + .attr('title', i18n.pause) + .removeAttr('aria-checked aria-live'); + + // ✅ 點擊後同步 aria-pressed + $resume.off('click.bannerA11y').on('click.bannerA11y', function() { + $resume.attr('aria-pressed', 'true'); + $pause.attr('aria-pressed', 'false'); + }); + + $pause.off('click.bannerA11y').on('click.bannerA11y', function() { + $pause.attr('aria-pressed', 'true'); + $resume.attr('aria-pressed', 'false'); + }); + }); + + }, 800); + } + + fixBannerPlayPauseA11y(); +}); +//banner alt +function removeDefaultBannerAlt() { + setTimeout(function () { + $('.w-ad-banner__image').each(function () { + if ($(this).attr('alt') === 'Banner image') { + $(this).attr('alt', ''); + } + }); + }, 500); +} + +$(function () { + removeDefaultBannerAlt(); +}); +//sdgs alt +function setSdgsIconAlt() { + setTimeout(function () { + var sdgsAltMap = { + 1 : '消除貧窮類別', + 2 : '消除飢餓類別', + 3 : '良好健康和福祉類別', + 4 : '優質教育類別', + 5 : '性別平等類別', + 6 : '潔淨水與衛生類別', + 7 : '可負擔的潔淨能源類別', + 8 : '尊嚴就業與經濟發展類別', + 9 : '產業創新與基礎設施類別', + 10: '減少不平等類別', + 11: '永續城市與社區類別', + 12: '負責任的消費與生產類別', + 13: '氣候行動類別', + 14: '水下生命類別', + 15: '陸域生命類別', + 16: '和平正義與有力的制度類別', + 17: '夥伴關係類別' + }; + + $('img[src*="sdgs_icon_"]').each(function () { + var src = $(this).attr('src') || ''; + var match = src.match(/sdgs_icon_(\d+)\.[a-zA-Z]+(?:\?.*)?$/); + + if (match && sdgsAltMap[match[1]]) { + $(this).attr('alt', sdgsAltMap[match[1]]); + } + }); + }, 500); +} + +$(function () { + setSdgsIconAlt(); +}); }(jQuery, window)); diff --git a/assets/stylesheets/template/base/_global.scss b/assets/stylesheets/template/base/_global.scss index 30c5c63..b6d6e86 100644 --- a/assets/stylesheets/template/base/_global.scss +++ b/assets/stylesheets/template/base/_global.scss @@ -6,6 +6,11 @@ .fa-classic, .fa-regular, .fa-solid, .far, .fas ,.fa{ font-family: "FontAwesome"; } +li#language-li { + @media(max-width:767px){ + display: none !important; + } +} #orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{ .orbit-bar-search-sign-language{ display: block @@ -212,6 +217,6 @@ a.btn-primary { // overflow-x: auto; // } // } -*[data-pp]>.editmode-ps>a, .admin-subpart-area .content>.editmode-ps>a{ - position: !important; -} \ No newline at end of file +input[type=checkbox]:focus { + outline: 0.3125em auto -webkit-focus-ring-color; +} diff --git a/assets/stylesheets/template/modules/ad_banner.scss b/assets/stylesheets/template/modules/ad_banner.scss index f00333f..53d376a 100644 --- a/assets/stylesheets/template/modules/ad_banner.scss +++ b/assets/stylesheets/template/modules/ad_banner.scss @@ -35,6 +35,7 @@ ul.button-mid{ width: 100%; height: 0; top: 50%; + z-index: 201; } .banner-pager .active-slide button{ background: $theme-color-second!important; @@ -44,6 +45,7 @@ ul.button-mid{ width: 100%; height: 0; top: 50%; + z-index: 201; } .next-button, .prev-button { cursor: pointer; diff --git a/assets/stylesheets/template/modules/archives.scss b/assets/stylesheets/template/modules/archives.scss index 34471c1..7a7561e 100644 --- a/assets/stylesheets/template/modules/archives.scss +++ b/assets/stylesheets/template/modules/archives.scss @@ -165,7 +165,7 @@ @extend .unity-title; } .link { background-color: #1368d4 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ -.txt { background-color: #3a8a40 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ +.txt { background-color: #2a7e31 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .xlsx { background-color: #9e3050 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .pdf { background-color: #2a7d36 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .docx { background-color: #5e46a0 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ @@ -174,7 +174,7 @@ .jpg { background-color: #8f3333 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .zip { background-color: #8a6400 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .rar { background-color: #9e5000 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ -.xls { background-color: #3a8a40 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ +.xls { background-color: #2a7e31 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .odt { background-color: #767676 !important; margin-left: 0.5em; } /* 對比 4.6:1 */ .table>caption+thead>tr:first-child>td, .table>caption+thead>tr:first-child>th, .table>colgroup+thead>tr:first-child>td, .table>colgroup+thead>tr:first-child>th, .table>thead:first-child>tr:first-child>td, .table>thead:first-child>tr:first-child>th{ // border-top: 0.0625em solid #ddd; diff --git a/assets/stylesheets/template/modules/event_news.scss b/assets/stylesheets/template/modules/event_news.scss index 361988e..5fdadfa 100644 --- a/assets/stylesheets/template/modules/event_news.scss +++ b/assets/stylesheets/template/modules/event_news.scss @@ -518,7 +518,6 @@ .i-annc__list { display: flex; flex-wrap: wrap; - justify-content: center; } .i-annc__title { font-family: $main-font; diff --git a/assets/stylesheets/template/modules/video.scss b/assets/stylesheets/template/modules/video.scss index 93dc42a..14cdb87 100644 --- a/assets/stylesheets/template/modules/video.scss +++ b/assets/stylesheets/template/modules/video.scss @@ -884,9 +884,9 @@ } .video_data-index-4{ - .i-annc__page-title{ - display: none; - } + // .i-annc__page-title{ + // display: none; + // } .category_box{ border:0; display: flex; diff --git a/modules/ad_banner/_ad_banner_widget2.html.erb b/modules/ad_banner/_ad_banner_widget2.html.erb index 70ef492..b74bbbc 100644 --- a/modules/ad_banner/_ad_banner_widget2.html.erb +++ b/modules/ad_banner/_ad_banner_widget2.html.erb @@ -29,9 +29,7 @@ - + + \ No newline at end of file diff --git a/modules/announcement/annc_index18.html.erb b/modules/announcement/annc_index18.html.erb index 778bb74..6ecfb02 100644 --- a/modules/announcement/annc_index18.html.erb +++ b/modules/announcement/annc_index18.html.erb @@ -3,7 +3,7 @@