fix(widgets): restore single-card reference UI for search and quote widgets

The 搜索框 and 一言 sidebar widgets fell into the generic renderer branch, so
they rendered a .jio-panel card wrapping a second bespoke card
(.jio-widget-search / .jio-widget-quote). In-article 一言 also used
divergent modifier classes and an extra hover rule.

- search: render through the shared jio_get_search_box() (legacy keyword,
  history and category pickers) inside one reference card, mirroring the
  reference widget's markup and title default 「搜索」
- quote: render the reference .yiyan-box card itself as the click root; the
  shell now emits only the reference widget-container/title wrapper
- article 一言: adopt the reference class lists for header, footer and the
  standalone after-article box; drop the invented yiyan--* modifiers and
  the duplicate hover/opacity rules
- client: fill .cn/.en in the reference order (first line .cn, second .en)
  and drop the stale window.JioYiyan bridge plus the dead qv-yiyan.php AJAX
  path in runtime main.js
- schema: replace the ad-hoc search_style radio with the reference switches
  (keywords, history, input category, more_cats) and default title
- assets: enqueue assets/js/yiyan.js through the quote widget's asset list

Tests: widget-system suite 820/821 (the one failure is the pre-existing
frontend-lifecycle theme-init stub); new search/quote card contracts pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-03 15:56:52 +08:00
1 parent 1549d5b25d
commit f80ca1e27d
19 files changed
+276 -182

No files matched your search

