402 Commits
Author SHA1 Message Date
kate522 0a4448dd70 收紧顶部卡片与下方主卡片的间距 2026-09-14 12:53:20 +08:00
kate522 632a7d15ba fix(user): replicate level center page 2026-09-13 21:28:10 +08:00
kate522 129eb25078 fix(email): lock templates to built-in catalog 2026-09-13 20:02:56 +08:00
kate522 3f02048bc5 test(admin): read the picker css before asserting the hidden guard 2026-09-06 16:38:42 +08:00
kate522 abf3a4ae31 fix(admin): re-assert [hidden] inside the icon modal so tabs and search switch 2026-09-06 16:37:11 +08:00
kate522 af04fcfd3c fix(admin): bind FaIconPicker with v-model so icon clicks update the value 2026-09-06 16:10:28 +08:00
kate522 2e25894eb5 fix(navigation): stop mangling zibsvg/customsvg menu icons
aksrt_render_menu_icon() prefixed any value without an fa substring
with fa fas fa-, turning picker values like zibsvg-hot into
fa fas fa-zibsvg-hot — blank icons in the frontend nav. Sprite and
inline SVG values now flow through aksrt_icon_markup with the
menu-item-icon classes attached; FA values keep the legacy padding.
2026-09-06 14:27:49 +08:00
kate522 7ab5f29f87 fix(icons): render brand icons under the fa fab double prefix and drop an empty sprite key
FA5's own single-class declarations lose the cascade to the later
.fa,.far,.fas family rule, so zibll-legacy values like "fa fab fa-weixin"
rendered with the Free font and came up blank — visible in the picker's
brand tab (500px…zhihu) and on every brand icon in the SPA and frontend
social links. Re-assert .fa.fab (and .fa.far weight) in the three
stylesheets that load FA5. Also remove the empty aksrt_svgs['qqww']
sprite entry, which surfaced as a blank built-in SVG item.
2026-09-06 13:31:24 +08:00
kate522 2e9650d15f test(widgets): contract-lock the universal icon picker
Assert the generated FA5 catalog, the REST route + sprite single
source, picker field wiring in widgets and nav menus, SVG-aware icon
sanitization on both save paths, the single aksrt-font-awesome handle
with FA5 class names, and the consolidated assets/icons layout.
2026-09-06 13:00:13 +08:00
kate522 e4745d501e refactor(icons): converge every icon render on aksrt_icon_markup
aksrt_get_comment_icon(), aksrt_renderer_svg_icon() and the widget
renderer's private icon_markup() all delegate to the unified helper,
and the duplicated 24px empty-state SVGs in user-center/user-home now
come from one aksrt_empty_state_svgs(). Contract tests follow the
delegation (sprite <use> markup asserted in the helper).
2026-09-06 12:59:44 +08:00
kate522 9496db5171 fix(single): place the video footer breadcrumb like the reference
Drop the invented .post-breadcrumbs wrapper and echo the breadcrumb
inside the reference's flex jsb at row; split .single-video .breadcrumb
out of the cover-overlay rule (-6px pull and opacity reset belong to
title-over-cover contexts only) and restore the legacy 15px footer
padding. Pin the structure in the cover contract test and rebuild the
homepage aggregates.
2026-09-06 11:26:21 +08:00
kate522 d3eef19b95 fix(single): match the reference video cover height (bare ratio)
Zibll reserves +50px only for covers whose title overlays them
(image/slide via .single-cover/.single-cover-slide); the video cover
keeps its title in the footer below and uses the bare scale height
(.dplayer-scale-height). Drop the +50px from the video box, pin the
reference height matrix in the contract test, and refresh the stale
slide-action assertion in the toast contract.
2026-09-06 11:12:13 +08:00
kate522 7c0d5945ca fix(single): stop the video cover letterboxing inside its ratio box
The player init wrote an inline object-fit:contain on the video
element, which outranked the injected stylesheet's object-fit:cover
fill contract and left black bars above/below whenever the cover box
ratio differed from the video. Drop the inline style so the
stylesheet rule is the single source of truth, and pin the
no-inline-style rule in the cover contract test.
2026-09-06 11:00:04 +08:00
kate522 6ffc5ba3d6 fix(submit): drop the redundant featured preview type badge
The reference theme renders no type badge in the featured box; the
swiper and dplayer previews are self-explanatory. Remove it from both
preview branches and delete the now-unused CSS rule.
2026-09-06 10:47:24 +08:00
kate522 b7f5523874 fix(submit): render slide cover preview as a real swiper
Replace the static first-image preview with the reference theme's
.new-swiper contract (loop + autoplay + prev/next + pagination) in both
the server-rendered box and the JS re-render, and run auto_fun for
slide covers so new_swiper initializes them.
2026-09-06 10:39:39 +08:00
kate522 d0c6c3e431 feat(submit): fold slide cover into multi-select image picker
Match the featured cover buttons row to the reference theme: drop the
dedicated slide button, let the icon-only image picker select multiple
images into a slide cover (single pick stays an image cover), and align
the loaded-state visibility matrix.
2026-09-06 10:30:27 +08:00
kate522 1a0b023658 fix(submit): raise TinyMCE fullscreen above the fixed navbar
TinyMCE's skin injects .mce-fullscreen { z-index: 100 } at editor init,
after core editor.css, so the fullscreen editor (toolbar at the viewport
top) lost to the fixed navbar (.nav-fixed .header, z-index 999). Restore
core's intended 100010 with an element+class selector that outranks the
skin regardless of injection order; it stays below the submit media
dialog (100080). Also remove the dead .mce-top-part.affix rules (no
AKSRT script drives them) and pin both in a contract test.
2026-09-06 10:10:20 +08:00
kate522 daee4cd67f feat(submit): make video cover row icon-only with hover titles
Replace the video-pic/video/clear button labels with icon-only buttons
carrying title + aria-label (设置视频封面/视频/清除), center the glyphs
via flex to fix the upward icon shift, rename the media picker title to
为视频设置封面, and drop the unused setVideoCover i18n key. Contract
test updated to pin the new markup and string set.
2026-09-06 10:10:12 +08:00
kate522 51a591e2b9 feat(submit): add video cover picker with playable video preview
Featured video preview now renders a real DPlayer (video-url/video-pic)
like the reference theme instead of a static image, so the cover video
plays on the submit page. Top-right bar gains the video-cover button
shown only when a video cover is loaded; backend honors pic_id and no
longer deletes the thumbnail before cover validation. Drop dead i18n
keys and data-can-* attributes.
2026-09-05 23:41:22 +08:00
kate522 d84d485ec7 refactor(submit): remove unused aksrt_update_post ajax endpoint
No caller anywhere: front JS updates via aksrt_submit_post (posts_id),
guests via aksrt_save_draft. Re-pin the one-captcha-admission contract
to ajax_submit_post, the only non-draft entry point.
2026-09-05 23:41:12 +08:00
kate522 5fbcfa2b49 fix data-aksrt-video 属性 2026-09-05 22:28:19 +08:00
kate522 5a61e68a8c fix(video): guard sourceless player play attempts 2026-09-05 22:04:24 +08:00
kate522 51dd38163d fix(submit): keep sidebar visible on front submit page 2026-09-05 21:50:40 +08:00
kate522 49ffdc6ab2 fix(runtime): remove obsolete jQuery compatibility assets 2026-09-05 21:31:11 +08:00
kate522 4a12de38cb fix(runtime): use compatible WordPress jQuery 2026-09-05 20:48:18 +08:00
kate522 d64c4cf1b4 fix single-post.css 2026-09-05 20:10:07 +08:00
kate522 d86147f406 fix(single): fill slide and video cover media like the image cover
Slide-mode images rendered at intrinsic ratio, top-aligned inside the
swiper chain (--pc-height:auto left .swiper-wrapper content-sized), so
the taller box showed a gap at the bottom and never center-cropped like
the image cover. The video cover had the same problem through
video-player.js (height:auto, capped at 70vh).

