进行了一些小修复
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
/.specs/
|
||||
/docs/
|
||||
/tools/*
|
||||
!/tools/build-public-assets.mjs
|
||||
/tests/*
|
||||
!/tools/wp-cli-visual-fixtures.php
|
||||
!/tests/fixtures/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,905 @@
|
||||
/* source: assets/css/frontend/homepage-fixed/base.css */
|
||||
/**
|
||||
* Homepage Fixed Layout — legacy Visual Parity
|
||||
*
|
||||
* Implements legacy's homepage visual language:
|
||||
* - System font stack with Chinese fallbacks
|
||||
* - 1200px container, 311px sidebar
|
||||
* - Post cards: list mode (190px thumb) + card mode (3-col grid)
|
||||
* - legacy shadow/radius/spacing values
|
||||
* - scale(1.02) thumbnail hover
|
||||
* - Lazy-load animations (blur/fade/scale)
|
||||
* - Full responsive: 1200/991/767/640px breakpoints
|
||||
*/
|
||||
|
||||
/* ================================================================
|
||||
0. ANIMATIONS
|
||||
================================================================ */
|
||||
|
||||
@keyframes aksrt-skeleton-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.4; }
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
1. HOMEPAGE CONTAINER & TYPOGRAPHY
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.42857143;
|
||||
color: var(--main-color, #4e5358);
|
||||
background: transparent;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
/* Slightly looser than stock legacy short pages: air between stream and footer */
|
||||
padding-bottom: 28px;
|
||||
}
|
||||
|
||||
.aksrt-homepage a[href] {
|
||||
transition: color 0.2s, background 0.3s, opacity 0.3s, box-shadow 0.3s, transform 0.3s;
|
||||
}
|
||||
|
||||
.aksrt-homepage .aksrt-skeleton {
|
||||
animation: aksrt-skeleton-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
2. LAYOUT SHELL
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__fluid-zone.content-shell,
|
||||
.aksrt-homepage__shell.content-shell {
|
||||
max-width: min(100%, var(--container, 1200px));
|
||||
}
|
||||
|
||||
.aksrt-homepage__fluid-zone.content-shell {
|
||||
padding-top: 18px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__hero {
|
||||
width: 100vw;
|
||||
max-width: 100vw;
|
||||
margin: 0 calc(-50vw + 50%) 24px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__hero .header-components-container {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__shell.content-shell {
|
||||
padding-top: 0;
|
||||
/* 36px + a bit more breathing room before footer */
|
||||
padding-bottom: 56px;
|
||||
}
|
||||
|
||||
/* Bottom fluid zone (if any) keeps a little gap above footer */
|
||||
.aksrt-homepage__fluid-zone--bottom {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.aksrt-homepage {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__shell.content-shell {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dual-column geometry is owned by body.site-layout-* float rules in layout.css. */
|
||||
.aksrt-homepage__content-layout {
|
||||
display: block;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.aksrt-homepage__fluid-zone.content-shell,
|
||||
.aksrt-homepage__shell.content-shell {
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone,
|
||||
.aksrt-homepage__fluid-zone,
|
||||
.aksrt-homepage__aside {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.aksrt-homepage__system-modules {
|
||||
gap: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone.aksrt-homepage__system-modules {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone--featured {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone--operated,
|
||||
.aksrt-homepage__content-zone--mid,
|
||||
.aksrt-homepage__content-zone--supplement {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone--supplement {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone .widget-card:last-child,
|
||||
.aksrt-homepage__aside .widget:last-child,
|
||||
.aksrt-homepage__fluid-zone .widget-fluid:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
3. FLUID WIDGETS
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__fluid-zone .widget-fluid {
|
||||
margin-bottom: 20px;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.aksrt-homepage .widget-fluid.widget_aksrt_tab_posts,
|
||||
.aksrt-homepage .widget-fluid.widget_aksrt_category_block,
|
||||
.aksrt-homepage .widget-fluid.widget_aksrt_category_tabs,
|
||||
.aksrt-homepage .widget-fluid.widget_aksrt_category_recommend {
|
||||
padding: 15px;
|
||||
background: var(--surface-1, #fff);
|
||||
border: none;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.aksrt-homepage__content-zone .widget-card,
|
||||
.aksrt-homepage__aside .widget {
|
||||
background: var(--surface-1, #fff);
|
||||
padding: 15px;
|
||||
border: none;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
4. STREAM CONTAINER
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__stream-header {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream-intro {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream-title {
|
||||
margin: 0;
|
||||
color: var(--color-ink);
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream-subtitle {
|
||||
margin: 0;
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream,
|
||||
.aksrt-homepage__stream.widget-card {
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
5. TABS
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__tabs,
|
||||
.aksrt-homepage__titlebox {
|
||||
margin-bottom: 6px;
|
||||
padding-bottom: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.box-body,
|
||||
.aksrt-homepage__titlebox.box-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs-sentinel {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.home-tab-nav-box {
|
||||
position: static;
|
||||
z-index: auto;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"] {
|
||||
position: sticky;
|
||||
top: var(--nav-height, 60px);
|
||||
z-index: 995;
|
||||
background: transparent;
|
||||
transition: background-color 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
border-radius 0.2s ease,
|
||||
padding 0.2s ease,
|
||||
margin 0.2s ease,
|
||||
backdrop-filter 0.2s ease,
|
||||
-webkit-backdrop-filter 0.2s ease;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
|
||||
margin-bottom: 14px;
|
||||
padding: 10px 16px;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border: none;
|
||||
border-radius: var(--radius-2xl, 16px);
|
||||
box-shadow: var(--shadow);
|
||||
backdrop-filter: saturate(1.6) blur(20px);
|
||||
-webkit-backdrop-filter: saturate(1.6) blur(20px);
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
|
||||
html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed,
|
||||
html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
|
||||
html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
|
||||
background: rgba(24, 24, 24, 0.82);
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-list {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__admin-link {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.scroll-x {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-item {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-radius: 20px;
|
||||
font-weight: 500;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-button {
|
||||
padding: 6px 14px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--color-ink);
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
font-weight: inherit;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
border-radius: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-button:hover {
|
||||
color: var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-item.is-active {
|
||||
background: var(--color-primary, var(--color-primary));
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-item.is-active .aksrt-homepage__tab-button,
|
||||
.aksrt-homepage__tab-button[aria-selected="true"] {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
6. SORTBAR + VIEW TOGGLE
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__sortbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 0 0 8px;
|
||||
border-bottom: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar-link {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
color: var(--color-ink-3, #777);
|
||||
text-decoration: none;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar-link:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar-link + .aksrt-homepage__sortbar-link::before {
|
||||
content: "\00b7";
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
color: var(--color-ink-4, #b1b1b1);
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar-link:hover,
|
||||
.aksrt-homepage__sortbar-link.is-active {
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.aksrt-homepage__view-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-left: auto;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.aksrt-homepage__view-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--color-ink-4, #999);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, background 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-homepage__view-btn:hover {
|
||||
color: var(--color-ink);
|
||||
background: var(--surface-2, #eee);
|
||||
}
|
||||
|
||||
.aksrt-homepage__view-btn.is-active {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.aksrt-homepage__view-btn svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.title-theme {
|
||||
position: relative;
|
||||
padding-left: 1.2em;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.title-theme::before {
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
bottom: 10%;
|
||||
left: 2px;
|
||||
width: 4px;
|
||||
content: "";
|
||||
background: var(--color-primary);
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 3px -1px var(--color-primary);
|
||||
}
|
||||
|
||||
.aksrt-homepage__page-indicator {
|
||||
margin-left: 10px;
|
||||
font-size: 80%;
|
||||
font-weight: 400;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.aksrt-homepage__panel[hidden],
|
||||
.index-tab-main .tab-pane[hidden],
|
||||
.home-tab-content .tab-pane[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.aksrt-homepage__panels,
|
||||
.home-tab-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.aksrt-homepage__panel {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.aksrt-homepage__panel.is-active,
|
||||
.aksrt-homepage__panel.active,
|
||||
.aksrt-homepage__panel.fade.in,
|
||||
.aksrt-homepage__panel.tab-pane.active,
|
||||
#index-tab-main.aksrt-homepage__panel,
|
||||
.home-tab-content .tab-pane.is-active,
|
||||
.home-tab-content .tab-pane.show,
|
||||
.home-tab-content .tab-pane.active,
|
||||
.aksrt-homepage__panel.show {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.home-tab-content .tab-pane.fade.is-active,
|
||||
.home-tab-content .tab-pane.fade.show,
|
||||
.home-tab-content .tab-pane.fade.active,
|
||||
#index-tab-main.fade {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.aksrt-homepage__panel-contract {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.flex.xx,
|
||||
.xx {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex1,
|
||||
.flex-1 {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.jsb,
|
||||
.jb {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ac {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
11. PAGINATION
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__panel-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__more,
|
||||
.aksrt-homepage .aksrt-load-more-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
|
||||
border-radius: var(--radius, 8px);
|
||||
background: var(--surface-1, #fff);
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
|
||||
.aksrt-homepage__more:hover,
|
||||
.aksrt-homepage .aksrt-load-more-btn:hover {
|
||||
color: var(--color-primary, var(--color-primary));
|
||||
border-color: var(--color-primary, var(--color-primary));
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.aksrt-homepage .ajax-pagination {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage .navigation.pagination .nav-links,
|
||||
.aksrt-homepage .pagination {
|
||||
gap: 0;
|
||||
margin: 20px 0 10px;
|
||||
}
|
||||
|
||||
.aksrt-homepage .navigation.pagination .page-numbers,
|
||||
.aksrt-homepage .pagination .page-numbers {
|
||||
min-width: 34px;
|
||||
height: 34px;
|
||||
padding: 0 10px;
|
||||
margin: 3px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-xs, 3px);
|
||||
background: var(--surface-4, #eee);
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.aksrt-homepage .navigation.pagination .page-numbers:hover,
|
||||
.aksrt-homepage .pagination .page-numbers:hover {
|
||||
opacity: 1;
|
||||
background: var(--color-primary-soft);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.aksrt-homepage .navigation.pagination .current,
|
||||
.aksrt-homepage .pagination .current {
|
||||
background: var(--color-primary, var(--color-primary)) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
12. SIDEBAR
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage__aside > .aksrt-panel,
|
||||
.aksrt-homepage__aside > .widget {
|
||||
margin-bottom: 15px;
|
||||
padding: 15px;
|
||||
background: var(--surface-1, #fff);
|
||||
border: 0;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside > .aksrt-panel:last-child,
|
||||
.aksrt-homepage__aside > .widget:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget-list li,
|
||||
.aksrt-homepage__aside .widget_recent_entries li,
|
||||
.aksrt-homepage__aside .recent-posts-row {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget-title,
|
||||
.aksrt-homepage__content-zone .widget-title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget-title {
|
||||
position: relative;
|
||||
margin: 0 0 10px;
|
||||
padding-left: 1.2em;
|
||||
padding-bottom: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget-title::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
bottom: 10%;
|
||||
left: 2px;
|
||||
width: 4px;
|
||||
height: auto;
|
||||
background: var(--color-primary, var(--color-primary));
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 3px -1px var(--color-primary, var(--color-primary));
|
||||
transition: transform 0.4s ease;
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget_recent_entries li a,
|
||||
.aksrt-homepage__aside .widget-list li a {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget_recent_entries li {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget_search .search-field {
|
||||
height: 40px;
|
||||
border-radius: 30px;
|
||||
background: var(--surface-2, #eee);
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .widget_search .search-submit {
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
border-radius: 30px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .tag-cloud {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .tag-cloud a {
|
||||
padding: 4px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
border: 0;
|
||||
background: var(--surface-2, #eee);
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-homepage__aside .tag-cloud a:hover {
|
||||
background: var(--color-primary, var(--color-primary));
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aksrt-homepage .widget.notop,
|
||||
.aksrt-homepage .box-body.notop {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage .widget.nobottom,
|
||||
.aksrt-homepage .box-body.nobottom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage .widget.widget_custom_html {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
13. LOADING & EMPTY STATES
|
||||
================================================================ */
|
||||
|
||||
.aksrt-homepage .aksrt-loading-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream .no-results {
|
||||
padding: 32px 16px;
|
||||
text-align: center;
|
||||
color: var(--color-ink-4, #999);
|
||||
}
|
||||
|
||||
/* source: assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css */
|
||||
/* AJAX tab skeleton placeholder */
|
||||
.aksrt-homepage__tab-skeleton {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-item {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
background: var(--surface-1, #fff);
|
||||
border: none;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: var(--shadow-sm);
|
||||
animation: aksrt-skeleton-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-thumb {
|
||||
width: 190px;
|
||||
min-width: 190px;
|
||||
height: 133px;
|
||||
background: var(--surface-2, #eee);
|
||||
border-radius: var(--radius, 8px);
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-line {
|
||||
height: 14px;
|
||||
background: var(--surface-2, #eee);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-line:first-child {
|
||||
width: 70%;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-line:nth-child(2) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-skeleton-line:nth-child(3) {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
/* source: assets/css/frontend/homepage-fixed/ajax-tab-error-state.css */
|
||||
/* AJAX tab error state */
|
||||
.aksrt-homepage__tab-error {
|
||||
padding: 32px 16px;
|
||||
text-align: center;
|
||||
color: var(--color-ink-4, #999);
|
||||
font-size: 14px;
|
||||
background: var(--surface-1);
|
||||
border: none;
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-retry {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 12px;
|
||||
padding: 8px 16px;
|
||||
border: 1px solid var(--color-line);
|
||||
border-radius: var(--radius-btn, 4px);
|
||||
background: var(--surface-4, #fff);
|
||||
color: var(--color-ink-3, #777);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s, border-color 0.2s, background 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tab-retry:hover {
|
||||
color: var(--color-primary, var(--color-primary));
|
||||
border-color: var(--color-primary, var(--color-primary));
|
||||
background: var(--color-primary-soft);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
14. RESPONSIVE — TABLET (max-width: 991px)
|
||||
================================================================ */
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.aksrt-homepage__shell.content-shell,
|
||||
.aksrt-homepage__fluid-zone.content-shell {
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
15. RESPONSIVE — MOBILE (max-width: 767px)
|
||||
================================================================ */
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.aksrt-homepage__shell.content-shell {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Tab skeleton: smaller thumb */
|
||||
.aksrt-homepage__tab-skeleton-thumb {
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
height: 84px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
16. RESPONSIVE — SMALL MOBILE (max-width: 640px)
|
||||
================================================================ */
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.aksrt-homepage__stream-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__stream-subtitle {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs,
|
||||
.aksrt-homepage__titlebox {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__admin-link {
|
||||
margin-left: 0;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
|
||||
.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.aksrt-homepage__sortbar {
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Tab skeleton: adapt */
|
||||
.aksrt-homepage__tab-skeleton-thumb {
|
||||
width: 96px;
|
||||
min-width: 96px;
|
||||
height: 67px;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -146,7 +146,7 @@
|
||||
* Additive: does NOT alter the AKSRT .btn system above. Lets reused
|
||||
* legacy-style markup (.but / .badg / .b-* / .jb-* / .c-* / .but-group /
|
||||
* .but-average / .toggle-radius) render via the --this-* context-coloring vars.
|
||||
* The --this-* DEFAULTS are set on the base rule here (BEFORE the .b-*/.jb-*
|
||||
* The --this-* DEFAULTS are set on the base rule here (BEFORE the .b-* and .jb-*
|
||||
* modifiers) so the cascade resolves colored variants correctly; scoped to
|
||||
* .but/.badg (never :root) so .float-btn's own var(--this-*, fallback) stays intact.
|
||||
* Consumes --focus-color-opacity* from compat-vars.css.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+45
-109
@@ -46,47 +46,22 @@ trait ScriptsPart1b {
|
||||
wp_add_inline_style('aksrt-style', '.lazyloaded{--lazy-animation:lazy_scale!important;}');
|
||||
}
|
||||
|
||||
$core_bundle = get_template_directory() . '/assets/css/build/core.min.css';
|
||||
if (file_exists($core_bundle)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-core-bundle',
|
||||
$base_uri . '/assets/css/build/core.min.css',
|
||||
['aksrt-style'],
|
||||
filemtime($core_bundle) ?: $version
|
||||
);
|
||||
$core_dep = 'aksrt-core-bundle';
|
||||
} else {
|
||||
$tokens_path = get_template_directory() . '/assets/css/core/tokens.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-tokens',
|
||||
$base_uri . '/assets/css/core/tokens.css',
|
||||
['aksrt-style'],
|
||||
file_exists($tokens_path) ? (string) filemtime($tokens_path) : $version
|
||||
);
|
||||
foreach (['reset', 'typography', 'buttons', 'forms', 'alerts'] as $slug) {
|
||||
$core_path = get_template_directory() . '/assets/css/core/' . $slug . '.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-core-' . $slug,
|
||||
$base_uri . '/assets/css/core/' . $slug . '.css',
|
||||
['aksrt-tokens'],
|
||||
file_exists($core_path) ? (string) filemtime($core_path) : $version
|
||||
);
|
||||
}
|
||||
$core_dep = 'aksrt-tokens';
|
||||
}
|
||||
$core_bundle = get_template_directory() . '/assets/css/build/core.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-core',
|
||||
$base_uri . '/assets/css/build/core.css',
|
||||
['aksrt-style'],
|
||||
file_exists($core_bundle) ? (string) filemtime($core_bundle) : $version
|
||||
);
|
||||
|
||||
$ext_css_files = ['animations', 'components-ext', 'color-utilities'];
|
||||
foreach ($ext_css_files as $slug) {
|
||||
$ext_path = get_template_directory() . '/assets/css/core/' . $slug . '.css';
|
||||
if (file_exists($ext_path)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-ext-' . $slug,
|
||||
$base_uri . '/assets/css/core/' . $slug . '.css',
|
||||
[$core_dep],
|
||||
filemtime($ext_path) ?: $version
|
||||
);
|
||||
}
|
||||
}
|
||||
$public_bundle = get_template_directory() . '/assets/css/build/public.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-public',
|
||||
$base_uri . '/assets/css/build/public.css',
|
||||
['aksrt-core', '_fontawesome'],
|
||||
file_exists($public_bundle) ? (string) filemtime($public_bundle) : $version
|
||||
);
|
||||
$core_dep = 'aksrt-public';
|
||||
|
||||
$deps = [$core_dep];
|
||||
$enqueue_module = function ($slug) use ($base_uri, $version, $deps) {
|
||||
@@ -99,16 +74,6 @@ trait ScriptsPart1b {
|
||||
);
|
||||
};
|
||||
|
||||
// AKSRT domain styles load after legacy main.css. The old aggregate is
|
||||
// intentionally not used because it contains the removed navigation CSS.
|
||||
$enqueue_module('base');
|
||||
$enqueue_module('header-userbox');
|
||||
$enqueue_module('card-primitives');
|
||||
$enqueue_module('overlay-primitives');
|
||||
$enqueue_module('layout');
|
||||
$enqueue_module('footer');
|
||||
$enqueue_module('floating-buttons');
|
||||
$enqueue_module('enhancements');
|
||||
if (!is_user_logged_in() || (bool) get_query_var('aksrt_sign')) {
|
||||
$auth_css = get_template_directory() . '/assets/css/routes/sign.css';
|
||||
wp_enqueue_style(
|
||||
@@ -119,19 +84,6 @@ trait ScriptsPart1b {
|
||||
);
|
||||
}
|
||||
|
||||
// 4a-b. 全局补充样式(骨架屏、空状态、分页、加载指示器)
|
||||
foreach (['skeleton', 'empty-state', 'pagination', 'ajax-spinner', 'modal-runtime'] as $slug) {
|
||||
$css_path = get_template_directory() . '/assets/css/frontend/' . $slug . '.css';
|
||||
if (file_exists($css_path)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-' . $slug,
|
||||
$base_uri . '/assets/css/frontend/' . $slug . '.css',
|
||||
[$core_dep],
|
||||
filemtime($css_path) ?: $version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Shared VIP purchase/poll coordinator for modal and credits surfaces.
|
||||
$vip_on = class_exists('\AKSRT\Settings\Settings')
|
||||
&& !empty(\AKSRT\Settings\Settings::get_payment_vip_settings()['enabled']);
|
||||
@@ -152,7 +104,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-vip-coordinator',
|
||||
$base_uri . '/assets/js/vip-purchase-coordinator.js',
|
||||
['aksrt-core-request'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($vip_coordinator),
|
||||
true
|
||||
);
|
||||
@@ -174,7 +126,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-pay-vip',
|
||||
$base_uri . '/assets/js/pay-vip.js',
|
||||
['loader_js', 'aksrt-lazy-image-attr', 'aksrt-core-request', 'aksrt-core-modal-runtime', 'aksrt-vip-coordinator', 'aksrt-notyf'],
|
||||
['aksrt-runtime', 'aksrt-vip-coordinator'],
|
||||
(string) filemtime($vip_js),
|
||||
true
|
||||
);
|
||||
@@ -313,7 +265,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-report',
|
||||
$base_uri . '/assets/js/report.js',
|
||||
['aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
filemtime($report_js_path) ?: $version,
|
||||
true
|
||||
);
|
||||
@@ -327,7 +279,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-author',
|
||||
$base_uri . '/assets/js/author.js',
|
||||
['loader_js', 'aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($author_js_path),
|
||||
true
|
||||
);
|
||||
@@ -415,7 +367,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-order-center',
|
||||
$base_uri . '/assets/js/order-center.js',
|
||||
['loader_js', 'aksrt-lazy-image-attr', 'aksrt-rehydrate', 'aksrt-core-request', 'aksrt-core-modal-runtime'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($order_center_js),
|
||||
true
|
||||
);
|
||||
@@ -427,14 +379,14 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-route-user-center-auth',
|
||||
$base_uri . '/assets/js/routes/user-center-auth.js',
|
||||
['loader_js', 'aksrt-core-request', 'aksrt-core-modal-runtime'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($identity_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
$user_center_deps = file_exists($identity_js)
|
||||
? ['loader_js', 'aksrt-route-user-center-auth', 'aksrt-notyf']
|
||||
: ['loader_js', 'aksrt-notyf'];
|
||||
? ['aksrt-runtime', 'aksrt-route-user-center-auth']
|
||||
: ['aksrt-runtime'];
|
||||
if ($has_orders_panel && wp_script_is('aksrt-order-center', 'registered')) {
|
||||
$user_center_deps[] = 'aksrt-order-center';
|
||||
}
|
||||
@@ -455,7 +407,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-search',
|
||||
$base_uri . '/assets/css/routes/search.css',
|
||||
['aksrt-tokens', 'aksrt-post-card'],
|
||||
['aksrt-public', 'aksrt-post-card'],
|
||||
$version
|
||||
);
|
||||
}
|
||||
@@ -465,7 +417,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-categories',
|
||||
$base_uri . '/assets/css/routes/categories.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
$version
|
||||
);
|
||||
}
|
||||
@@ -475,7 +427,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-friends',
|
||||
$base_uri . '/assets/css/routes/friends.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
file_exists(get_template_directory() . '/assets/css/routes/friends.css')
|
||||
? (string) filemtime(get_template_directory() . '/assets/css/routes/friends.css')
|
||||
: $version
|
||||
@@ -490,7 +442,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-page-navs',
|
||||
$base_uri . '/assets/js/page-navs.js',
|
||||
['aksrt-lazy-image-attr'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($page_navs_js),
|
||||
true
|
||||
);
|
||||
@@ -501,7 +453,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-posts-navs',
|
||||
$base_uri . '/assets/css/routes/posts-navs.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
(string) filemtime($pn_css)
|
||||
);
|
||||
}
|
||||
@@ -520,7 +472,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-posts-navs-page',
|
||||
$base_uri . '/assets/js/posts-navs-page.js',
|
||||
['jquery', 'aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($pn_js),
|
||||
true
|
||||
);
|
||||
@@ -534,7 +486,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-archives',
|
||||
$base_uri . '/assets/css/routes/archives.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
(string) filemtime($ar_css)
|
||||
);
|
||||
}
|
||||
@@ -547,7 +499,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-ban-appeal',
|
||||
$base_uri . '/assets/css/routes/ban-appeal.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
(string) filemtime($ba_css)
|
||||
);
|
||||
}
|
||||
@@ -556,7 +508,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-ban-appeal-page',
|
||||
$base_uri . '/assets/js/ban-appeal-page.js',
|
||||
['aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($ba_js),
|
||||
true
|
||||
);
|
||||
@@ -570,7 +522,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_style(
|
||||
'aksrt-messages',
|
||||
$base_uri . '/assets/css/frontend/messages.css',
|
||||
['aksrt-tokens'],
|
||||
['aksrt-public'],
|
||||
(string) filemtime($messages_css)
|
||||
);
|
||||
}
|
||||
@@ -651,7 +603,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-cms-download',
|
||||
$base_uri . '/assets/js/cms-download.js',
|
||||
['loader_js', 'aksrt-runtime', 'aksrt-core-request'],
|
||||
['aksrt-runtime'],
|
||||
file_exists($cms_download_js_path) ? (string) filemtime($cms_download_js_path) : $version,
|
||||
true
|
||||
);
|
||||
@@ -659,35 +611,19 @@ trait ScriptsPart1b {
|
||||
|
||||
if ($is_fixed_homepage) {
|
||||
$enqueue_module('post-card');
|
||||
$homepage_style_deps = ['_main', 'aksrt-layout', 'aksrt-post-card'];
|
||||
$homepage_style_deps = ['aksrt-public', 'aksrt-post-card'];
|
||||
$homepage_style_deps = array_values(array_filter(
|
||||
$homepage_style_deps,
|
||||
static fn(string $handle): bool => wp_style_is($handle, 'registered')
|
||||
));
|
||||
|
||||
// Enqueue leaf stylesheets directly so each file receives its own cache version.
|
||||
$homepage_style_parts = [
|
||||
'base',
|
||||
'ajax-tab-skeleton-placeholder',
|
||||
'ajax-tab-error-state',
|
||||
];
|
||||
$part_deps = $homepage_style_deps;
|
||||
foreach ($homepage_style_parts as $part_index => $part_name) {
|
||||
$is_last_part = $part_index === count($homepage_style_parts) - 1;
|
||||
$part_handle = $is_last_part
|
||||
? 'aksrt-homepage-fixed'
|
||||
: 'aksrt-homepage-fixed-' . sanitize_key($part_name);
|
||||
$part_relative_path = '/assets/css/frontend/homepage-fixed/' . $part_name . '.css';
|
||||
$part_path = get_template_directory() . $part_relative_path;
|
||||
|
||||
wp_enqueue_style(
|
||||
$part_handle,
|
||||
$base_uri . $part_relative_path,
|
||||
$part_deps,
|
||||
file_exists($part_path) ? (string) filemtime($part_path) : $version
|
||||
);
|
||||
$part_deps = [$part_handle];
|
||||
}
|
||||
$homepage_bundle = get_template_directory() . '/assets/css/build/homepage.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-homepage-fixed',
|
||||
$base_uri . '/assets/css/build/homepage.css',
|
||||
$homepage_style_deps,
|
||||
file_exists($homepage_bundle) ? (string) filemtime($homepage_bundle) : $version
|
||||
);
|
||||
}
|
||||
|
||||
// 积分相关:已登录 + 启用积分功能时全站加载
|
||||
@@ -700,7 +636,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-credits',
|
||||
$base_uri . '/assets/js/credits.js',
|
||||
['loader_js', 'aksrt-lazy-image-attr', 'aksrt-core-request', 'aksrt-core-modal-runtime', 'aksrt-vip-coordinator', 'aksrt-notyf'],
|
||||
['aksrt-runtime', 'aksrt-vip-coordinator'],
|
||||
file_exists($credits_js_path) ? (string) filemtime($credits_js_path) : $version,
|
||||
true
|
||||
);
|
||||
@@ -713,7 +649,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-signin',
|
||||
$base_uri . '/assets/js/signin.js',
|
||||
['aksrt-core-request', 'aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
file_exists($signin_js_path) ? (string) filemtime($signin_js_path) : $version,
|
||||
true
|
||||
);
|
||||
@@ -732,7 +668,7 @@ trait ScriptsPart1b {
|
||||
wp_enqueue_script(
|
||||
'aksrt-user-badge-actions',
|
||||
$base_uri . '/assets/js/user-badge-actions.js',
|
||||
['loader_js', 'aksrt-core-modal-runtime'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($badge_actions_path),
|
||||
true
|
||||
);
|
||||
|
||||
+44
-202
@@ -20,18 +20,6 @@ trait ScriptsPart1c {
|
||||
* Fonts / FA / global JS stack / aksrtData (split from enqueue_public).
|
||||
*/
|
||||
private function enqueue_public_fonts_js_and_data($base_uri, $core_dep, $deps, $is_fixed_homepage, $is_home_or_archive, $is_single_post, $is_single_resource, $version): void {
|
||||
$notyf_css = get_template_directory() . '/assets/css/frontend/notyf.css';
|
||||
wp_enqueue_style(
|
||||
'aksrt-notyf',
|
||||
$base_uri . '/assets/css/frontend/notyf.css',
|
||||
[$core_dep, '_fontawesome'],
|
||||
file_exists($notyf_css) ? (string) filemtime($notyf_css) : $version
|
||||
);
|
||||
|
||||
// ===== 7. JS =====
|
||||
|
||||
$needs_post_list_media = wp_style_is('aksrt-post-card', 'enqueued');
|
||||
|
||||
$runtime_uri = $base_uri . '/assets';
|
||||
$runtime_loader_path = get_template_directory() . '/assets/js/runtime/loader.js';
|
||||
$runtime_main_path = get_template_directory() . '/assets/js/runtime/main.min.js';
|
||||
@@ -95,26 +83,15 @@ trait ScriptsPart1c {
|
||||
]
|
||||
);
|
||||
|
||||
$lazy_image_attr_path = get_template_directory() . '/assets/js/lazy-image-attr.js';
|
||||
$public_runtime_path = get_template_directory() . '/assets/js/build/public.js';
|
||||
wp_enqueue_script(
|
||||
'aksrt-lazy-image-attr',
|
||||
$base_uri . '/assets/js/lazy-image-attr.js',
|
||||
'aksrt-runtime',
|
||||
$base_uri . '/assets/js/build/public.js',
|
||||
['loader_js'],
|
||||
file_exists($lazy_image_attr_path) ? (string) filemtime($lazy_image_attr_path) : $version,
|
||||
file_exists($public_runtime_path) ? (string) filemtime($public_runtime_path) : $version,
|
||||
true
|
||||
);
|
||||
|
||||
// AKSRT-only modules register after the legacy loader; navigation is owned by main.min.js.
|
||||
wp_enqueue_script(
|
||||
'aksrt-rehydrate',
|
||||
$base_uri . '/assets/js/rehydrate.js',
|
||||
['loader_js', 'aksrt-lazy-image-attr'],
|
||||
file_exists(get_template_directory() . '/assets/js/rehydrate.js')
|
||||
? (string) filemtime(get_template_directory() . '/assets/js/rehydrate.js')
|
||||
: $version,
|
||||
true
|
||||
);
|
||||
|
||||
// AJAX 调试(WP_DEBUG 或 ?aksrt_ajax_debug=1):记录所有失败的
|
||||
// jQuery ajax / fetch 请求,用于定位 vendor main.min.js 的 400 "0" 来源。
|
||||
if (function_exists('aksrt_ajax_debug_enabled') && aksrt_ajax_debug_enabled()) {
|
||||
@@ -122,114 +99,19 @@ trait ScriptsPart1c {
|
||||
wp_enqueue_script(
|
||||
'aksrt-ajax-debug',
|
||||
$base_uri . '/assets/js/core/ajax-debug.js',
|
||||
['loader_js'],
|
||||
['aksrt-runtime'],
|
||||
file_exists($ajax_debug_path) ? (string) filemtime($ajax_debug_path) : $version,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if ($needs_post_list_media) {
|
||||
$grade_js = get_template_directory() . '/assets/js/grade.min.js';
|
||||
wp_enqueue_script(
|
||||
'aksrt-grade',
|
||||
$base_uri . '/assets/js/grade.min.js',
|
||||
[],
|
||||
file_exists($grade_js) ? (string) filemtime($grade_js) : $version,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$notyf_js = get_template_directory() . '/assets/js/notyf.js';
|
||||
wp_enqueue_script(
|
||||
'aksrt-notyf',
|
||||
$base_uri . '/assets/js/notyf.js',
|
||||
['jquery'],
|
||||
file_exists($notyf_js) ? (string) filemtime($notyf_js) : $version,
|
||||
true
|
||||
);
|
||||
|
||||
// Runtime infrastructure: tbquire / confirm / scrollTopTo / [data-*] declarative
|
||||
$runtime_js = get_template_directory() . '/assets/js/aksrt-runtime.js';
|
||||
if (file_exists($runtime_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-runtime',
|
||||
$base_uri . '/assets/js/aksrt-runtime.js',
|
||||
['aksrt-rehydrate', 'aksrt-notyf'],
|
||||
(string) filemtime($runtime_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Follow toggle: delegated [data-aksrt-follow] handler; the buttons render on
|
||||
// user home / user center / single author bar and user cards anywhere.
|
||||
// Depends on aksrt-runtime because aksrtData (REST root + nonce) is localized
|
||||
// onto that handle and follow.js reads it at parse time.
|
||||
$follow_js = get_template_directory() . '/assets/js/follow.js';
|
||||
if (file_exists($follow_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-follow',
|
||||
$base_uri . '/assets/js/follow.js',
|
||||
['aksrt-notyf', 'aksrt-runtime'],
|
||||
(string) filemtime($follow_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Core modules (split from main.js) — register with AksrtFrontend
|
||||
$core_modules = [
|
||||
'aksrt-core-article' => 'article.js',
|
||||
'aksrt-core-comments' => 'comments.js',
|
||||
'aksrt-core-comment-fixed' => 'comment-fixed-input.js',
|
||||
'aksrt-core-comment-move' => 'comment-move-form.js',
|
||||
// Shared legacy-parity list/modal engines (before pagination consumers).
|
||||
'aksrt-core-ajax-list' => 'ajax-list.js',
|
||||
'aksrt-core-modal-telemetry' => 'modal-telemetry.js',
|
||||
'aksrt-core-request' => 'request.js',
|
||||
'aksrt-core-modal-cache' => 'modal-cache.js',
|
||||
'aksrt-core-modal-state' => 'modal-state.js',
|
||||
'aksrt-core-modal-runtime' => 'modal-runtime.js',
|
||||
'aksrt-core-modal-triggers' => 'modal-triggers.js',
|
||||
'aksrt-core-pagination' => 'pagination.js',
|
||||
'aksrt-core-archive' => 'archive.js',
|
||||
'aksrt-core-footer-tabbar' => 'footer-tabbar.js',
|
||||
'aksrt-core-misc' => 'misc.js',
|
||||
];
|
||||
$core_handles = [];
|
||||
foreach ($core_modules as $handle => $file) {
|
||||
$path = get_template_directory() . '/assets/js/core/' . $file;
|
||||
if (file_exists($path)) {
|
||||
// Depend on aksrt-runtime so window.aksrtData (localized below) is available.
|
||||
$deps = ['aksrt-rehydrate', 'aksrt-runtime'];
|
||||
if ($handle === 'aksrt-core-misc' && $needs_post_list_media) {
|
||||
$deps[] = 'aksrt-grade';
|
||||
} elseif ($handle === 'aksrt-core-modal-runtime') {
|
||||
$deps = array_merge($deps, [
|
||||
'aksrt-core-modal-telemetry',
|
||||
'aksrt-core-request',
|
||||
'aksrt-core-modal-cache',
|
||||
'aksrt-core-modal-state',
|
||||
]);
|
||||
} elseif ($handle === 'aksrt-core-modal-triggers') {
|
||||
$deps[] = 'aksrt-core-modal-runtime';
|
||||
}
|
||||
wp_enqueue_script(
|
||||
$handle,
|
||||
$base_uri . '/assets/js/core/' . $file,
|
||||
$deps,
|
||||
(string) filemtime($path),
|
||||
true
|
||||
);
|
||||
$core_handles[] = $handle;
|
||||
}
|
||||
}
|
||||
|
||||
// Code block enhancements (copy button + language label)
|
||||
$precode_js = get_template_directory() . '/assets/js/precode.js';
|
||||
if (file_exists($precode_js)) {
|
||||
if (is_singular() && file_exists($precode_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-precode',
|
||||
$base_uri . '/assets/js/precode.js',
|
||||
[],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($precode_js),
|
||||
true
|
||||
);
|
||||
@@ -237,11 +119,15 @@ trait ScriptsPart1c {
|
||||
|
||||
// Input field enhancements (auto-resize, counter, validation)
|
||||
$input_expand_js = get_template_directory() . '/assets/js/input-expand.js';
|
||||
if (file_exists($input_expand_js)) {
|
||||
$needs_input_enhancements = is_singular()
|
||||
|| (bool) get_query_var('aksrt_sign')
|
||||
|| (bool) get_query_var('aksrt_user_center')
|
||||
|| (bool) get_query_var('aksrt_author_identifier');
|
||||
if ($needs_input_enhancements && file_exists($input_expand_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-input-expand',
|
||||
$base_uri . '/assets/js/input-expand.js',
|
||||
[],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($input_expand_js),
|
||||
true
|
||||
);
|
||||
@@ -261,11 +147,11 @@ trait ScriptsPart1c {
|
||||
|
||||
// Section navs: article TOC / scrollspy
|
||||
$section_navs_js = get_template_directory() . '/assets/js/section-navs.js';
|
||||
if (file_exists($section_navs_js)) {
|
||||
if (is_singular() && file_exists($section_navs_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-section-navs',
|
||||
$base_uri . '/assets/js/section-navs.js',
|
||||
['aksrt-rehydrate', 'aksrt-runtime'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($section_navs_js),
|
||||
true
|
||||
);
|
||||
@@ -273,92 +159,35 @@ trait ScriptsPart1c {
|
||||
|
||||
// Video player (MP4/HLS/FLV)
|
||||
$video_player_js = get_template_directory() . '/assets/js/video-player.js';
|
||||
if (file_exists($video_player_js)) {
|
||||
if (is_singular() && file_exists($video_player_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-video-player',
|
||||
$base_uri . '/assets/js/video-player.js',
|
||||
[],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($video_player_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Image color extraction
|
||||
$color_extract_js = get_template_directory() . '/assets/js/color-extract.js';
|
||||
if (file_exists($color_extract_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-color-extract',
|
||||
$base_uri . '/assets/js/color-extract.js',
|
||||
[],
|
||||
(string) filemtime($color_extract_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// ===== 全局 UI 增强(骨架屏、悬停动效、灯箱、滚动感知)=====
|
||||
$enhancements_css = get_template_directory() . '/assets/css/frontend/enhancements.css';
|
||||
if (file_exists($enhancements_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-enhancements',
|
||||
$base_uri . '/assets/css/frontend/enhancements.css',
|
||||
[$core_dep],
|
||||
(string) filemtime($enhancements_css)
|
||||
);
|
||||
}
|
||||
|
||||
$enhancements_js = get_template_directory() . '/assets/js/enhancements.js';
|
||||
if (file_exists($enhancements_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-enhancements',
|
||||
$base_uri . '/assets/js/enhancements.js',
|
||||
['loader_js'],
|
||||
(string) filemtime($enhancements_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$enhancements2_js = get_template_directory() . '/assets/js/enhancements2.js';
|
||||
if (file_exists($enhancements2_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-enhancements2',
|
||||
$base_uri . '/assets/js/enhancements2.js',
|
||||
['loader_js'],
|
||||
(string) filemtime($enhancements2_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Reward (打赏)
|
||||
$reward_js = get_template_directory() . '/assets/js/reward.js';
|
||||
if (file_exists($reward_js)) {
|
||||
if (($is_single_post || $is_single_resource) && file_exists($reward_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-reward',
|
||||
$base_uri . '/assets/js/reward.js',
|
||||
['loader_js', 'aksrt-core-request'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($reward_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Effects (count-up, countdown, marquee, tilt, FPS detection)
|
||||
$effects_js = get_template_directory() . '/assets/js/effects.js';
|
||||
if (file_exists($effects_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-effects',
|
||||
$base_uri . '/assets/js/effects.js',
|
||||
['loader_js'],
|
||||
(string) filemtime($effects_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Yiyan (一言轮播)
|
||||
$yiyan_js = get_template_directory() . '/assets/js/yiyan.js';
|
||||
if (file_exists($yiyan_js)) {
|
||||
if (($is_single_post || $is_single_resource) && file_exists($yiyan_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-yiyan',
|
||||
$base_uri . '/assets/js/yiyan.js',
|
||||
[],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($yiyan_js),
|
||||
true
|
||||
);
|
||||
@@ -366,8 +195,16 @@ trait ScriptsPart1c {
|
||||
|
||||
// Frontend translate (默认关)
|
||||
// Content protection (copy notice / right-click / F12)
|
||||
$content_protect = class_exists('\AKSRT\Settings\Settings')
|
||||
? [
|
||||
'enabled' => (bool) \AKSRT\Settings\Settings::get_value('content_protect_enabled', false),
|
||||
'copy' => (bool) \AKSRT\Settings\Settings::get_value('content_protect_copy_notice', false),
|
||||
'right_click' => (bool) \AKSRT\Settings\Settings::get_value('content_protect_right_click', false),
|
||||
'devtools' => (bool) \AKSRT\Settings\Settings::get_value('content_protect_f12', false),
|
||||
]
|
||||
: [];
|
||||
$content_protect_js = get_template_directory() . '/assets/js/content-protect.js';
|
||||
if (file_exists($content_protect_js)) {
|
||||
if (in_array(true, $content_protect, true) && file_exists($content_protect_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-content-protect',
|
||||
$base_uri . '/assets/js/content-protect.js',
|
||||
@@ -378,8 +215,13 @@ trait ScriptsPart1c {
|
||||
}
|
||||
|
||||
// Site notice popup (global, controlled by Settings)
|
||||
$site_notice_config = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_system_notice_config()
|
||||
: [];
|
||||
$site_notice_enabled = !empty($site_notice_config['enabled'])
|
||||
&& trim((string) ($site_notice_config['content'] ?? '')) !== '';
|
||||
$site_notice_css = get_template_directory() . '/assets/css/frontend/site-notice.css';
|
||||
if (file_exists($site_notice_css)) {
|
||||
if ($site_notice_enabled && file_exists($site_notice_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-site-notice',
|
||||
$base_uri . '/assets/css/frontend/site-notice.css',
|
||||
@@ -388,11 +230,11 @@ trait ScriptsPart1c {
|
||||
);
|
||||
}
|
||||
$site_notice_js = get_template_directory() . '/assets/js/site-notice.js';
|
||||
if (file_exists($site_notice_js)) {
|
||||
if ($site_notice_enabled && file_exists($site_notice_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-site-notice',
|
||||
$base_uri . '/assets/js/site-notice.js',
|
||||
[],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($site_notice_js),
|
||||
true
|
||||
);
|
||||
@@ -400,11 +242,11 @@ trait ScriptsPart1c {
|
||||
|
||||
// One state machine owns modal and /sign/ authentication.
|
||||
$auth_js = get_template_directory() . '/assets/js/auth.js';
|
||||
if (file_exists($auth_js)) {
|
||||
if ((!is_user_logged_in() || (bool) get_query_var('aksrt_sign')) && file_exists($auth_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-auth',
|
||||
$base_uri . '/assets/js/auth.js',
|
||||
['aksrt-notyf', 'aksrt-runtime'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($auth_js),
|
||||
true
|
||||
);
|
||||
@@ -415,7 +257,7 @@ trait ScriptsPart1c {
|
||||
wp_enqueue_script(
|
||||
'aksrt-homepage-fixed',
|
||||
$base_uri . '/assets/js/homepage-fixed.js',
|
||||
['loader_js'],
|
||||
['aksrt-runtime'],
|
||||
file_exists($homepage_js_path) ? (string) filemtime($homepage_js_path) : $version,
|
||||
true
|
||||
);
|
||||
@@ -429,7 +271,7 @@ trait ScriptsPart1c {
|
||||
wp_enqueue_script(
|
||||
'aksrt-comment-tools',
|
||||
$base_uri . '/assets/js/comment-tools.js',
|
||||
['loader_js', 'aksrt-core-comment-fixed', 'aksrt-core-comment-move'],
|
||||
['aksrt-runtime'],
|
||||
file_exists($comment_tools_path) ? (string) filemtime($comment_tools_path) : $version,
|
||||
true
|
||||
);
|
||||
@@ -452,7 +294,7 @@ trait ScriptsPart1c {
|
||||
wp_enqueue_script(
|
||||
'aksrt-comment-ajax',
|
||||
$base_uri . '/assets/js/comment-ajax.js',
|
||||
['loader_js', 'aksrt-core-comments'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($comment_ajax_path),
|
||||
true
|
||||
);
|
||||
@@ -465,7 +307,7 @@ trait ScriptsPart1c {
|
||||
wp_enqueue_script(
|
||||
'aksrt-page-template',
|
||||
$base_uri . '/assets/js/page-template.js',
|
||||
['loader_js'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($page_template_path),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -57,7 +57,7 @@ if (file_exists($js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-front-submit',
|
||||
get_template_directory_uri() . '/assets/js/front-submit.js',
|
||||
['jquery', 'aksrt-notyf'],
|
||||
['aksrt-runtime'],
|
||||
(string) filemtime($js),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@ test('modal and sign page use one renderer and one state machine', () => {
|
||||
assert.match(shared, /data-auth-panel="bind"/);
|
||||
assert.match(shared, /data-auth-panel="oauth"/);
|
||||
assert.match(scripts, /assets\/js\/auth\.js/);
|
||||
assert.match(scripts, /'aksrt-notyf', 'aksrt-runtime'/);
|
||||
assert.match(scripts, /'aksrt-auth',[\s\S]*?assets\/js\/auth\.js[\s\S]*?\['aksrt-runtime'\]/);
|
||||
assert.doesNotMatch(scripts, /modal-auth\.js|sign-register\.js/);
|
||||
assert.doesNotMatch(runtime, /signsubmit-loader|tbquire\(\['sign-register'\]\)|\.on\('click', '\.(?:signin|signup)-loader'/);
|
||||
assert.doesNotMatch(loader, /sign-register/);
|
||||
|
||||
@@ -126,18 +126,20 @@ test('the legacy runtime owns lazySizes while AKSRT consumers share one image-at
|
||||
const bridge = read('assets/js/lazy-image-attr.js');
|
||||
const scripts = read('src/Core/ScriptsPart1c.php');
|
||||
const routeScripts = read('src/Core/ScriptsPart1b.php');
|
||||
const builder = read('tools/build-public-assets.mjs');
|
||||
const pagination = read('assets/js/core/pagination.js');
|
||||
const widgets = read('assets/widgets/frontend.js');
|
||||
|
||||
assert.match(runtime, /window\.lazySizes = lazySizes/);
|
||||
assert.match(bridge, /window\.aksrtGetLazyImageAttr = function/);
|
||||
assert.match(scripts, /'aksrt-lazy-image-attr'/);
|
||||
assert.match(scripts, /'aksrt-rehydrate'[\s\S]*?\['loader_js', 'aksrt-lazy-image-attr'\]/);
|
||||
assert.match(builder, /assets\/js\/lazy-image-attr\.js/);
|
||||
assert.match(builder, /assets\/js\/rehydrate\.js/);
|
||||
assert.match(scripts, /assets\/js\/build\/public\.js'[\s\S]*?\['loader_js'\]/);
|
||||
for (const file of ['pay-vip.js', 'order-center.js', 'page-navs.js', 'credits.js']) {
|
||||
const blocks = enqueueBlocksFor(routeScripts, file);
|
||||
assert.ok(blocks.length > 0, `${file} must be enqueued`);
|
||||
for (const block of blocks) {
|
||||
assert.match(block, /aksrt-lazy-image-attr/, `${file} must depend on the image-attribute bridge`);
|
||||
assert.match(block, /aksrt-runtime/, `${file} must depend on the bundled image-attribute bridge`);
|
||||
}
|
||||
}
|
||||
assert.match(runtime, /lazybeforeunveil/);
|
||||
|
||||
@@ -277,7 +277,7 @@ test('AJAX pagination can recover, caps auto loading and rehydrates appended med
|
||||
assert.match(media, /window\.Grade\(container/);
|
||||
assert.match(media, /linear-gradient\(135deg/);
|
||||
assert.match(media, /aksrtGradientState/);
|
||||
assert.match(read('src/Core/ScriptsPart1c.php'), /'aksrt-grade'/);
|
||||
assert.match(read('tools/build-public-assets.mjs'), /assets\/js\/grade\.min\.js/);
|
||||
});
|
||||
|
||||
test('the pinned visual baseline records all source checksums', () => {
|
||||
|
||||
@@ -173,6 +173,7 @@ test('clicking a notification uses the legacy exit class and removal delay', ()
|
||||
test('notyf CSS and WordPress enqueue match the reference contract', () => {
|
||||
const css = read('assets/css/frontend/notyf.css');
|
||||
const scripts = read('src/Core/ScriptsPart1c.php');
|
||||
const builder = read('tools/build-public-assets.mjs');
|
||||
|
||||
assert.match(css, /\.notyn\s*\{[\s\S]*?bottom:\s*6em;[\s\S]*?max-width:\s*320px;[\s\S]*?z-index:\s*10000000;/);
|
||||
assert.match(css, /\.notyf\s*\{[\s\S]*?position:\s*relative;[\s\S]*?font-size:\s*14px;[\s\S]*?line-height:\s*1\.42857143;[\s\S]*?min-width:\s*200px;[\s\S]*?padding:\s*1em 3em 1em 3\.4em;/);
|
||||
@@ -188,9 +189,9 @@ test('notyf CSS and WordPress enqueue match the reference contract', () => {
|
||||
assert.match(css, /content:\s*'\\f057'/);
|
||||
assert.match(css, /\.notyf\.load::before[\s\S]*?huan-rotate 1s/);
|
||||
|
||||
assert.match(scripts, /'aksrt-notyf',[\s\S]*?'\/assets\/js\/notyf\.js',[\s\S]*?\['jquery'\]/);
|
||||
assert.match(scripts, /'aksrt-runtime',[\s\S]*?\['aksrt-rehydrate', 'aksrt-notyf'\]/);
|
||||
assert.match(scripts, /'\/assets\/css\/frontend\/notyf\.css',[\s\S]*?'_fontawesome'/);
|
||||
assert.match(builder, /assets\/js\/notyf\.js/);
|
||||
assert.match(builder, /assets\/css\/frontend\/notyf\.css/);
|
||||
assert.match(scripts, /'aksrt-runtime',[\s\S]*?'\/assets\/js\/build\/public\.js',[\s\S]*?\['loader_js'\]/);
|
||||
});
|
||||
|
||||
test('balance center actions use direct fixed-id notyf flows', () => {
|
||||
@@ -242,8 +243,8 @@ test('balance center actions use direct fixed-id notyf flows', () => {
|
||||
assert.doesNotMatch(credits, /function initSignin\(|\/signin\/today|POST \/signin/);
|
||||
assert.match(signinController, /aksrtSigninInitialized/);
|
||||
assert.match(credits, /aksrtPointsExchangeInitialized[\s\S]*?aksrtWithdrawInitialized/);
|
||||
assert.match(scripts, /'aksrt-credits',[\s\S]*?\/assets\/js\/credits\.js',[\s\S]*?\[[^\]]*'aksrt-notyf'[^\]]*\]/);
|
||||
assert.match(scripts, /\$signin_on\s*=\s*is_user_logged_in\(\)[\s\S]*?'aksrt-signin',[\s\S]*?\/assets\/js\/signin\.js',[\s\S]*?'aksrt-core-request'[\s\S]*?'aksrt-notyf'/);
|
||||
assert.match(scripts, /'aksrt-credits',[\s\S]*?\/assets\/js\/credits\.js',[\s\S]*?\[[^\]]*'aksrt-runtime'[^\]]*\]/);
|
||||
assert.match(scripts, /\$signin_on\s*=\s*is_user_logged_in\(\)[\s\S]*?'aksrt-signin',[\s\S]*?\/assets\/js\/signin\.js',[\s\S]*?'aksrt-runtime'/);
|
||||
assert.ok(header.indexOf('data-signin-btn') < header.indexOf('uc-header__message-btn'));
|
||||
assert.match(header, /uc-header__message-btn[^>]+aria-label="<\?php esc_attr_e\('消息通知'/);
|
||||
assert.doesNotMatch(header, /<i class="fa fas fa-bell"[^>]*><\/i>\s*<\?php esc_html_e\('消息通知'/);
|
||||
@@ -282,7 +283,7 @@ test('VIP purchase and points exchange use direct fixed-id notyf flows', () => {
|
||||
|
||||
assert.doesNotMatch(vip, /setTip|aksrt-vip-modal-tip/);
|
||||
assert.doesNotMatch(css, /\.aksrt-vip-modal-tip/);
|
||||
assert.match(scripts, /'aksrt-pay-vip',[\s\S]*?\/assets\/js\/pay-vip\.js',[\s\S]*?\[[^\]]*'aksrt-notyf'[^\]]*\]/);
|
||||
assert.match(scripts, /'aksrt-pay-vip',[\s\S]*?\/assets\/js\/pay-vip\.js',[\s\S]*?\[[^\]]*'aksrt-runtime'[^\]]*\]/);
|
||||
});
|
||||
|
||||
test('payment entry points never load the removed legacy pay runtime', () => {
|
||||
@@ -324,7 +325,7 @@ test('profile save uses AJAX rehydrate and a fixed-id notyf flow without query f
|
||||
assert.match(profile, /notyf\([^;]+?'success'[^;]+?'aksrt-profile-save-toast'\);/);
|
||||
assert.match(profile, /notyf\([^;]+?'danger'[^;]+?'aksrt-profile-save-toast'\);/);
|
||||
assert.match(profile, /fetch\(ajaxUrl, \{ method: 'POST', credentials: 'same-origin', body: data \}\)/);
|
||||
assert.match(scripts, /\$user_center_deps[\s\S]*?\[[^\]]*'aksrt-notyf'[^\]]*\][\s\S]*?\/assets\/js\/routes\/user-center\.js/);
|
||||
assert.match(scripts, /\$user_center_deps[\s\S]*?\[[^\]]*'aksrt-runtime'[^\]]*\][\s\S]*?\/assets\/js\/routes\/user-center\.js/);
|
||||
|
||||
assert.doesNotMatch(page, /REQUEST_METHOD|profile_error|['"]saved['"]|add_query_arg/);
|
||||
assert.doesNotMatch([profile, form, layout, lists].join('\n'), /profile-save-msg|profile-form__submit-msg/);
|
||||
@@ -401,7 +402,7 @@ test('front submit actions use direct fixed-id notyf flows', () => {
|
||||
assert.match(submit, /needContent[^;]+?'warning'/);
|
||||
assert.doesNotMatch(submit, /\b(?:window\.)?alert\s*\(/);
|
||||
|
||||
assert.match(page, /'aksrt-front-submit',[\s\S]*?'\/assets\/js\/front-submit\.js',[\s\S]*?\[[^\]]*'aksrt-notyf'[^\]]*\]/);
|
||||
assert.match(page, /'aksrt-front-submit',[\s\S]*?'\/assets\/js\/front-submit\.js',[\s\S]*?\[[^\]]*'aksrt-runtime'[^\]]*\]/);
|
||||
});
|
||||
|
||||
test('legacy frontend toast APIs and selectors are fully removed', () => {
|
||||
@@ -409,7 +410,7 @@ test('legacy frontend toast APIs and selectors are fully removed', () => {
|
||||
'assets/js',
|
||||
'assets/css/frontend',
|
||||
'assets/css/routes',
|
||||
'assets/css/build/frontend-base.min.css.disabled',
|
||||
'assets/css/build',
|
||||
'page.php',
|
||||
'templates/pages/page-profile.php',
|
||||
];
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const cssBuildDir = path.join(repoRoot, 'assets/css/build');
|
||||
const jsBuildDir = path.join(repoRoot, 'assets/js/build');
|
||||
|
||||
const cssBundles = {
|
||||
'core.css': [
|
||||
'assets/css/core/tokens.css',
|
||||
'assets/css/core/reset.css',
|
||||
'assets/css/core/typography.css',
|
||||
'assets/css/core/buttons.css',
|
||||
'assets/css/core/forms.css',
|
||||
'assets/css/core/alerts.css',
|
||||
'assets/css/core/animations.css',
|
||||
'assets/css/core/components-ext.css',
|
||||
'assets/css/core/color-utilities.css',
|
||||
],
|
||||
'public.css': [
|
||||
'assets/css/frontend/base.css',
|
||||
'assets/css/frontend/header-userbox.css',
|
||||
'assets/css/frontend/card-primitives.css',
|
||||
'assets/css/frontend/overlay-primitives.css',
|
||||
'assets/css/frontend/layout.css',
|
||||
'assets/css/frontend/footer.css',
|
||||
'assets/css/frontend/floating-buttons.css',
|
||||
'assets/css/frontend/enhancements.css',
|
||||
'assets/css/frontend/skeleton.css',
|
||||
'assets/css/frontend/empty-state.css',
|
||||
'assets/css/frontend/pagination.css',
|
||||
'assets/css/frontend/ajax-spinner.css',
|
||||
'assets/css/frontend/modal-runtime.css',
|
||||
'assets/css/frontend/notyf.css',
|
||||
],
|
||||
'homepage.css': [
|
||||
'assets/css/frontend/homepage-fixed/base.css',
|
||||
'assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css',
|
||||
'assets/css/frontend/homepage-fixed/ajax-tab-error-state.css',
|
||||
],
|
||||
};
|
||||
|
||||
const publicScripts = [
|
||||
'assets/js/lazy-image-attr.js',
|
||||
'assets/js/rehydrate.js',
|
||||
'assets/js/notyf.js',
|
||||
'assets/js/aksrt-runtime.js',
|
||||
'assets/js/grade.min.js',
|
||||
'assets/js/core/modal-telemetry.js',
|
||||
'assets/js/core/request.js',
|
||||
'assets/js/core/modal-cache.js',
|
||||
'assets/js/core/modal-state.js',
|
||||
'assets/js/core/modal-runtime.js',
|
||||
'assets/js/core/modal-triggers.js',
|
||||
'assets/js/core/article.js',
|
||||
'assets/js/core/comments.js',
|
||||
'assets/js/core/comment-fixed-input.js',
|
||||
'assets/js/core/comment-move-form.js',
|
||||
'assets/js/core/ajax-list.js',
|
||||
'assets/js/core/pagination.js',
|
||||
'assets/js/core/archive.js',
|
||||
'assets/js/core/footer-tabbar.js',
|
||||
'assets/js/core/misc.js',
|
||||
'assets/js/follow.js',
|
||||
'assets/js/enhancements.js',
|
||||
'assets/js/enhancements2.js',
|
||||
'assets/js/color-extract.js',
|
||||
'assets/js/effects.js',
|
||||
];
|
||||
|
||||
function normalizePath(filePath) {
|
||||
return filePath.split(path.sep).join('/');
|
||||
}
|
||||
|
||||
function rewriteCssUrls(css, sourcePath, outputPath) {
|
||||
const outputDir = path.dirname(outputPath);
|
||||
return css.replace(/url\(\s*(['"]?)([^)'"\s]+)\1\s*\)/gi, (match, quote, rawUrl) => {
|
||||
if (/^(?:data:|https?:|\/\/|\/|#|var\()/i.test(rawUrl)) {
|
||||
return match;
|
||||
}
|
||||
|
||||
const suffixIndex = rawUrl.search(/[?#]/);
|
||||
const pathname = suffixIndex === -1 ? rawUrl : rawUrl.slice(0, suffixIndex);
|
||||
const suffix = suffixIndex === -1 ? '' : rawUrl.slice(suffixIndex);
|
||||
const absoluteAsset = path.resolve(path.dirname(sourcePath), pathname);
|
||||
let relativeAsset = normalizePath(path.relative(outputDir, absoluteAsset));
|
||||
if (!relativeAsset.startsWith('.')) {
|
||||
relativeAsset = `./${relativeAsset}`;
|
||||
}
|
||||
const wrapper = quote || '"';
|
||||
return `url(${wrapper}${relativeAsset}${suffix}${wrapper})`;
|
||||
});
|
||||
}
|
||||
|
||||
async function expandCss(sourcePath, outputPath, stack = []) {
|
||||
const absoluteSource = path.resolve(sourcePath);
|
||||
if (stack.includes(absoluteSource)) {
|
||||
throw new Error(`Circular CSS import: ${normalizePath(path.relative(repoRoot, absoluteSource))}`);
|
||||
}
|
||||
|
||||
const source = await readFile(absoluteSource, 'utf8');
|
||||
const importPattern = /@import\s+(?:url\(\s*)?['"]([^'"]+\.css)['"]\s*\)?\s*;/gi;
|
||||
let expanded = '';
|
||||
let cursor = 0;
|
||||
let match;
|
||||
|
||||
while ((match = importPattern.exec(source)) !== null) {
|
||||
expanded += rewriteCssUrls(source.slice(cursor, match.index), absoluteSource, outputPath);
|
||||
const importedPath = path.resolve(path.dirname(absoluteSource), match[1]);
|
||||
expanded += await expandCss(importedPath, outputPath, [...stack, absoluteSource]);
|
||||
cursor = importPattern.lastIndex;
|
||||
}
|
||||
|
||||
expanded += rewriteCssUrls(source.slice(cursor), absoluteSource, outputPath);
|
||||
return expanded.trimEnd();
|
||||
}
|
||||
|
||||
async function buildCssBundle(outputName, sources) {
|
||||
const outputPath = path.join(cssBuildDir, outputName);
|
||||
const sections = [];
|
||||
for (const source of sources) {
|
||||
const sourcePath = path.join(repoRoot, source);
|
||||
sections.push(`/* source: ${source} */\n${await expandCss(sourcePath, outputPath)}`);
|
||||
}
|
||||
await writeFile(outputPath, `${sections.join('\n\n')}\n`, 'utf8');
|
||||
}
|
||||
|
||||
async function buildScriptBundle() {
|
||||
const sections = [];
|
||||
for (const source of publicScripts) {
|
||||
const content = (await readFile(path.join(repoRoot, source), 'utf8')).trimEnd();
|
||||
sections.push(`/* source: ${source} */\n${content}\n;`);
|
||||
}
|
||||
await writeFile(path.join(jsBuildDir, 'public.js'), `${sections.join('\n\n')}\n`, 'utf8');
|
||||
}
|
||||
|
||||
await mkdir(cssBuildDir, { recursive: true });
|
||||
await mkdir(jsBuildDir, { recursive: true });
|
||||
for (const [outputName, sources] of Object.entries(cssBundles)) {
|
||||
await buildCssBundle(outputName, sources);
|
||||
}
|
||||
await buildScriptBundle();
|
||||
|
||||
console.log('Built public CSS and JS bundles.');
|
||||
Reference in New Issue
Block a user