feat: rewrite schema-driven widget system
This commit is contained in:
1 parent
6c6c462df8
commit
ad99ab53ce
28 files changed
+3489
No files matched your search
@@ -0,0 +1,166 @@
|
||||
.aksrt-widget-form {
|
||||
--aksrt-field-border: #dcdcde;
|
||||
--aksrt-field-accent: #2271b1;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
padding: 4px 0 10px;
|
||||
}
|
||||
|
||||
.aksrt-widget-field {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.aksrt-widget-field[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.aksrt-widget-field__label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.aksrt-widget-field .description {
|
||||
margin: -2px 0 7px;
|
||||
}
|
||||
|
||||
.aksrt-widget-switch {
|
||||
display: inline-flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aksrt-widget-switch input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.aksrt-widget-switch span {
|
||||
position: relative;
|
||||
width: 38px;
|
||||
height: 22px;
|
||||
border-radius: 999px;
|
||||
background: #8c8f94;
|
||||
transition: background .18s ease;
|
||||
}
|
||||
|
||||
.aksrt-widget-switch span::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
transition: transform .18s ease;
|
||||
}
|
||||
|
||||
.aksrt-widget-switch input:checked + span { background: var(--aksrt-field-accent); }
|
||||
.aksrt-widget-switch input:checked + span::after { transform: translateX(16px); }
|
||||
.aksrt-widget-switch input:focus-visible + span { outline: 2px solid #72aee6; outline-offset: 2px; }
|
||||
|
||||
.aksrt-widget-choices {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.aksrt-widget-choices label input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.aksrt-widget-choices label span {
|
||||
display: block;
|
||||
padding: 5px 9px;
|
||||
border: 1px solid var(--aksrt-field-border);
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aksrt-widget-choices label input:checked + span {
|
||||
border-color: var(--aksrt-field-accent);
|
||||
color: var(--aksrt-field-accent);
|
||||
box-shadow: 0 0 0 1px var(--aksrt-field-accent);
|
||||
}
|
||||
|
||||
.aksrt-widget-number,
|
||||
.aksrt-widget-icon,
|
||||
.aksrt-widget-link,
|
||||
.aksrt-widget-background {
|
||||
display: grid;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.aksrt-widget-number {
|
||||
grid-template-columns: minmax(0, 1fr) 50px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.aksrt-widget-upload {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.aksrt-widget-upload img {
|
||||
width: 100%;
|
||||
max-height: 150px;
|
||||
border-radius: 6px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.aksrt-widget-upload .widefat { flex: 1 1 100%; }
|
||||
|
||||
.aksrt-widget-spacing {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.aksrt-widget-spacing label span {
|
||||
display: block;
|
||||
margin-bottom: 3px;
|
||||
color: #646970;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.aksrt-widget-repeater__row,
|
||||
.aksrt-widget-nested {
|
||||
margin-bottom: 9px;
|
||||
border: 1px solid var(--aksrt-field-border);
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.aksrt-widget-repeater__bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid var(--aksrt-field-border);
|
||||
background: #f6f7f7;
|
||||
}
|
||||
|
||||
.aksrt-widget-repeater__bar .dashicons { cursor: move; }
|
||||
.aksrt-widget-repeater__bar strong { flex: 1; }
|
||||
.aksrt-widget-repeater__fields,
|
||||
.aksrt-widget-nested__body { display: grid; gap: 12px; padding: 10px; }
|
||||
.aksrt-widget-nested > summary { padding: 9px 10px; font-weight: 600; cursor: pointer; }
|
||||
|
||||
.aksrt-widget-form-lazy {
|
||||
padding: 14px;
|
||||
border: 1px dashed #c3c4c7;
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.aksrt-widget-form-lazy__status { margin-top: 0; color: #646970; }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.aksrt-widget-switch span,
|
||||
.aksrt-widget-switch span::after { transition: none; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
(function ($) {
|
||||
'use strict';
|
||||
|
||||
const config = window.aksrtWidgetAdmin || {};
|
||||
|
||||
function initForm(root) {
|
||||
const $root = $(root);
|
||||
$root.find('.aksrt-widget-color').wpColorPicker();
|
||||
$root.find('.aksrt-widget-repeater__rows').sortable({
|
||||
handle: '.dashicons-move',
|
||||
axis: 'y',
|
||||
update: renumberRepeaters,
|
||||
});
|
||||
$root.find('input[type="range"]').each(function () {
|
||||
const output = this.parentElement.querySelector('output');
|
||||
if (output) this.addEventListener('input', () => { output.textContent = this.value; });
|
||||
});
|
||||
evaluateDependencies($root);
|
||||
}
|
||||
|
||||
function loadForm(container) {
|
||||
const $container = $(container);
|
||||
if ($container.data('loading') || $container.data('loaded')) return;
|
||||
$container.data('loading', true).find('.aksrt-widget-form-lazy__status').text(config.i18n?.loading || 'Loading…');
|
||||
$.post(config.ajaxUrl, {
|
||||
action: config.action,
|
||||
nonce: config.nonce,
|
||||
id_base: $container.data('id-base'),
|
||||
widget_number: $container.data('widget-number'),
|
||||
}).done((response) => {
|
||||
if (!response?.success || !response.data?.html) throw new Error('Invalid response');
|
||||
const $form = $(response.data.html);
|
||||
$container.replaceWith($form);
|
||||
initForm($form);
|
||||
}).fail(() => {
|
||||
$container.data('loading', false).find('.aksrt-widget-form-lazy__status').text(config.i18n?.error || 'Failed to load.');
|
||||
});
|
||||
}
|
||||
|
||||
function renumberRepeaters(_event, ui) {
|
||||
const $form = $(ui?.item || this).closest('.aksrt-widget-form');
|
||||
$form.find('.aksrt-widget-repeater__rows').each(function () {
|
||||
$(this).children('.aksrt-widget-repeater__row').each(function (index) {
|
||||
this.dataset.rowIndex = String(index);
|
||||
});
|
||||
});
|
||||
$form.find('[name]').each(function () {
|
||||
const rowIndexes = $(this).parents('.aksrt-widget-repeater__row').get().reverse().map((row) => Number(row.dataset.rowIndex || 0));
|
||||
if (!rowIndexes.length) return;
|
||||
let foundWidgetNumber = false;
|
||||
let cursor = 0;
|
||||
this.name = this.name.replace(/\[(\d+|__index_[a-f0-9]+__)\]/g, (match, index) => {
|
||||
if (!foundWidgetNumber && /^\d+$/.test(index)) {
|
||||
foundWidgetNumber = true;
|
||||
return match;
|
||||
}
|
||||
return cursor < rowIndexes.length ? `[${rowIndexes[cursor++]}]` : match;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function fieldValue($form, id) {
|
||||
const $field = $form.find(`.aksrt-widget-field[data-field-id="${CSS.escape(id)}"]`).first();
|
||||
const $checked = $field.find('input:checked').first();
|
||||
if ($checked.length) return String($checked.val());
|
||||
return String($field.find('input,select,textarea').first().val() ?? '');
|
||||
}
|
||||
|
||||
function evaluateDependencies($form) {
|
||||
$form.find('[data-dependency]').each(function () {
|
||||
let rule;
|
||||
try { rule = JSON.parse(this.dataset.dependency || '[]'); } catch (_error) { return; }
|
||||
if (!Array.isArray(rule) || rule.length < 3) return;
|
||||
const $row = $(this).closest('.aksrt-widget-repeater__row');
|
||||
const current = fieldValue($row.length ? $row : $form, String(rule[0]));
|
||||
const expected = String(rule[2]);
|
||||
const visible = rule[1] === '==' ? current === expected : current !== expected;
|
||||
this.hidden = !visible;
|
||||
});
|
||||
}
|
||||
|
||||
$(document)
|
||||
.on('click', '.aksrt-widget-form-lazy__load', function () { loadForm($(this).closest('.aksrt-widget-form-lazy')); })
|
||||
.on('click', '.widget.open .aksrt-widget-form-lazy', function () { loadForm(this); })
|
||||
.on('change input', '.aksrt-widget-form input, .aksrt-widget-form select, .aksrt-widget-form textarea', function () { evaluateDependencies($(this).closest('.aksrt-widget-form')); })
|
||||
.on('click', '.aksrt-widget-repeater__add', function () {
|
||||
const $repeater = $(this).closest('.aksrt-widget-repeater');
|
||||
const max = Number($repeater.data('max-items') || 50);
|
||||
const $rows = $repeater.children('.aksrt-widget-repeater__rows');
|
||||
if ($rows.children().length >= max) return;
|
||||
const index = $rows.children().length;
|
||||
const token = String($repeater.data('index-token') || '__index__');
|
||||
const html = $repeater.children('template').html().replaceAll(token, String(index));
|
||||
const $row = $(html).appendTo($rows);
|
||||
initForm($row);
|
||||
renumberRepeaters.call($rows[0]);
|
||||
})
|
||||
.on('click', '.aksrt-widget-repeater__remove', function () {
|
||||
const $rows = $(this).closest('.aksrt-widget-repeater__rows');
|
||||
$(this).closest('.aksrt-widget-repeater__row').remove();
|
||||
renumberRepeaters.call($rows[0]);
|
||||
})
|
||||
.on('click', '.aksrt-widget-upload__choose', function () {
|
||||
const $wrap = $(this).closest('.aksrt-widget-upload');
|
||||
const frame = wp.media({ title: '选择媒体', multiple: false });
|
||||
frame.on('select', () => {
|
||||
const attachment = frame.state().get('selection').first().toJSON();
|
||||
$wrap.find('input[type="url"]').val(attachment.url).trigger('change');
|
||||
let $image = $wrap.find('img');
|
||||
if (!$image.length) $image = $('<img alt="">').prependTo($wrap);
|
||||
$image.attr('src', attachment.url);
|
||||
});
|
||||
frame.open();
|
||||
})
|
||||
.on('click', '.aksrt-widget-upload__remove', function () {
|
||||
const $wrap = $(this).closest('.aksrt-widget-upload');
|
||||
$wrap.find('input[type="url"]').val('').trigger('change');
|
||||
$wrap.find('img').remove();
|
||||
});
|
||||
|
||||
$(document).on('widget-added widget-updated', function (_event, widget) {
|
||||
$(widget).find('.aksrt-widget-form-lazy').each(function () { loadForm(this); });
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$('.aksrt-widget-form').each(function () { initForm(this); });
|
||||
$('.widget.open .aksrt-widget-form-lazy').each(function () { loadForm(this); });
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,135 @@
|
||||
.aksrt-widget {
|
||||
--aksrt-widget-bg-light: transparent;
|
||||
--aksrt-widget-bg-dark: transparent;
|
||||
--aksrt-widget-radius: 12px;
|
||||
margin: var(--aksrt-widget-space-top, 0) var(--aksrt-widget-space-right, 0) var(--aksrt-widget-space-bottom, 20px) var(--aksrt-widget-space-left, 0);
|
||||
background-color: var(--aksrt-widget-bg-light);
|
||||
background-image: var(--aksrt-widget-bg-image-light, none);
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
color: var(--theme-color, #2d2d35);
|
||||
}
|
||||
.dark-theme .aksrt-widget,
|
||||
[data-theme="dark"] .aksrt-widget { background-color: var(--aksrt-widget-bg-dark); background-image: var(--aksrt-widget-bg-image-dark, none); color: #e7e7ea; }
|
||||
.aksrt-widget *, .aksrt-widget *::before, .aksrt-widget *::after { box-sizing: border-box; }
|
||||
.aksrt-widget img, .aksrt-widget video { max-width: 100%; }
|
||||
.aksrt-widget a { color: inherit; text-decoration: none; }
|
||||
.aksrt-widget button, .aksrt-widget input { font: inherit; }
|
||||
.aksrt-widget__header { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; margin-bottom: 16px; }
|
||||
.aksrt-widget__header--big { display: block; text-align: center; margin-bottom: 30px; }
|
||||
.aksrt-widget__title { margin: 0; font-size: 20px; line-height: 1.35; font-weight: 700; }
|
||||
.aksrt-widget__header--big .aksrt-widget__title { font-size: clamp(27px, 4vw, 42px); }
|
||||
.aksrt-widget__title mark { padding: 0; background: transparent; color: var(--focus-color, #ff5473); }
|
||||
.aksrt-widget__subtitle { margin: 7px 0 0; color: var(--muted-color, #8a8c98); }
|
||||
.aksrt-widget__title-links { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
|
||||
.aksrt-widget__title-links a { padding: 5px 11px; border-radius: 999px; background: #f2f3f5; font-size: 13px; }
|
||||
.dark-theme .aksrt-widget__title-links a, [data-theme="dark"] .aksrt-widget__title-links a { background: #292a30; }
|
||||
.aksrt-widget-grid { display: grid; grid-template-columns: repeat(var(--aksrt-cols, 3), minmax(0, 1fr)); gap: 16px; }
|
||||
.aksrt-widget__empty, .aksrt-widget-request-error { padding: 28px 18px; border: 1px dashed rgba(127,127,127,.25); border-radius: var(--aksrt-widget-radius); color: var(--muted-color, #8a8c98); text-align: center; }
|
||||
.aksrt-widget-request-error button { margin-left: 10px; padding: 5px 12px; border: 0; border-radius: 999px; cursor: pointer; }
|
||||
.aksrt-widget--affix { position: sticky; top: 76px; }
|
||||
.aksrt-widget--only-mobile { display: none; }
|
||||
|
||||
.aksrt-widget-search { display: flex; min-height: 46px; padding: 5px; border: 1px solid rgba(127,127,127,.18); border-radius: 10px; background: var(--main-bg, #fff); box-shadow: 0 8px 25px rgba(31,35,48,.06); }
|
||||
.aksrt-widget-search label { flex: 1; display: flex; }
|
||||
.aksrt-widget-search input { width: 100%; padding: 8px 12px; border: 0; outline: 0; background: transparent; color: inherit; }
|
||||
.aksrt-widget-search button { display: flex; align-items: center; gap: 7px; padding: 8px 16px; border: 0; border-radius: 8px; background: var(--focus-color, #ff5473); color: #fff; cursor: pointer; }
|
||||
.aksrt-widget-search--compact button span { display: none; }
|
||||
.aksrt-widget-search--large { min-height: 58px; border-radius: 14px; }
|
||||
|
||||
.aksrt-widget-toc { padding: 14px 16px; border-radius: var(--aksrt-widget-radius); background: var(--main-bg, #fff); box-shadow: 0 8px 30px rgba(31,35,48,.06); }
|
||||
.aksrt-widget-toc__toggle { display: flex; width: 100%; align-items: center; justify-content: space-between; padding: 0; border: 0; background: transparent; color: inherit; font-weight: 700; cursor: pointer; }
|
||||
.aksrt-widget-toc__list { margin: 14px 0 0; padding-left: 20px; max-height: 55vh; overflow: auto; }
|
||||
.aksrt-widget-toc__list li { margin: 7px 0; color: var(--muted-color, #737582); }
|
||||
.aksrt-widget-toc__list .level-h3 { padding-left: 12px; font-size: 14px; }
|
||||
.aksrt-widget-toc__list .level-h4 { padding-left: 24px; font-size: 13px; }
|
||||
.aksrt-widget-toc.is-collapsed .aksrt-widget-toc__list { display: none; }
|
||||
|
||||
.aksrt-widget-quote { position: relative; min-height: 130px; margin: 0; padding: 24px 48px 24px 25px; overflow: hidden; border-radius: var(--aksrt-widget-radius); background: linear-gradient(135deg, #6772e5, #8b5cf6); color: #fff; }
|
||||
.aksrt-widget-quote > i { opacity: .35; font-size: 26px; }
|
||||
.aksrt-widget-quote blockquote { margin: 12px 0 0; font-size: 16px; line-height: 1.8; }
|
||||
.aksrt-widget-quote button { position: absolute; right: 13px; bottom: 13px; width: 30px; height: 30px; border: 0; border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; cursor: pointer; }
|
||||
|
||||
.aksrt-widget-icon-card, .aksrt-widget-icon-cards .icon-card, .aksrt-widget-icon-cards .icon-cover-card { min-height: 130px; padding: 22px; border-radius: var(--aksrt-widget-radius); background: var(--main-bg, #fff); box-shadow: 0 10px 32px rgba(31,35,48,.07); transition: transform .25s, box-shadow .25s; }
|
||||
.aksrt-widget-icon-card:hover, .aksrt-widget-icon-cards .icon-card:hover, .aksrt-widget-icon-cards .icon-cover-card:hover { transform: translateY(-4px); box-shadow: 0 16px 40px rgba(31,35,48,.12); }
|
||||
.aksrt-widget-icon-card { display: flex; flex-direction: column; gap: 12px; text-align: center; }
|
||||
.aksrt-widget-icon-cards--cover .aksrt-widget-icon-card { flex-direction: row; align-items: center; text-align: left; }
|
||||
.aksrt-widget-icon-card > i { font-size: 34px; color: var(--focus-color, #ff5473); }
|
||||
.aksrt-widget-icon-card span { display: flex; flex-direction: column; gap: 5px; }
|
||||
.aksrt-widget-icon-card small { color: var(--muted-color, #8a8c98); }
|
||||
|
||||
.aksrt-widget-video { position: relative; overflow: hidden; border-radius: var(--aksrt-widget-radius); background: #000; aspect-ratio: 16 / 9; }
|
||||
.aksrt-widget-video--4-3 { aspect-ratio: 4 / 3; }.aksrt-widget-video--1-1 { aspect-ratio: 1; }.aksrt-widget-video--auto { aspect-ratio: auto; }
|
||||
.aksrt-widget-video video, .aksrt-widget-video__player, .aksrt-widget-video .dplayer { width: 100%; height: 100%; }
|
||||
.aksrt-widget-media-error { position: absolute; inset: auto 15px 15px; color: #fff; }
|
||||
.aksrt-widget-embed { position: relative; height: 0; padding-bottom: var(--aksrt-embed-ratio, 56.25%); overflow: hidden; border-radius: var(--aksrt-widget-radius); background: #111; }
|
||||
.aksrt-widget-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
|
||||
|
||||
.aksrt-media-card { position: relative; display: block; overflow: hidden; min-height: 180px; border-radius: var(--aksrt-widget-radius); background: var(--main-bg, #fff); box-shadow: 0 8px 28px rgba(31,35,48,.07); }
|
||||
.aksrt-media-card__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: #eceef2; }
|
||||
.aksrt-media-card__media img, .aksrt-media-card__media video { width: 100%; height: 100%; object-fit: cover; transition: transform .35s; }
|
||||
.aksrt-media-card:hover .aksrt-media-card__media img { transform: scale(1.04); }
|
||||
.aksrt-media-card__image--dark { display: none; }
|
||||
.dark-theme .aksrt-media-card__image--dark, [data-theme="dark"] .aksrt-media-card__image--dark { display: block; }
|
||||
.dark-theme .aksrt-media-card__image--dark ~ .aksrt-media-card__image, [data-theme="dark"] .aksrt-media-card__image--dark ~ .aksrt-media-card__image { display: none; }
|
||||
.aksrt-media-card__body { display: flex; flex-direction: column; gap: 5px; padding: 14px 16px 16px; }
|
||||
.aksrt-media-card__body small { color: var(--muted-color, #8a8c98); }
|
||||
.aksrt-widget-partners { overflow: hidden; padding: 5px 0; }
|
||||
.aksrt-widget-partners__track { display: grid; grid-auto-flow: column; grid-template-rows: repeat(var(--aksrt-partner-rows), 76px); grid-auto-columns: 210px; gap: 12px; width: max-content; animation: aksrt-partners var(--aksrt-partner-speed) linear infinite; }
|
||||
.aksrt-widget-partners:hover .aksrt-widget-partners__track { animation-play-state: paused; }
|
||||
.aksrt-widget-partners .aksrt-media-card { display: flex; min-height: 76px; align-items: center; }
|
||||
.aksrt-widget-partners .aksrt-media-card__media { width: 64px; aspect-ratio: 1; margin-left: 8px; border-radius: 9px; }
|
||||
.aksrt-widget-partners .aksrt-media-card__body { padding: 10px; }
|
||||
@keyframes aksrt-partners { to { transform: translateX(-50%); } }
|
||||
.aksrt-combo-card { overflow: hidden; border-radius: var(--aksrt-widget-radius); background: var(--main-bg,#fff); box-shadow: 0 8px 28px rgba(31,35,48,.07); }
|
||||
.aksrt-combo-card .aksrt-media-card { box-shadow: none; }
|
||||
.aksrt-combo-card__tags { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 16px 16px; }
|
||||
.aksrt-combo-card__tags span { padding: 3px 8px; border-radius: 999px; background: rgba(127,127,127,.1); font-size: 12px; }
|
||||
|
||||
.aksrt-widget-text-title { padding: 18px 0; }.aksrt-widget-text-title.is-center { text-align: center; }.aksrt-widget-text-title.is-right { text-align: right; }
|
||||
.aksrt-widget-text-title h2 { margin: 0; font-size: clamp(26px,4vw,44px); line-height: 1.25; }.aksrt-widget-text-title p { margin: 12px 0 0; color: var(--muted-color,#8a8c98); line-height: 1.8; }
|
||||
.aksrt-widget-buttons { display: flex; flex-wrap: wrap; gap: var(--aksrt-button-gap,10px); }.aksrt-widget-buttons.is-center { justify-content: center; }.aksrt-widget-buttons.is-right { justify-content: flex-end; }
|
||||
.aksrt-widget-button { display: inline-flex; min-height: 40px; padding: 9px 18px; align-items: center; justify-content: center; gap: 7px; border: 0; border-radius: 9px; background: var(--focus-color,#ff5473); color: #fff !important; font-weight: 600; cursor: pointer; transition: filter .2s, transform .2s; }
|
||||
.aksrt-widget-button:hover { filter: brightness(1.07); transform: translateY(-1px); }.aksrt-widget-button.is-ghost { background: rgba(127,127,127,.12); color: inherit !important; }
|
||||
.aksrt-widget-gap { height: var(--aksrt-gap); }
|
||||
.aksrt-widget-tag-cloud { display: flex; flex-wrap: wrap; gap: 8px; }.aksrt-widget-tag-cloud a { padding: 6px 11px; border-radius: 6px; background: rgba(127,127,127,.1); font-size: 13px; transition: background .2s,color .2s; }.aksrt-widget-tag-cloud a:hover { background: var(--focus-color,#ff5473); color: #fff; }.aksrt-widget-tag-cloud small { margin-left: 5px; opacity: .65; }
|
||||
.aksrt-widget-comments { display: grid; gap: 15px; margin: 0; padding: 0; list-style: none; }.aksrt-widget-comments li { display: flex; gap: 11px; }.aksrt-widget-comments__avatar img { width: 42px; height: 42px; border-radius: 50%; }.aksrt-widget-comments p { margin: 3px 0; color: var(--muted-color,#8a8c98); font-size: 13px; line-height: 1.55; }.aksrt-widget-comments__source { font-size: 12px; opacity: .65; }
|
||||
.aksrt-widget-links { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 10px; }.aksrt-widget-links a { display: flex; flex-direction: column; gap: 4px; padding: 14px; border-radius: 9px; background: var(--main-bg,#fff); box-shadow: 0 6px 20px rgba(31,35,48,.06); }.aksrt-widget-links small { color: var(--muted-color,#8a8c98); }.aksrt-widget-links--simple { display: flex; flex-wrap: wrap; }.aksrt-widget-links--simple a { padding: 5px 9px; box-shadow: none; background: transparent; }
|
||||
.aksrt-widget-notice { display: flex; height: 48px; align-items: center; gap: 12px; padding: 0 16px; overflow: hidden; border-radius: 9px; background: var(--main-bg,#fff); box-shadow: 0 7px 22px rgba(31,35,48,.06); }.aksrt-widget-notice .swiper { height: 48px; flex: 1; }.aksrt-widget-notice .swiper-slide, .aksrt-widget-notice .swiper-slide a { display: flex; height: 48px; align-items: center; gap: 10px; }.aksrt-widget-notice .swiper-slide span { overflow: hidden; color: var(--muted-color,#8a8c98); text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
.aksrt-term-card { display: block; overflow: hidden; border-radius: var(--aksrt-widget-radius); background: var(--main-bg,#fff); box-shadow: 0 8px 28px rgba(31,35,48,.07); }.aksrt-term-card__media { display: block; aspect-ratio: 16/9; background: linear-gradient(135deg,#667eea,#764ba2); }.aksrt-term-card__media img { width: 100%; height: 100%; object-fit: cover; }.aksrt-term-card__body { display: flex; flex-direction: column; gap: 5px; padding: 14px; }.aksrt-term-card__body small { min-height: 38px; color: var(--muted-color,#8a8c98); }.aksrt-term-card__body em { font-size: 12px; color: var(--focus-color,#ff5473); font-style: normal; }
|
||||
.aksrt-term-aggregation { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 16px; }.aksrt-term-aggregation__card { padding: 16px; border-radius: var(--aksrt-widget-radius); background: var(--main-bg,#fff); box-shadow: 0 8px 28px rgba(31,35,48,.07); }.aksrt-term-aggregation header a { display: flex; justify-content: space-between; }.aksrt-term-aggregation header span { color: var(--muted-color,#8a8c98); font-size: 13px; }.aksrt-term-aggregation ul { display: grid; gap: 10px; margin: 14px 0 0; padding: 0; list-style: none; }.aksrt-term-aggregation li a { display: flex; align-items: center; gap: 10px; }.aksrt-term-aggregation li img { width: 55px; height: 42px; border-radius: 6px; object-fit: cover; }
|
||||
.aksrt-widget-items { position: relative; min-height: 40px; }.aksrt-widget-items.is-loading { opacity: .72; pointer-events: none; }.aksrt-widget-skeleton { height: 180px; border-radius: 10px; background: linear-gradient(90deg,rgba(127,127,127,.08),rgba(127,127,127,.17),rgba(127,127,127,.08)); background-size: 200% 100%; animation: aksrt-shimmer 1.2s infinite; }.aksrt-widget-load-more { display: block; min-width: 120px; margin: 18px auto 0; padding: 9px 18px; border: 0; border-radius: 999px; background: rgba(127,127,127,.12); color: inherit; cursor: pointer; }.aksrt-widget-pagination { display:flex;justify-content:center;gap:6px;margin-top:18px; }.aksrt-widget-pagination button { min-width:34px;height:34px;border:0;border-radius:8px;background:rgba(127,127,127,.1);color:inherit;cursor:pointer; }.aksrt-widget-pagination button[aria-current="page"] { background:var(--focus-color,#ff5473);color:#fff; }@keyframes aksrt-shimmer { to { background-position: -200% 0; } }
|
||||
.aksrt-widget-oneline .swiper-slide { width: min(300px,78vw); }.aksrt-widget-tabs__nav { display: flex; gap: 8px; margin-bottom: 15px; overflow-x: auto; }.aksrt-widget-tabs__nav button { flex: none; padding: 7px 14px; border: 0; border-radius: 999px; background: rgba(127,127,127,.1); color: inherit; cursor: pointer; }.aksrt-widget-tabs__nav button[aria-selected="true"] { background: var(--focus-color,#ff5473); color: #fff; }
|
||||
.aksrt-post-pay { padding: 20px; border-radius: var(--aksrt-widget-radius); text-align: center; }.aksrt-post-pay.is-authorized { background: rgba(34,197,94,.1); }.aksrt-post-pay > i { display: block; margin-bottom: 9px; color: #22c55e; font-size: 30px; }.aksrt-post-pay p { color: var(--muted-color,#8a8c98); }
|
||||
|
||||
.aksrt-pricing-card { position: relative; display: flex; flex-direction: column; padding: 25px; border: 1px solid rgba(127,127,127,.13); border-radius: 16px; background: var(--main-bg,#fff); box-shadow: 0 10px 35px rgba(31,35,48,.06); }.aksrt-pricing-card.is-featured { border-color: var(--focus-color,#ff5473); transform: translateY(-8px); }.aksrt-pricing-card__badge { position: absolute; top: 12px; right: 12px; padding: 4px 9px; border-radius: 999px; background: var(--focus-color,#ff5473); color: #fff; font-size: 12px; }.aksrt-pricing-card h3 { margin: 0 0 12px; }.aksrt-pricing-card__price { font-size: 34px; font-weight: 800; }.aksrt-pricing-card p { color: var(--muted-color,#8a8c98); }.aksrt-pricing-card ul { flex: 1; display: grid; gap: 9px; margin: 15px 0 22px; padding: 0; list-style: none; }.aksrt-pricing-card li i { margin-right: 8px; color: #22c55e; }
|
||||
.aksrt-reviews .swiper-slide { width: min(390px,86vw); height: auto; }.aksrt-review-card { height: 100%; padding: 22px; border-radius: 14px; background: var(--main-bg,#fff); box-shadow: 0 8px 28px rgba(31,35,48,.07); }.aksrt-review-card__rating { color: #f6b73c; }.aksrt-review-card blockquote { min-height: 80px; margin: 15px 0; line-height: 1.75; }.aksrt-review-card footer { display: flex; align-items: center; gap: 11px; }.aksrt-review-card__avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }.aksrt-review-card footer span { display: flex; flex-direction: column; }.aksrt-review-card footer small { color: var(--muted-color,#8a8c98); }
|
||||
.aksrt-faq { max-width: 880px; margin: auto; }.aksrt-faq__search { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; padding: 10px 14px; border: 1px solid rgba(127,127,127,.16); border-radius: 10px; }.aksrt-faq__search input { width: 100%; border: 0; outline: 0; background: transparent; color: inherit; }.aksrt-faq__items { display: grid; gap: 10px; }.aksrt-faq__item { overflow: hidden; border: 1px solid rgba(127,127,127,.13); border-radius: 10px; background: var(--main-bg,#fff); }.aksrt-faq__item > button { display: flex; width: 100%; justify-content: space-between; padding: 15px 17px; border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer; }.aksrt-faq__item > div { padding: 0 17px 17px; color: var(--muted-color,#8a8c98); line-height: 1.75; }
|
||||
.aksrt-stat { padding: 22px; text-align: center; }.aksrt-stat > strong { display: block; color: var(--focus-color,#ff5473); font-size: clamp(32px,5vw,52px); }.aksrt-stat h3 { margin: 5px 0; }.aksrt-stat p { margin: 0; color: var(--muted-color,#8a8c98); }.aksrt-highlight--large { grid-column: span 2; }.aksrt-tilt-case { transform-style: preserve-3d; }.aksrt-tilt-case .aksrt-media-card__body { transform: translateZ(20px); }
|
||||
.aksrt-feature-intro__tabs { display: flex; justify-content: center; gap: 8px; margin-bottom: 18px; }.aksrt-feature-intro__tabs button { padding: 7px 14px; border: 0; border-radius: 999px; background: rgba(127,127,127,.1); color: inherit; cursor: pointer; }.aksrt-feature-intro__tabs button[aria-selected="true"] { background: var(--focus-color,#ff5473); color: #fff; }.aksrt-feature-intro__panels article { display: grid; grid-template-columns: 1.15fr 1fr; align-items: center; gap: 34px; }.aksrt-feature-intro__copy p, .aksrt-feature-intro__copy li { color: var(--muted-color,#8a8c98); line-height: 1.7; }
|
||||
|
||||
.aksrt-slider { height: var(--aksrt-slider-height); overflow: hidden; border-radius: var(--aksrt-widget-radius); background: #111; }.aksrt-slider .swiper-slide, .aksrt-slider .swiper-slide > a { position: relative; display: block; width: 100%; height: 100%; overflow: hidden; }.aksrt-slider .swiper-slide > img, .aksrt-slider .swiper-slide > video, .aksrt-slider .swiper-slide > a > img, .aksrt-slider .swiper-slide > a > video { width: 100%; height: 100%; object-fit: cover; }.aksrt-slide-copy { position: absolute; z-index: 2; right: 8%; bottom: 12%; left: 8%; color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.4); }.aksrt-slide-copy.is-center { top: 50%; bottom: auto; text-align: center; transform: translateY(-50%); }.aksrt-slide-copy.is-right-bottom { text-align: right; }.aksrt-slide-copy h3 { margin: 0; font-size: clamp(25px,4vw,44px); }.aksrt-slide-copy p { margin: 8px 0 0; }.aksrt-slide-layer { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }.aksrt-slider-combo { display: grid; grid-template-columns: minmax(0,2fr) minmax(240px,1fr); gap: 15px; }.aksrt-slider-combo__side { display: grid; gap: 15px; }.aksrt-slider-combo__side .aksrt-media-card { min-height: 0; }.aksrt-slider-combo__side .aksrt-media-card__media { aspect-ratio: 2/1; }
|
||||
|
||||
.aksrt-user-card { position: relative; overflow: hidden; border-radius: 14px; background: var(--main-bg,#fff); box-shadow: 0 9px 30px rgba(31,35,48,.07); text-align: center; }.aksrt-user-card__cover { height: 105px; background: linear-gradient(135deg,#667eea,#764ba2); background-position: center; background-size: cover; }.aksrt-user-card__body { position: relative; padding: 18px; }.aksrt-user-card__avatar { display: inline-block; margin-top: -62px; padding: 4px; border-radius: 50%; background: var(--main-bg,#fff); }.aksrt-user-card__avatar img { display: block; width: 84px; height: 84px; border-radius: 50%; object-fit: cover; }.aksrt-user-card.is-guest .aksrt-user-card__avatar { margin-top: -58px; }.aksrt-user-card h3 { margin: 7px 0; }.aksrt-user-card__identity { margin: 6px 0; }.aksrt-user-card__body > p { color: var(--muted-color,#8a8c98); }.aksrt-user-card__stats { display: flex; justify-content: center; gap: 24px; margin: 16px 0; }.aksrt-user-card__stats span { display: flex; flex-direction: column; font-size: 12px; color: var(--muted-color,#8a8c98); }.aksrt-user-card__stats b { color: inherit; font-size: 17px; }.aksrt-user-card__actions { display: flex; justify-content: center; gap: 9px; }.aksrt-user-card__follow { position: absolute; top: 14px; right: 14px; padding: 5px 12px; border: 0; border-radius: 999px; background: var(--focus-color,#ff5473); color: #fff; cursor: pointer; }.aksrt-user-card__follow.is-following { background: rgba(0,0,0,.5); }.aksrt-user-card__posts { padding: 0 16px 16px; text-align: left; }
|
||||
.aksrt-user-ranking { display: grid; gap: 11px; margin: 0; padding: 0; list-style: none; }.aksrt-user-ranking li { display: flex; align-items: center; gap: 9px; }.aksrt-user-ranking__index { width: 24px; text-align: center; color: var(--muted-color,#8a8c98); font-weight: 700; }.aksrt-user-ranking__index.is-top { color: #f59e0b; }.aksrt-user-tile { display: flex; min-width: 0; flex: 1; align-items: center; gap: 10px; }.aksrt-user-tile img { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }.aksrt-user-tile span { display: flex; min-width: 0; flex-direction: column; }.aksrt-user-tile strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.aksrt-user-tile small { color: var(--muted-color,#8a8c98); }.aksrt-user-list { --aksrt-cols: 4; }.aksrt-user-list article { padding: 14px; border-radius: 10px; background: var(--main-bg,#fff); box-shadow: 0 6px 20px rgba(31,35,48,.06); }
|
||||
.aksrt-user-card.no-cover .aksrt-user-card__avatar { margin-top: 0; }.aksrt-user-card__oauth { margin-top: 14px; }
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.aksrt-widget { margin: var(--aksrt-widget-space-m-top,0) var(--aksrt-widget-space-m-right,0) var(--aksrt-widget-space-m-bottom,15px) var(--aksrt-widget-space-m-left,0); }
|
||||
.aksrt-widget--only-pc { display: none; }.aksrt-widget--only-mobile { display: block; }
|
||||
.aksrt-widget-grid { grid-template-columns: repeat(var(--aksrt-cols-m,1),minmax(0,1fr)); gap: 10px; }
|
||||
.aksrt-widget__header { align-items: flex-start; flex-direction: column; }.aksrt-widget__title-links { justify-content: flex-start; }
|
||||
.aksrt-widget-links { grid-template-columns: repeat(2,minmax(0,1fr)); }
|
||||
.aksrt-widget-partners__track { grid-template-rows: repeat(var(--aksrt-partner-rows-m),70px); }
|
||||
.aksrt-term-aggregation, .aksrt-feature-intro__panels article, .aksrt-slider-combo { grid-template-columns: 1fr; }
|
||||
.aksrt-highlight--large { grid-column: auto; }
|
||||
.aksrt-slider { height: var(--aksrt-slider-height-m); }.aksrt-slide--hide-mobile { display: none !important; }
|
||||
.aksrt-widget-gap { height: var(--aksrt-gap-m); }.aksrt-pricing-card.is-featured { transform: none; }
|
||||
.aksrt-user-list { --aksrt-cols-m: 1; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.aksrt-widget *, .aksrt-widget *::before, .aksrt-widget *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
|
||||
}
|
||||
.aksrt-widget--animate { animation: aksrt-widget-fade .55s both; }.aksrt-widget--animate-slideup { animation-name: aksrt-widget-slideup; }.aksrt-widget--animate-slidedown { animation-name: aksrt-widget-slidedown; }.aksrt-widget--animate-slideright { animation-name: aksrt-widget-slideright; }.aksrt-widget--animate-slideleft { animation-name: aksrt-widget-slideleft; }.aksrt-widget--animate-zoomin { animation-name: aksrt-widget-zoomin; }.aksrt-widget--animate-zoomout { animation-name: aksrt-widget-zoomout; }.aksrt-widget--animate-repeat { animation-iteration-count: infinite; animation-duration: 2s; }
|
||||
@keyframes aksrt-widget-fade { from { opacity: 0; } }@keyframes aksrt-widget-slideup { from { opacity:0;transform:translateY(25px); } }@keyframes aksrt-widget-slidedown { from { opacity:0;transform:translateY(-25px); } }@keyframes aksrt-widget-slideright { from { opacity:0;transform:translateX(-25px); } }@keyframes aksrt-widget-slideleft { from { opacity:0;transform:translateX(25px); } }@keyframes aksrt-widget-zoomin { from { opacity:0;transform:scale(.9); } }@keyframes aksrt-widget-zoomout { from { opacity:0;transform:scale(1.1); } }
|
||||
@@ -0,0 +1,290 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var config = window.aksrtWidgets || {};
|
||||
var reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
function once(el, key) {
|
||||
var name = 'aksrt' + key;
|
||||
if (el.dataset[name]) return false;
|
||||
el.dataset[name] = '1';
|
||||
return true;
|
||||
}
|
||||
|
||||
function initSwiper(el) {
|
||||
if (!once(el, 'Swiper') || typeof window.Swiper !== 'function') return;
|
||||
var kind = el.dataset.aksrtSwiper || 'cards';
|
||||
var vertical = kind === 'notice' || el.dataset.direction === 'vertical';
|
||||
var options = {
|
||||
direction: vertical ? 'vertical' : 'horizontal',
|
||||
loop: el.dataset.loop === '1' || kind === 'notice',
|
||||
speed: Number(el.dataset.speed || 500),
|
||||
spaceBetween: Number(el.dataset.space || 16),
|
||||
observer: true,
|
||||
observeParents: true,
|
||||
watchOverflow: true,
|
||||
navigation: {
|
||||
nextEl: el.querySelector('.swiper-button-next'),
|
||||
prevEl: el.querySelector('.swiper-button-prev')
|
||||
},
|
||||
pagination: { el: el.querySelector('.swiper-pagination'), clickable: true }
|
||||
};
|
||||
if (kind === 'scroll' || kind === 'cards') {
|
||||
options.slidesPerView = 'auto';
|
||||
options.freeMode = kind === 'scroll';
|
||||
}
|
||||
if (kind === 'slider') {
|
||||
options.effect = el.dataset.effect || 'slide';
|
||||
options.parallax = !!el.querySelector('[data-swiper-parallax]');
|
||||
}
|
||||
if (!reducedMotion && (el.dataset.autoplay === '1' || kind === 'notice')) {
|
||||
options.autoplay = { delay: Number(el.dataset.interval || 4000), disableOnInteraction: false, pauseOnMouseEnter: true };
|
||||
}
|
||||
try {
|
||||
el.aksrtSwiper = new window.Swiper(el, options);
|
||||
} catch (error) {
|
||||
el.classList.add('is-fallback');
|
||||
}
|
||||
}
|
||||
|
||||
function videoType(url) {
|
||||
if (/\.m3u8(?:\?|$)/i.test(url)) return 'hls';
|
||||
if (/\.flv(?:\?|$)/i.test(url)) return 'flv';
|
||||
if (/\.mpd(?:\?|$)/i.test(url)) return 'dash';
|
||||
return 'auto';
|
||||
}
|
||||
|
||||
function initVideo(el) {
|
||||
if (!once(el, 'Video')) return;
|
||||
var fallback = el.querySelector('video');
|
||||
if (fallback) {
|
||||
fallback.addEventListener('error', function () {
|
||||
var message = el.querySelector('.aksrt-widget-media-error');
|
||||
if (message) message.hidden = false;
|
||||
});
|
||||
}
|
||||
if (typeof window.DPlayer !== 'function') return;
|
||||
var holder = document.createElement('div');
|
||||
holder.className = 'aksrt-widget-video__player';
|
||||
el.insertBefore(holder, fallback || el.firstChild);
|
||||
try {
|
||||
el.aksrtPlayer = new window.DPlayer({
|
||||
container: holder,
|
||||
autoplay: el.dataset.autoplay === '1' && !reducedMotion,
|
||||
video: {
|
||||
url: el.dataset.videoUrl || '',
|
||||
pic: el.dataset.videoPoster || '',
|
||||
type: videoType(el.dataset.videoUrl || '')
|
||||
}
|
||||
});
|
||||
if (el.dataset.muted === '1' && el.aksrtPlayer.video) el.aksrtPlayer.video.muted = true;
|
||||
if (fallback) fallback.hidden = true;
|
||||
} catch (error) {
|
||||
holder.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function initToc(toc) {
|
||||
if (!once(toc, 'Toc')) return;
|
||||
var scope = document.querySelector('.article-content, .wp-posts-content, article .entry-content');
|
||||
var headings = scope ? Array.prototype.slice.call(scope.querySelectorAll('h2,h3,h4')) : [];
|
||||
var minimum = Number(toc.dataset.minHeadings || 3);
|
||||
var list = toc.querySelector('.aksrt-widget-toc__list');
|
||||
if (headings.length < minimum || !list) {
|
||||
toc.hidden = true;
|
||||
return;
|
||||
}
|
||||
headings.forEach(function (heading, index) {
|
||||
if (!heading.id) heading.id = 'aksrt-heading-' + (index + 1);
|
||||
var item = document.createElement('li');
|
||||
item.className = 'level-' + heading.tagName.toLowerCase();
|
||||
var link = document.createElement('a');
|
||||
link.href = '#' + heading.id;
|
||||
link.textContent = heading.textContent.trim();
|
||||
link.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
window.scrollTo({ top: heading.getBoundingClientRect().top + window.scrollY - Number(toc.dataset.scrollOffset || 70), behavior: reducedMotion ? 'auto' : 'smooth' });
|
||||
history.replaceState(null, '', link.href);
|
||||
});
|
||||
item.appendChild(link);
|
||||
list.appendChild(item);
|
||||
});
|
||||
var empty = toc.querySelector('.aksrt-widget-toc__empty');
|
||||
if (empty) empty.remove();
|
||||
var toggle = toc.querySelector('.aksrt-widget-toc__toggle');
|
||||
if (toggle) toggle.addEventListener('click', function () {
|
||||
var expanded = toggle.getAttribute('aria-expanded') === 'true';
|
||||
toggle.setAttribute('aria-expanded', expanded ? 'false' : 'true');
|
||||
toc.classList.toggle('is-collapsed', expanded);
|
||||
});
|
||||
}
|
||||
|
||||
function updateQuote(figure) {
|
||||
if (figure.dataset.source !== 'api' || !config.quoteUrl) return Promise.resolve();
|
||||
var button = figure.querySelector('button');
|
||||
if (button) button.disabled = true;
|
||||
return fetch(config.quoteUrl, { credentials: 'same-origin', headers: { Accept: 'application/json' } })
|
||||
.then(function (response) { if (!response.ok) throw new Error('quote'); return response.json(); })
|
||||
.then(function (data) {
|
||||
if (data && data.text) figure.querySelector('blockquote').textContent = data.text;
|
||||
})
|
||||
.catch(function () {})
|
||||
.finally(function () { if (button) button.disabled = false; });
|
||||
}
|
||||
|
||||
function initQuote(figure) {
|
||||
if (!once(figure, 'Quote')) return;
|
||||
var button = figure.querySelector('button');
|
||||
if (button) button.addEventListener('click', function () { updateQuote(figure); });
|
||||
if (!reducedMotion && figure.dataset.source === 'api') {
|
||||
window.setInterval(function () { if (!document.hidden) updateQuote(figure); }, Math.max(5, Number(figure.dataset.interval || 30)) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function errorMarkup() {
|
||||
var i18n = config.i18n || {};
|
||||
return '<div class="aksrt-widget-request-error" role="alert"><span>' + (i18n.error || '加载失败,请重试。') + '</span><button type="button" data-widget-retry>' + (i18n.retry || '重试') + '</button></div>';
|
||||
}
|
||||
|
||||
function itemsUrl(widget, instance, page, segment) {
|
||||
var base = String(config.restUrl || '').replace(/\/$/, '');
|
||||
var url = base + '/' + encodeURIComponent(widget) + '/items?instance=' + encodeURIComponent(instance) + '&page=' + encodeURIComponent(page);
|
||||
if (segment !== undefined && segment !== '') url += '&segment=' + encodeURIComponent(segment);
|
||||
return url;
|
||||
}
|
||||
|
||||
function loadItems(container, page, append) {
|
||||
var owner = container.closest('[data-widget]') || container;
|
||||
var widget = owner.dataset.widget || container.dataset.widget;
|
||||
var instance = owner.dataset.instance || container.dataset.instance;
|
||||
var segment = container.dataset.segment || owner.dataset.segment || '';
|
||||
if (!widget || !instance || !config.restUrl || container.dataset.loading === '1') return;
|
||||
container.dataset.loading = '1';
|
||||
container.classList.add('is-loading');
|
||||
fetch(itemsUrl(widget, instance, page, segment), { credentials: 'same-origin', headers: { Accept: 'application/json' } })
|
||||
.then(function (response) { if (!response.ok) throw new Error('items'); return response.json(); })
|
||||
.then(function (data) {
|
||||
var oldPagination = container.querySelector('.aksrt-widget-pagination, .aksrt-widget-load-more');
|
||||
if (oldPagination) oldPagination.remove();
|
||||
var fragment = document.createElement('div');
|
||||
fragment.innerHTML = String(data.html || '');
|
||||
if (append) {
|
||||
var target = container.querySelector('.aksrt-widget-posts, .posts-row, .swiper-wrapper') || container;
|
||||
var source = fragment.querySelector('.aksrt-widget-posts, .posts-row, .swiper-wrapper');
|
||||
Array.prototype.slice.call((source || fragment).children).forEach(function (node) { target.appendChild(node); });
|
||||
} else {
|
||||
container.innerHTML = fragment.innerHTML;
|
||||
}
|
||||
if (data.paginate_html) container.insertAdjacentHTML('beforeend', data.paginate_html);
|
||||
container.dataset.page = String(data.page || page);
|
||||
scan(container);
|
||||
})
|
||||
.catch(function () { container.innerHTML = errorMarkup(); })
|
||||
.finally(function () { delete container.dataset.loading; container.classList.remove('is-loading'); });
|
||||
}
|
||||
|
||||
function initItems(container) {
|
||||
if (!once(container, 'Items')) return;
|
||||
if (container.classList.contains('is-loading')) loadItems(container, 1, false);
|
||||
container.addEventListener('click', function (event) {
|
||||
var retry = event.target.closest('[data-widget-retry]');
|
||||
var more = event.target.closest('.aksrt-widget-load-more');
|
||||
var pageButton = event.target.closest('[data-widget-page]');
|
||||
if (retry) loadItems(container, Number(container.dataset.page || 1), false);
|
||||
if (more) loadItems(container, Number(more.dataset.nextPage || 2), true);
|
||||
if (pageButton) loadItems(container, Number(pageButton.dataset.widgetPage || 1), false);
|
||||
});
|
||||
if ('IntersectionObserver' in window) {
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
var more = container.querySelector('.aksrt-widget-load-more[data-mode="infinite"]');
|
||||
if (entry.isIntersecting && more) loadItems(container, Number(more.dataset.nextPage || 2), true);
|
||||
});
|
||||
}, { rootMargin: '240px' });
|
||||
observer.observe(container);
|
||||
}
|
||||
}
|
||||
|
||||
function initTabs(tabs) {
|
||||
if (!once(tabs, 'Tabs')) return;
|
||||
tabs.addEventListener('click', function (event) {
|
||||
var button = event.target.closest('[data-segment]');
|
||||
if (!button) return;
|
||||
tabs.querySelectorAll('[role="tab"]').forEach(function (tab) { tab.setAttribute('aria-selected', tab === button ? 'true' : 'false'); });
|
||||
var panel = tabs.querySelector('[data-widget-items]');
|
||||
panel.dataset.segment = button.dataset.segment;
|
||||
loadItems(panel, 1, false);
|
||||
});
|
||||
}
|
||||
|
||||
function initFaq(faq) {
|
||||
if (!once(faq, 'Faq')) return;
|
||||
faq.addEventListener('click', function (event) {
|
||||
var button = event.target.closest('.aksrt-faq__item > button');
|
||||
if (!button) return;
|
||||
var expanded = button.getAttribute('aria-expanded') === 'true';
|
||||
button.setAttribute('aria-expanded', expanded ? 'false' : 'true');
|
||||
var panel = document.getElementById(button.getAttribute('aria-controls'));
|
||||
if (panel) panel.hidden = expanded;
|
||||
});
|
||||
var search = faq.querySelector('input[type="search"]');
|
||||
if (search) search.addEventListener('input', function () {
|
||||
var needle = search.value.trim().toLowerCase();
|
||||
faq.querySelectorAll('.aksrt-faq__item').forEach(function (item) { item.hidden = needle && String(item.dataset.search || '').toLowerCase().indexOf(needle) === -1; });
|
||||
});
|
||||
}
|
||||
|
||||
function initFeatures(features) {
|
||||
if (!once(features, 'Features')) return;
|
||||
features.addEventListener('click', function (event) {
|
||||
var button = event.target.closest('[data-feature-index]');
|
||||
if (!button) return;
|
||||
var index = button.dataset.featureIndex;
|
||||
features.querySelectorAll('[data-feature-index]').forEach(function (tab) { tab.setAttribute('aria-selected', tab === button ? 'true' : 'false'); });
|
||||
features.querySelectorAll('[data-feature-panel]').forEach(function (panel) { panel.hidden = panel.dataset.featurePanel !== index; });
|
||||
});
|
||||
}
|
||||
|
||||
function initCount(el) {
|
||||
if (!once(el, 'Count') || reducedMotion) return;
|
||||
var raw = el.dataset.countUp || '';
|
||||
var match = raw.match(/-?[0-9]+(?:\.[0-9]+)?/);
|
||||
if (!match) return;
|
||||
var target = Number(match[0]);
|
||||
var prefix = raw.slice(0, match.index);
|
||||
var suffix = raw.slice(match.index + match[0].length);
|
||||
var start = performance.now();
|
||||
function frame(now) {
|
||||
var progress = Math.min(1, (now - start) / 900);
|
||||
el.textContent = prefix + Math.round(target * (1 - Math.pow(1 - progress, 3))) + suffix;
|
||||
if (progress < 1) requestAnimationFrame(frame);
|
||||
}
|
||||
requestAnimationFrame(frame);
|
||||
}
|
||||
|
||||
function scan(root) {
|
||||
var scope = root || document;
|
||||
scope.querySelectorAll('[data-aksrt-swiper]').forEach(initSwiper);
|
||||
scope.querySelectorAll('.aksrt-widget-video[data-video-url]').forEach(initVideo);
|
||||
scope.querySelectorAll('.aksrt-widget-toc').forEach(initToc);
|
||||
scope.querySelectorAll('.aksrt-widget-quote').forEach(initQuote);
|
||||
scope.querySelectorAll('[data-widget-items]').forEach(initItems);
|
||||
scope.querySelectorAll('.aksrt-widget-tabs').forEach(initTabs);
|
||||
scope.querySelectorAll('.aksrt-faq').forEach(initFaq);
|
||||
scope.querySelectorAll('.aksrt-feature-intro').forEach(initFeatures);
|
||||
scope.querySelectorAll('[data-count-up]').forEach(initCount);
|
||||
if (typeof window.VanillaTilt !== 'undefined') scope.querySelectorAll('[data-aksrt-tilt]').forEach(function (el) { if (once(el, 'Tilt')) window.VanillaTilt.init(el); });
|
||||
}
|
||||
|
||||
function ready() {
|
||||
scan(document);
|
||||
if ('MutationObserver' in window) {
|
||||
new MutationObserver(function (mutations) {
|
||||
mutations.forEach(function (mutation) { mutation.addedNodes.forEach(function (node) { if (node.nodeType === 1) scan(node); }); });
|
||||
}).observe(document.body, { childList: true, subtree: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ready);
|
||||
else ready();
|
||||
})();
|
||||
Reference in new issue
Block a user