- aksrt_render_slider scale mode emits --pc-height/--m-height 100% so
  the wrapper/slide/img chain fills the ratio box and object-fit: cover
  center-crops inside it (same pattern as the .scale-height widgets)
- video-player.js renders the video at height:100% + object-fit:cover;
  with an undimensioned container height:100% degrades to auto,
  matching the previous behavior
- drop the dead .single-cover padding-bottom rules (every producer owns
  its height inline, and the rule squeezed the absolutely positioned
  slide inner) and the orphaned --single-cover-scale var in
  tokens.css/compat-vars.css/main.css/InlineStyleBuilder
- rebuild public bundles; extend the single-cover-height contract
2026-09-05 18:53:45 +08:00
kate522 9fa7190232 test(submit): align toast contract with unified media picker
f3fcfe45 moved featured/slide/video cover uploads into the shared
AksrtSubmitMedia picker, which owns the fixed-id load/success/danger
flow under aksrt-front-submit-editor-media-toast, and pay downloads now
only add a success confirmation with the resource-upload id. Update the
contract accordingly: drop the obsolete featured-upload/slide-upload/
video-cover ids and the image/slide/videoToastId variable assertions,
and assert instead that all three cover actions route through
AksrtSubmitMedia.open and that the picker keeps its fixed-id flow.
2026-09-05 18:22:59 +08:00
kate522 4f2d17f6ee fix(single): align slide and video cover heights with image cover
The image-mode cover reserves +50px for the title/breadcrumb overlay
(calc(scale% + 50px)), but the slide cover wrapper was given a bare
inline padding-bottom by aksrt_render_slider, permanently defeating the
.cover-slide rule, and the video cover used a bare video_scale%.