@@ -1,45 +1,3 @@
/* ---- Yiyan inline blocks (single post) ---- */
.yiyan--header,
.yiyan--footer {
margin: 16px 0;
padding: 12px 16px;
}
.yiyan--box {
margin: 24px 0;
padding: 20px;
border-radius: 8px;
background: var(--card-bg, #fff);
box-shadow: var(--card-shadow, 0 2px 8px rgba(0, 0, 0, .06));
}
.jio-yiyan[data-jio-yiyan] {
cursor: pointer;
transition: box-shadow .2s ease, opacity .2s ease;
}
.jio-yiyan[data-jio-yiyan]:hover,
.jio-yiyan[data-jio-yiyan]:focus-visible {
box-shadow: inset 0 0 5px 0 var(--focus-shadow-color, rgba(253, 83, 161, .3));
}
.jio-yiyan .yiyan {
line-height: 1.8;
}
.jio-yiyan .yiyan .en {
font-size: .9em;
opacity: .8;
}
.jio-yiyan.is-loading {
opacity: .65;
}
.jio-yiyan.is-error .cn {
color: var(--muted-color, #777);
}
/* ---- Front / After content insertion ---- */
.article-front-content,
.article-after-content {
+1 -35
View File
@@ -4463,41 +4463,7 @@ jQuery(document).ready(function () {
.delay(1e3, function () {
jQuery(this).remove(), jQuery('#qj_dh_css').remove();
});
/*一言功能*/
function yiyan_nr(n) {
var yylink = _win.uri + '/yiyan/qv-yiyan.php',
y_nr;
jQuery.ajax({
type: 'POST',
url: yylink,
}).done(function (i) {
var lines = i
.replace(/\r\n|\r/g, '/&/')
.trim()
.split('/&/');
if (lines) {
var type = n.attr('type');
if (type) {
y_nr = type === 'en' ? lines[0] : lines[1];
} else {
y_nr = '<div class="cn">' + lines[0] + '</div><div class="en">' + lines[1] + '</div>';
}
n.html(y_nr);
}
});
}
jQuery('.yiyan').each(function () {
yiyan_nr(jQuery(this));
}),
setInterval(function () {
jQuery('.yiyan').each(function () {
yiyan_nr(jQuery(this));
});
}, 3e4);
jQuery('.yiyan').on('click', function () {
yiyan_nr(jQuery(this));
});
/*一言功能由 assets/js/yiyan.js 单独负责([data-jio-yiyan])*/
/*文章目录由 Jio section-navs 按需入队,legacy 不再重复加载。*/
+1 -1
View File
@@ -1 +1 @@
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"jio-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("jio-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.JioModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.jioData||window2.jio||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/jio/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&&(result["CoLine truncated
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"jio-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("jio-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.JioModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.jioData||window2.jio||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/jio/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&&(result["CoLine truncated
+22 -8
View File
@@ -26,10 +26,26 @@
var quote = response && response.success && response.data;
if (!quote || !quote.cn || !quote.en) throw new Error('empty quote');
var cn = el.querySelector('.cn');
var en = el.querySelector('.en');
if (cn) cn.textContent = quote.cn;
if (en) en.textContent = quote.en;
// 参考结构:.yiyan 初始为空,由脚本写入首行 .cn 与次行 .en。
var body = el.querySelector('.yiyan');
if (body) {
var cn = body.querySelector('.cn');
var en = body.querySelector('.en');
if (cn && en) {
cn.textContent = quote.en;
en.textContent = quote.cn;
} else {
body.innerHTML = '';
var lineCn = document.createElement('div');
lineCn.className = 'cn';
lineCn.textContent = quote.en;
var lineEn = document.createElement('div');
lineEn.className = 'en';
lineEn.textContent = quote.cn;
body.appendChild(lineCn);
body.appendChild(lineEn);
}
}
el.classList.remove('is-loading');
el.classList.remove('is-error');
el.classList.add('is-ready');
@@ -37,8 +53,8 @@
.catch(function () {
el.classList.remove('is-loading');
el.classList.add('is-error');
var cn = el.querySelector('.cn');
if (cn && !el.classList.contains('is-ready')) cn.textContent = '加载失败,点击重试';
var body = el.querySelector('.yiyan');
if (body && !el.classList.contains('is-ready')) body.textContent = '加载失败,点击重试';
})
.finally(function () {
delete el.dataset.loading;
@@ -70,8 +86,6 @@
});
}
window.JioYiyan = { init: init };
if (window.jQuery) {
window.jQuery(document).off('auto_fun.jio-yiyan').on('auto_fun.jio-yiyan', function () {
init(document);
+2 -11
View File
@@ -43,17 +43,8 @@
.jio-widget--affix { position: sticky; top: 76px; }
.jio-widget--only-mobile { display: none; }
.jio-widget-search { display: flex; min-height: 42px; padding: 4px; border: 1px solid var(--main-border-color,rgba(127,127,127,.18)); border-radius: var(--main-radius,8px); background: var(--main-bg-color, #fff); }
.jio-widget-search label { flex: 1; display: flex; }
.jio-widget-search input { width: 100%; padding: 8px 12px; border: 0; outline: 0; background: transparent; color: inherit; }
.jio-widget-search button { display: flex; align-items: center; gap: 7px; padding: 7px 14px; border: 0; border-radius: var(--mini-radius,4px); background: var(--focus-color, #ff5473); color: #fff; cursor: pointer; }
.jio-widget-search--compact button span { display: none; }
.jio-widget-search--large { min-height: 58px; border-radius: 14px; }
.jio-widget-quote { margin: 0; padding: 12px 15px; border-radius: var(--jio-widget-radius); background: var(--main-bg-color, #fff); color: var(--main-color, inherit); box-shadow: 0 0 10px var(--main-shadow, rgba(116,116,116,.08)); }
.jio-widget-quote .yiyan { line-height: 1.8; }
.jio-widget-quote .yiyan .en { font-size: .9em; opacity: .8; }
.jio-widget-quote.is-loading { opacity: .65; }
/* 搜索框与一言复用 main.css 中的参考卡片(.search-input / .yiyan-box),
* 这里不再重复定义表面样式,避免与卡片叠加。 */
/* The Jio base stylesheet already carries the icon-card and utility rules.
* Restore the one renamed primitive used verbatim by these two widget renderers. */
-6
View File
@@ -74,11 +74,6 @@
}
}
function initQuote(figure) {
if (!once(figure, 'Quote')) return;
if (window.JioYiyan) window.JioYiyan.init(figure);
}
function errorMarkup(page, append) {
var i18n = config.i18n || {};
return '<div class="jio-widget-request-error" role="alert"><span>' + (i18n.error || '加载失败,请重试。') + '</span><button type="button" data-widget-retry data-retry-page="' + page + '" data-retry-append="' + (append ? '1' : '0') + '">' + (i18n.retry || '重试') + '</button></div>';
@@ -357,7 +352,6 @@
function scan(root) {
var scope = root || document;
scope.querySelectorAll('.jio-widget-video[data-video-url]').forEach(initVideo);
scope.querySelectorAll('.jio-widget-quote').forEach(initQuote);
if (scope.matches && scope.matches('[data-widget-items]')) initItems(scope);
scope.querySelectorAll('[data-widget-items]').forEach(initItems);
scope.querySelectorAll('.widget-tab-post').forEach(initTabs);