- aksrt_render_slider: add scale_extra so scale mode emits
  calc(ratio% + extra); the single cover passes 50px so all three
  modes share one height formula
- drop the unreachable static slide fallback and function_exists guard
  (the helper is unconditionally loaded by inc/bootstrap.php), the
  always-true cover_url/ep_count conditions, and the dead --scale-ratio
  and inner swiper padding emitted in scale mode
- remove the dead cover CSS cluster with no producer: .single-cover-slide
  (main.css/main.min.css/cover.css), .single-cover-slider family
  (components/base.css), .single-cover-slide-wrap and .single-cover__*
  helpers (cover.css), and initSlideCovers in misc.js
- rebuild public bundles via tools/build-public-assets.mjs
- add single-cover-height-contract test covering the shared formula
  and the dead-code removals
2026-09-05 18:22:37 +08:00
kate522 05a6b6fc54 fix 更多栏目 2026-09-05 17:32:18 +08:00
kate522 1839150ecb fix(sidebar): collapse empty sidebar column on every scene
Sidebar visibility had two disconnected decisions: the body site-layout-*
class (via aksrt_is_show_sidebar_filter) only checked widget activity for
singles, while the homepage aside renderer skipped the column and
sidebar.php rendered an empty one. With the toggle on and no widgets, the
homepage kept a reserved gutter and squeezed the main content aside.

- collapse every scene to no-sidebar when the sidebar widget stack is empty
- resolve home_sidebar before the page branch so a static front page is
  checked against the zones the homepage renders
- guard the homepage aside with aksrt_is_show_sidebar() alone and drop the
  duplicate aksrt_homepage_has_sidebar gate
- early-return sidebar.php instead of rendering an empty column
- drop dead code: archive helper $preferred param, wp_is_mobile fallback,
  container--no-sidebar class, unreachable front-page fallback
- update post-visual-contract to pin the single visibility decision

Verification: php -l on all changed files; node --test
tests/widget-system/*.test.cjs 242/243 (the toast-contract failure is
pre-existing and unrelated).
2026-09-05 15:40:11 +08:00
kate522 4eb2ddef66 fix(widgets): keep slider media combo PC layout flex in admin preview
后台模板预览只加载 frontend.css,不加载 main.css 的 .flex 工具类,
PC 端两列因此退化为 block 上下堆叠;在 widget 自有样式层显式声明
display:flex(移动端媒体查询的 display:block/flex 覆盖不受影响)
2026-09-05 14:30:39 +08:00
kate522 65a69b1dec fix(widgets): align slider media combo with the Zibll reference
- 渲染器:幻灯片按参考补回 span/a 包裹、lazyload swiper-lazy 懒加载契约、
  视频背景与图层视差属性条件;组合模块补回 is_show 门控、超管缺省提示、
  widget-graphic-cover mb 类与内层样式容器、卡片列入场动画类与 lazy_cover 开关
- Schema:幻灯片/图层/卡片字段补齐 library、unit、参考描述文案与分组按钮标题
- 后台表单:分组按钮文案(添加幻灯片/添加卡片/添加图层)、行编号格式、
  视频上传不渲染图片预览(FormRenderer + admin.js)
- 契约测试:新增 slider media combo 前后台参考契约断言

验证:php -l 全部通过;run.php 133 断言;node --test 243 项(仅主干既有
toast-contract 失败);validate-widget-golden 通过
2026-09-05 14:17:03 +08:00
kate522 d7950730dd fix(widgets): keep widget-content an unstyled structural layer
Reference contract: widget cards carry their own 15px padding and
.widget-content is bare. The added 20px padding inset every widget
card from the content max width on the fixed homepage (the only
bundle loading sidebar.css).

- drop the root padding rule and the unreferenced --flush modifier
- drop the now-redundant user-widget padding:0 workaround
- drop the dead --card-padding-lg token
- lock the contract with negative assertions in the display test
2026-09-05 13:26:52 +08:00
kate522 b639d57c5b feat(widgets): replicate 12 reference widgets for full Zibll parity
- rewrite schemas for posts, tab_posts, oneline_posts, hot_posts,
  term_cards, term_aggregation, media_cards, combo_info, partners,
  recent_comments, posts_toc and slider_media_combo to mirror the
  modern reference modules field by field (options, defaults,
  dependencies, min/max/step, subheadings)
- port reference renderers: hot ranking with TOP badges, category
  aggregation card, graphic cover cards, partners CSS marquee,
  combo info cards with auto band palette, recent comment list
- rename 分类与标签聚合卡片 to 分类聚合卡片 and restrict it to
  categories (no tags/topics branch in this project)
- drop topics filter fields and the topics query branch; align
  orderby value domain with supported post meta
- add searchable sortable terms admin field type and spinner unit
  suffix rendering
- unify widget pagination and lazy loading on the REST client with
  the runtime-owned ias reveal trigger; remove the legacy
  post_ajax_trigger dual path
- align section-navs TOC with the reference contract (wznav ids,
  3-heading minimum, zib-widget box)
2026-09-05 11:28:00 +08:00
kate522 9dc278bd83 fix payment points 2026-09-04 23:35:19 +08:00
kate522 f3fcfe45da feat(submit): add user media library 2026-09-04 22:53:33 +08:00
kate522 44e165d34e fix(comments): align image upload with Zibll
Unify comment image upload settings, REST permissions, preview, progress,
and response handling while removing obsolete compatibility paths.
2026-09-04 19:52:56 +08:00
kate522 129432ae45 进行了小优化 2026-09-04 18:48:57 +08:00
kate522 8af1b9ac4b fix(runtime): remove legacy action endpoint 2026-09-04 14:28:57 +08:00
kate522 05f40d7728 fix(email): set sender before PHPMailer init 2026-09-04 13:56:11 +08:00
kate522 dda343e398 fix(email): derive SMTP auth from credentials 2026-09-04 13:24:26 +08:00
kate522 4833053a5c fix(email): complete mail settings and templates 2026-09-04 12:06:42 +08:00
kate522 4f8ab94fac fix(widgets): align user card action buttons 2026-09-03 21:33:30 +08:00
kate522 7308f055c7 fix(frontend): keep asset and homepage filters in DOM 2026-09-03 19:21:24 +08:00
kate522 a0adddce59 fix(captcha): wait for runtime before sign-in 2026-09-03 13:59:07 +08:00
kate522 9d458dd99a fix(runtime): remove stale aksrt namespace dependency 2026-09-03 13:24:51 +08:00
kate522 5fd7c212ed fix(runtime): 按参考主题硬切换为 loader/main/auto_fun 单一 DOM 生命周期
- 删除 AksrtFrontend registry/rehydrate 双路架构及 build/public.js 拼包入口,
  前台唯一初始路径为 PHP 本地栈(jQuery 1.9.1 → Bootstrap 3.4.1)
  → loader_js(_win/aksrtData 唯一注入)→ tbquire(['main']) → runtime/main.min.js
- window.auto_fun = debounce(z_auto_fun, 100) 为唯一重扫入口;所有模块改为
  执行一次 + off/on('auto_fun.aksrt-*') 命名空间重扫,data/class 标记幂等
- 局部更新协议统一:HTML 注入 → post_ajax.ed → auto_fun();
  远程 modal → loaded.bs.modal → auto_fun();JSON 成功 → zib_ajax.success
- 灯箱恢复 Miniimgbox/imgbox 唯一 owner(imgbox-container、a[data-imgbox]、
  imgbox_data),删除 AksrtLightbox/data-aksrt-lightbox 第二实现及 CSS/overlay,
  _win.imgbox* 重新接上 post-display 设置
- 死代码清理:runtime 下 11 组被自有实现替代的旧模块副本、无消费 vendored 库、
  顶层 grade.min.js、revenue.js、无调用方的 aksrt_get_win_runtime_config(),
  以及 loader 中 16 条死 mapping
- PHP 入队改为本地栈 + loader_js,routed/widget/submit 依赖统一换绑;
  用户卡片发布按钮恢复 nav_user_newposts_btn 设置门控
- 测试对齐:新增 frontend-lifecycle-contract,重写 navigation/lazyload/toast/
  auth-source/comment/page-display/post-visual 等断言为目标架构契约

验证:node --test widget-system+navigation 223 通过 0 失败;
构建脚本重建 main/imgbox min 与 CSS bundles;改动 PHP php -l、JS node --check
全部通过;git diff --check 干净;credits 重入 harness 通过。
2026-09-03 12:44:31 +08:00
kate522 9e6ee55de9 test(navigation): 契约断言对齐打包后的运行时架构
- 依赖图测试:jquery deregister/单文件注册断言改为断言 jquery-core 收敛、
  aksrt-runtime 指向 public.js,以及打包工具纳入 bootstrap/fontawesome5/
  main.min.css/loader/main.min
- header DOM 测试:移除已废弃的 nav_user_newposts_btn 与 navbar-but 断言,
  改断言 navbar-newposts 与 header-userbox.css 进入 public.css 打包清单
2026-09-02 21:49:41 +08:00
kate522 1f4a39d8f8 feat(runtime): 全站前端脚本统一接入 AksrtFrontend 全局 DOM 生命周期
- rehydrate.js 新增 boot()/aksrt:ready 事件,支持 boot 后晚注册立即以 init 触发
- aksrt-runtime.js 初始加载改走 AksrtFrontend.boot,tooltip/倒计时注册为组件
- 约 30 个前端脚本(首页、评论、支付、路由、页面叶子、widgets)
  从直接 DOMContentLoaded 迁移为 AksrtFrontend.register,并加幂等标记
- section-navs 依赖改为 aksrt-runtime,保证注册时序
- 清理死代码:删除孤儿 loader.js/main.js 及 runtime/page-navs 遗留副本
- loader.js 移除已迁移模块的 tbquire 路径映射,main.js 相应瘦身
- build-public-assets.mjs 增加 runtime/main.min.js 自动压缩步骤
- 新增 4 个契约测试(homepage-dom/rehydrate-runtime/global-dom-init/
  public-bundle-parity),3 个既有 harness 适配注册表初始化方式
2026-09-02 21:48:56 +08:00