Changeset 3725635
- Timestamp:
- 10/02/2026 11:39:13 PM (3 weeks ago)
- Location:
- loops-block/trunk
- Files:
-
- 9 edited
-
build/loop.js (modified) (3 diffs)
-
build/loop.min.js (modified) (1 diff)
-
build/loop/block.json (modified) (1 diff)
-
build/loop/index.js (modified) (1 diff)
-
build/style.css (modified) (1 diff)
-
build/style.min.css (modified) (1 diff)
-
includes/class-loopsblock.php (modified) (69 diffs)
-
loops-block.php (modified) (1 diff)
-
readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
loops-block/trunk/build/loop.js
r3622994 r3725635 270 270 var el = el 271 271 , options = options || {} 272 , trigger = el. getElementsByClassName('scroller')[0]272 , trigger = el.querySelector('.scroller') ?? el.nextElementSibling?.closest('.scroller') 273 273 , autoTrigger = options.autoTrigger == false ? false : true 274 274 , autoTriggerUntil = options.autoTriggerUntil || 1000 … … 305 305 trigger.className = ''; 306 306 trigger.removeEventListener('click', _load); 307 el.removeChild(trigger);307 trigger.remove(); 308 308 var dom = document.createElement('div'), i; 309 309 dom.innerHTML = r.response.content; … … 311 311 while(i=dom.firstChild) el.appendChild(i); 312 312 313 trigger = el. getElementsByClassName('scroller')[0];313 trigger = el.querySelector('.scroller') ?? el.nextElementSibling?.closest('.scroller'); 314 314 trigger && trigger.addEventListener('click', _load, false); 315 315 -
loops-block/trunk/build/loop.min.js
r3671635 r3725635 1 !function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).BezierEasing=e()}((function(){return function e(t,n,i){function o( a,l){if(!n[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(r)return r(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[a]={exports:{}};t[a][0].call(d.exports,(function(e){return o(t[a][1][e]||e)}),d,d.exports,e,t,n,i)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<i.length;a++)o(i[a]);return o}({1:[function(e,t,n){var i="function"==typeof Float32Array;function o(e,t){return 1-3*t+3*e}function r(e,t){return 3*t-6*e}function a(e){return 3*e}function l(e,t,n){return((o(t,n)*e+r(t,n))*e+a(t))*e}function s(e,t,n){return 3*o(t,n)*e*e+2*r(t,n)*e+a(t)}function u(e){return e}t.exports=function(e,t,n,o){if(!(0<=e&&e<=1&&0<=n&&n<=1))throw new Error("bezier x values must be in [0, 1] range");if(e===t&&n===o)return u;for(var r=i?new Float32Array(11):new Array(11),a=0;a<11;++a)r[a]=l(.1*a,e,n);return function(i){return 0===i?0:1===i?1:l(function(t){for(var i=0,o=1;10!==o&&r[o]<=t;++o)i+=.1;var a=i+(t-r[--o])/(r[o+1]-r[o])*.1,u=s(a,e,n);return.001<=u?function(e,t,n,i){for(var o=0;o<4;++o){var r=s(t,n,i);if(0===r)return t;t-=(l(t,n,i)-e)/r}return t}(t,a,e,n):0===u?a:function(e,t,n,i,o){for(var r,a,s=0;0<(r=l(a=t+(n-t)/2,i,o)-e)?n=a:t=a,Math.abs(r)>1e-7&&++s<10;);return a}(t,i,i+.1,e,n)}(i),t,o)}}},{}]},{},[1])(1)})),function(){"use strict";function plugin(){for(var el,str_plugin="data-plugin",str_option="data-option",els=document.querySelectorAll('[data-plugin],[class^="plugin-"],[class*=" plugin-"]'),options,plugin,i=0;i<els.length;i++){if(el=els[i],el.className.indexOf("plug-initialized")>-1)return;plugin=el.getAttribute(str_plugin)||el.className.match(/(?:^|\s)plugin-(.*?)(?:$|\s)/)[1],options=el.getAttribute(str_option)||"{}",options=eval("("+options+")");for(var klass=el.className,reg=/data-([^-]+)-([^\s]+)/g,result;null!==(result=reg.exec(klass));)options[result[1]]=result[2];for(var d in el.dataset)if(d.indexOf(plugin)>-1){var attr=d.replace(plugin,"").toLowerCase();""!==attr&&(options[attr]=el.dataset[d])}options.child&&(el=el.children[0]),(el[plugin]||window[plugin])&&(el.removeAttribute(str_plugin),el.removeAttribute(str_option),el.className+=" plug-initialized",el[plugin]?el[plugin].apply(el,options):new window[plugin](el,options))}}function on(e,t,n){document.addEventListener(e,(function(e){let i=e.target;for(;i&&i!==document;){if(i.matches&&i.matches(t))return void n.call(i,e);i=i.parentElement}}))}function init(){location.href.indexOf("dir=rtl")>-1&&document.body.classList.add("rtl"),plugin()}window.slider=function(e,t){var n,i,o,r,a,l,s="rtl"==getComputedStyle(e).direction,u=0!=t.arrows,d=!!t.dots,c=(t.slides,!!t.autoplay),f=t.autoplaySpeed||4e3,p=!!t.loop,v=parseInt(getComputedStyle(e).gridColumnGap,10),g=e.parentElement.className.indexOf("block-loop-center")>-1,m=parseFloat(getComputedStyle(e).getPropertyValue("--loop-max-width"))/100,h=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent),t.l_c||"slider-left-btn"),y=t.r_c||"slider-right-btn",w=t.l_svg||'<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>',L=t.r_svg||'<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>',E=8,b=!1,N="block-slider-scrolling";function x(){var e=A(),t="";if(r&&!(e<2)){for(var n=0;n<e;n++)t+='<button data-index="'+n+'"></button>';r.innerHTML=t,r.addEventListener("click",k)}}function k(t){H();var n=1,i=e.scrollLeft;t.target.parentElement.className.indexOf("block-loop-dot")>-1?(n=t.target.dataset.index,i=0):n=t.currentTarget.className.indexOf(h)>-1?-1:1,_(i+=n*O())}function T(){!0===t.autoplay&&0!=c&&(c=!0,setTimeout(C,f))}function H(){c=!1}function C(){if(!b){var t=e.scrollLeft+(g?O():O(1));e.scrollLeft+e.offsetWidth==e.scrollWidth&&(p?(t=0,g&&(t=O())):H()),c&&_(t),P()}}function O(t){var n=e.offsetWidth,i=e.children[0].offsetWidth,o=t?t*(i+v):n+v;return g&&m<1&&(o=parseInt(m*(o+v/2)),0!=e.scrollLeft&&e.scrollLeft+e.offsetWidth!=e.scrollWidth||(o-=n*(1-m)/2)),o*(s?-1:1)}function A(){return Math.round(e.scrollWidth/e.offsetWidth)}function i(){i||(requestAnimationFrame((function(){x(),P(),i=!1})),i=!0)}function P(){for(var t=A(),n=e.children,i=e.scrollLeft,c=i+e.offsetWidth,f=e.scrollWidth,p=Math.round((f-i)/e.offsetWidth),v=0;v<n.length;v++){var g=n[v],m=g.offsetLeft,h=m+g.offsetWidth,y=n[v].getElementsByTagName("video")[0];if(c-4<m||i+4>h){var w=new RegExp("(\\s|^)slider-active(\\s|$)");n[v].className=n[v].className.replace(w,""),y&&y.pause()}else-1==n[v].className.indexOf("slider-active")&&(n[v].className+=" slider-active",y&&y.play())}if(u&&(a.style.display=a&&i*(s?-1:1)<E?"none":"",l&&f-i*(s?-1:1)<e.offsetWidth+E?l.style.display="none":l.style.display="",o)){var L=e.getElementsByClassName("post-thumbnail"),b=getComputedStyle(e);L[0]&&(o.style.setProperty("--height",L[0].offsetHeight+"px"),o.style.setProperty("--top",e.offsetTop+L[0].offsetTop+parseInt(L[0].offsetHeight/2)+"px")),b.getPropertyValue("--loop-rows")>1&&L[0]&&o.style.setProperty("--top","calc(50% + "+parseInt(e.offsetTop/2)+"px)")}if(d){var N=r.querySelector('[data-index="'+(t-p)*(s?-1:1)+'"]'),x=r.getElementsByTagName("button");for(v=0;v<x.length;v++)x[v].className="";N&&(N.className="active")}}function _(t){if(!e.classList.contains(N)){var n=e.scrollLeft;!function(e,t,n,i,o,r,a){var l=[.425,.005,0,1];l=BezierEasing(l[0],l[1],l[2],l[3]);const s=o=>{e[t]=n+(i-n)*o},u=Date.now(),d=()=>{var e=(Date.now()-u)/o;e>1?(s(1),a&&a()):(requestAnimationFrame(d),s(l(e)))};r&&r();d()}(e,"scrollLeft",n,t,1500,(function(){b=!0,e.classList.add(N)}),(function(){b=!1,e.classList.remove(N),T()}))}}e.className+=" block-loop-slider",u&&((o=document.createElement("div")).className="block-loop-nav",e.parentNode.appendChild(o),function(){A();var e="";e='<div class="'+h+'"><button>'+w+'</button></div><span></span><div class="'+y+'"><button>'+L+"</button></div>",o.innerHTML=e,a=o.getElementsByClassName(h)[0],l=o.getElementsByClassName(y)[0],a.addEventListener("click",k),l.addEventListener("click",k)}()),d&&((r=document.createElement("div")).className="block-loop-dot",e.parentNode.appendChild(r),x()),g&&_(O()),c&&T(),P(),e.addEventListener("ontouchstart"in window?"touchstart":"mouseenter",(function(){c=!1})),e.addEventListener("ontouchstart"in window?"touchend":"mouseleave",(function(){c=!0})),e.addEventListener("scroll",(function(){n||(requestAnimationFrame((function(){P(),n=!1})),n=!0)})),window.addEventListener("resize",i)},window.scroller=function(e,t){t=t||{};var n=(e=e).getElementsByClassName("scroller")[0],i=0!=t.autoTrigger,o=t.autoTriggerUntil||1e3,r=0,a=t.loadingHtml||'<span class="spinner"></span><span class="screen-reader-text"></span>';if(n){var l=window,s=getComputedStyle(n.parentElement).getPropertyValue("overflow-y");"scroll"!=s&&"auto"!=s||(l=n.parentElement),l.addEventListener("scroll",(function(){n&&function(e,t,n){var i=e.offsetTop,o=i+e.clientHeight,r=t.pageYOffset?t.pageYOffset:t.scrollTop,a=r+(t.pageYOffset?t.innerHeight:t.clientHeight),l=n&&(i<r&&o>r||o>a&&i<a);return i>=r&&o<=a||l}(n,l)&&i&&r<o&&u()}),!1),n.addEventListener("click",u,!1)}function u(t){if(t&&t.preventDefault(),t&&t.stopPropagation(),!(n.className.indexOf("is-loading")>-1)){n.innerHTML=a,n.className+=" is-loading";var i=n.href,o=new XMLHttpRequest;o.responseType="json",o.onreadystatechange=function(){if(4==o.readyState&&200==o.status){n.className="",n.removeEventListener("click",u),e.removeChild(n);var t,i=document.createElement("div");for(i.innerHTML=o.response.content;t=i.firstChild;)e.appendChild(t);(n=e.getElementsByClassName("scroller")[0])&&n.addEventListener("click",u,!1),document.dispatchEvent(new Event("refresh")),r++}},o.open("GET",i,!0),"undefined"!=typeof play&&void 0!==play.nonce&&o.setRequestHeader("X-WP-Nonce",play.nonce),o.send()}}},window.range=function(e){var t=e.getAttribute("value"),n=null===t?[]:t.split(","),i=+(e.min||0),o=+(e.max||100),r=document.createElement("span"),a=document.createElement("span"),l=e.cloneNode();e.classList.add("multirange"),e.classList.add("original"),l.classList.add("multirange"),l.classList.add("ghost"),r.classList.add("range-min"),a.classList.add("range-max"),e.value=n[0]||i+(o-i)/2,l.value=n[1]||i+(o-i)/2,e.parentNode.insertBefore(l,e.nextSibling),e.parentNode.insertBefore(r,e.previousSibling),e.parentNode.insertBefore(a,e.previousSibling);var s=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");function u(t){var n=(e.valueLow-i)/(o-i)*100,s=(e.valueHigh-i)/(o-i)*100;l.style.setProperty("--low",n+"%"),l.style.setProperty("--high",s+"%"),r&&(r.innerHTML=e.valueLow,r.style.setProperty("--left",n)),a&&(a.innerHTML=e.valueHigh,a.style.setProperty("--left",s)),1!==t&&(clearTimeout(d),d=setTimeout((function(){var t=e.getAttribute("data-url"),n=e.getAttribute("name"),i=(e.getAttribute("type"),new RegExp(n+"__(\\d+)-(\\d+)[%2C]*[(\\d+)\\-(\\d+)]*"));t=t.replace(i,n+"__"+e.valueLow+"-"+e.valueHigh),"undefined"==typeof Pjax?location.href=t:document.dispatchEvent(new CustomEvent("reload",{detail:{url:t}}))}),1e3))}Object.defineProperty(e,"originalValue",s.get?s:{get:function(){return this.value},set:function(e){this.value=e}}),Object.defineProperties(e,{valueLow:{get:function(){return Math.min(this.originalValue,l.value)},set:function(e){this.originalValue=e,u()},enumerable:!0},valueHigh:{get:function(){return Math.max(this.originalValue,l.value)},set:function(e){l.value=e,u()},enumerable:!0}}),s.get&&Object.defineProperty(e,"value",{get:function(){return this.valueLow+","+this.valueHigh},set:function(e){var t=e.split(",");this.valueLow=t[0],this.valueHigh=t[1],u()},enumerable:!0}),"function"==typeof e.oninput&&(l.oninput=e.oninput.bind(e)),l.addEventListener("mousedown",(function(t){var n=i+(o-i)*t.offsetX/this.offsetWidth,r=(e.valueHigh+e.valueLow)/2;e.valueLow==l.value==n>r&&(e.value=l.value)})),e.addEventListener("input",u),l.addEventListener("input",u);var d=null;u(1)},on("click",".dropdown-toggle-filter",(function(e){e.preventDefault();var t=this.nextElementSibling;t&&(t.classList.toggle("show"),t.parentNode.querySelector(".dropdown-backdrop")||t.parentNode.insertAdjacentHTML("beforeend",'<div class="dropdown-backdrop"></div>'),on("click",".dropdown-backdrop",(function(e){t.classList.remove("show")})))})),window.addEventListener("call:plugin",(function(){plugin()})),window.addEventListener("pjax:complete",(function(){init()})),init()}();1 !function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).BezierEasing=e()}((function(){return function e(t,n,i){function o(l,a){if(!n[l]){if(!t[l]){var s="function"==typeof require&&require;if(!a&&s)return s(l,!0);if(r)return r(l,!0);var u=new Error("Cannot find module '"+l+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[l]={exports:{}};t[l][0].call(d.exports,(function(e){return o(t[l][1][e]||e)}),d,d.exports,e,t,n,i)}return n[l].exports}for(var r="function"==typeof require&&require,l=0;l<i.length;l++)o(i[l]);return o}({1:[function(e,t,n){var i="function"==typeof Float32Array;function o(e,t){return 1-3*t+3*e}function r(e,t){return 3*t-6*e}function l(e){return 3*e}function a(e,t,n){return((o(t,n)*e+r(t,n))*e+l(t))*e}function s(e,t,n){return 3*o(t,n)*e*e+2*r(t,n)*e+l(t)}function u(e){return e}t.exports=function(e,t,n,o){if(!(0<=e&&e<=1&&0<=n&&n<=1))throw new Error("bezier x values must be in [0, 1] range");if(e===t&&n===o)return u;for(var r=i?new Float32Array(11):new Array(11),l=0;l<11;++l)r[l]=a(.1*l,e,n);return function(i){return 0===i?0:1===i?1:a(function(t){for(var i=0,o=1;10!==o&&r[o]<=t;++o)i+=.1;var l=i+(t-r[--o])/(r[o+1]-r[o])*.1,u=s(l,e,n);return.001<=u?function(e,t,n,i){for(var o=0;o<4;++o){var r=s(t,n,i);if(0===r)return t;t-=(a(t,n,i)-e)/r}return t}(t,l,e,n):0===u?l:function(e,t,n,i,o){for(var r,l,s=0;0<(r=a(l=t+(n-t)/2,i,o)-e)?n=l:t=l,Math.abs(r)>1e-7&&++s<10;);return l}(t,i,i+.1,e,n)}(i),t,o)}}},{}]},{},[1])(1)})),function(){"use strict";function plugin(){for(var el,str_plugin="data-plugin",str_option="data-option",els=document.querySelectorAll('[data-plugin],[class^="plugin-"],[class*=" plugin-"]'),options,plugin,i=0;i<els.length;i++){if(el=els[i],el.className.indexOf("plug-initialized")>-1)return;plugin=el.getAttribute(str_plugin)||el.className.match(/(?:^|\s)plugin-(.*?)(?:$|\s)/)[1],options=el.getAttribute(str_option)||"{}",options=eval("("+options+")");for(var klass=el.className,reg=/data-([^-]+)-([^\s]+)/g,result;null!==(result=reg.exec(klass));)options[result[1]]=result[2];for(var d in el.dataset)if(d.indexOf(plugin)>-1){var attr=d.replace(plugin,"").toLowerCase();""!==attr&&(options[attr]=el.dataset[d])}options.child&&(el=el.children[0]),(el[plugin]||window[plugin])&&(el.removeAttribute(str_plugin),el.removeAttribute(str_option),el.className+=" plug-initialized",el[plugin]?el[plugin].apply(el,options):new window[plugin](el,options))}}function on(e,t,n){document.addEventListener(e,(function(e){let i=e.target;for(;i&&i!==document;){if(i.matches&&i.matches(t))return void n.call(i,e);i=i.parentElement}}))}function init(){location.href.indexOf("dir=rtl")>-1&&document.body.classList.add("rtl"),plugin()}window.slider=function(e,t){var n,i,o,r,l,a,s="rtl"==getComputedStyle(e).direction,u=0!=t.arrows,d=!!t.dots,c=(t.slides,!!t.autoplay),f=t.autoplaySpeed||4e3,p=!!t.loop,v=parseInt(getComputedStyle(e).gridColumnGap,10),g=e.parentElement.className.indexOf("block-loop-center")>-1,m=parseFloat(getComputedStyle(e).getPropertyValue("--loop-max-width"))/100,h=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent),t.l_c||"slider-left-btn"),y=t.r_c||"slider-right-btn",w=t.l_svg||'<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>',L=t.r_svg||'<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>',b=8,E=!1,x="block-slider-scrolling";function N(){var e=A(),t="";if(r&&!(e<2)){for(var n=0;n<e;n++)t+='<button data-index="'+n+'"></button>';r.innerHTML=t,r.addEventListener("click",k)}}function k(t){H();var n=1,i=e.scrollLeft;t.target.parentElement.className.indexOf("block-loop-dot")>-1?(n=t.target.dataset.index,i=0):n=t.currentTarget.className.indexOf(h)>-1?-1:1,P(i+=n*O())}function T(){!0===t.autoplay&&0!=c&&(c=!0,setTimeout(C,f))}function H(){c=!1}function C(){if(!E){var t=e.scrollLeft+(g?O():O(1));e.scrollLeft+e.offsetWidth==e.scrollWidth&&(p?(t=0,g&&(t=O())):H()),c&&P(t),S()}}function O(t){var n=e.offsetWidth,i=e.children[0].offsetWidth,o=t?t*(i+v):n+v;return g&&m<1&&(o=parseInt(m*(o+v/2)),0!=e.scrollLeft&&e.scrollLeft+e.offsetWidth!=e.scrollWidth||(o-=n*(1-m)/2)),o*(s?-1:1)}function A(){return Math.round(e.scrollWidth/e.offsetWidth)}function i(){i||(requestAnimationFrame((function(){N(),S(),i=!1})),i=!0)}function S(){for(var t=A(),n=e.children,i=e.scrollLeft,c=i+e.offsetWidth,f=e.scrollWidth,p=Math.round((f-i)/e.offsetWidth),v=0;v<n.length;v++){var g=n[v],m=g.offsetLeft,h=m+g.offsetWidth,y=n[v].getElementsByTagName("video")[0];if(c-4<m||i+4>h){var w=new RegExp("(\\s|^)slider-active(\\s|$)");n[v].className=n[v].className.replace(w,""),y&&y.pause()}else-1==n[v].className.indexOf("slider-active")&&(n[v].className+=" slider-active",y&&y.play())}if(u&&(l.style.display=l&&i*(s?-1:1)<b?"none":"",a&&f-i*(s?-1:1)<e.offsetWidth+b?a.style.display="none":a.style.display="",o)){var L=e.getElementsByClassName("post-thumbnail"),E=getComputedStyle(e);L[0]&&(o.style.setProperty("--height",L[0].offsetHeight+"px"),o.style.setProperty("--top",e.offsetTop+L[0].offsetTop+parseInt(L[0].offsetHeight/2)+"px")),E.getPropertyValue("--loop-rows")>1&&L[0]&&o.style.setProperty("--top","calc(50% + "+parseInt(e.offsetTop/2)+"px)")}if(d){var x=r.querySelector('[data-index="'+(t-p)*(s?-1:1)+'"]'),N=r.getElementsByTagName("button");for(v=0;v<N.length;v++)N[v].className="";x&&(x.className="active")}}function P(t){if(!e.classList.contains(x)){var n=e.scrollLeft;!function(e,t,n,i,o,r,l){var a=[.425,.005,0,1];a=BezierEasing(a[0],a[1],a[2],a[3]);const s=o=>{e[t]=n+(i-n)*o},u=Date.now(),d=()=>{var e=(Date.now()-u)/o;e>1?(s(1),l&&l()):(requestAnimationFrame(d),s(a(e)))};r&&r();d()}(e,"scrollLeft",n,t,1500,(function(){E=!0,e.classList.add(x)}),(function(){E=!1,e.classList.remove(x),T()}))}}e.className+=" block-loop-slider",u&&((o=document.createElement("div")).className="block-loop-nav",e.parentNode.appendChild(o),function(){A();var e="";e='<div class="'+h+'"><button>'+w+'</button></div><span></span><div class="'+y+'"><button>'+L+"</button></div>",o.innerHTML=e,l=o.getElementsByClassName(h)[0],a=o.getElementsByClassName(y)[0],l.addEventListener("click",k),a.addEventListener("click",k)}()),d&&((r=document.createElement("div")).className="block-loop-dot",e.parentNode.appendChild(r),N()),g&&P(O()),c&&T(),S(),e.addEventListener("ontouchstart"in window?"touchstart":"mouseenter",(function(){c=!1})),e.addEventListener("ontouchstart"in window?"touchend":"mouseleave",(function(){c=!0})),e.addEventListener("scroll",(function(){n||(requestAnimationFrame((function(){S(),n=!1})),n=!0)})),window.addEventListener("resize",i)},window.scroller=function(e,t){t=t||{};var n=(e=e).querySelector(".scroller")??e.nextElementSibling?.closest(".scroller"),i=0!=t.autoTrigger,o=t.autoTriggerUntil||1e3,r=0,l=t.loadingHtml||'<span class="spinner"></span><span class="screen-reader-text"></span>';if(n){var a=window,s=getComputedStyle(n.parentElement).getPropertyValue("overflow-y");"scroll"!=s&&"auto"!=s||(a=n.parentElement),a.addEventListener("scroll",(function(){n&&function(e,t,n){var i=e.offsetTop,o=i+e.clientHeight,r=t.pageYOffset?t.pageYOffset:t.scrollTop,l=r+(t.pageYOffset?t.innerHeight:t.clientHeight),a=n&&(i<r&&o>r||o>l&&i<l);return i>=r&&o<=l||a}(n,a)&&i&&r<o&&u()}),!1),n.addEventListener("click",u,!1)}function u(t){if(t&&t.preventDefault(),t&&t.stopPropagation(),!(n.className.indexOf("is-loading")>-1)){n.innerHTML=l,n.className+=" is-loading";var i=n.href,o=new XMLHttpRequest;o.responseType="json",o.onreadystatechange=function(){if(4==o.readyState&&200==o.status){n.className="",n.removeEventListener("click",u),n.remove();var t,i=document.createElement("div");for(i.innerHTML=o.response.content;t=i.firstChild;)e.appendChild(t);(n=e.querySelector(".scroller")??e.nextElementSibling?.closest(".scroller"))&&n.addEventListener("click",u,!1),document.dispatchEvent(new Event("refresh")),r++}},o.open("GET",i,!0),"undefined"!=typeof play&&void 0!==play.nonce&&o.setRequestHeader("X-WP-Nonce",play.nonce),o.send()}}},window.range=function(e){var t=e.getAttribute("value"),n=null===t?[]:t.split(","),i=+(e.min||0),o=+(e.max||100),r=document.createElement("span"),l=document.createElement("span"),a=e.cloneNode();e.classList.add("multirange"),e.classList.add("original"),a.classList.add("multirange"),a.classList.add("ghost"),r.classList.add("range-min"),l.classList.add("range-max"),e.value=n[0]||i+(o-i)/2,a.value=n[1]||i+(o-i)/2,e.parentNode.insertBefore(a,e.nextSibling),e.parentNode.insertBefore(r,e.previousSibling),e.parentNode.insertBefore(l,e.previousSibling);var s=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");function u(t){var n=(e.valueLow-i)/(o-i)*100,s=(e.valueHigh-i)/(o-i)*100;a.style.setProperty("--low",n+"%"),a.style.setProperty("--high",s+"%"),r&&(r.innerHTML=e.valueLow,r.style.setProperty("--left",n)),l&&(l.innerHTML=e.valueHigh,l.style.setProperty("--left",s)),1!==t&&(clearTimeout(d),d=setTimeout((function(){var t=e.getAttribute("data-url"),n=e.getAttribute("name"),i=(e.getAttribute("type"),new RegExp(n+"__(\\d+)-(\\d+)[%2C]*[(\\d+)\\-(\\d+)]*"));t=t.replace(i,n+"__"+e.valueLow+"-"+e.valueHigh),"undefined"==typeof Pjax?location.href=t:document.dispatchEvent(new CustomEvent("reload",{detail:{url:t}}))}),1e3))}Object.defineProperty(e,"originalValue",s.get?s:{get:function(){return this.value},set:function(e){this.value=e}}),Object.defineProperties(e,{valueLow:{get:function(){return Math.min(this.originalValue,a.value)},set:function(e){this.originalValue=e,u()},enumerable:!0},valueHigh:{get:function(){return Math.max(this.originalValue,a.value)},set:function(e){a.value=e,u()},enumerable:!0}}),s.get&&Object.defineProperty(e,"value",{get:function(){return this.valueLow+","+this.valueHigh},set:function(e){var t=e.split(",");this.valueLow=t[0],this.valueHigh=t[1],u()},enumerable:!0}),"function"==typeof e.oninput&&(a.oninput=e.oninput.bind(e)),a.addEventListener("mousedown",(function(t){var n=i+(o-i)*t.offsetX/this.offsetWidth,r=(e.valueHigh+e.valueLow)/2;e.valueLow==a.value==n>r&&(e.value=a.value)})),e.addEventListener("input",u),a.addEventListener("input",u);var d=null;u(1)},on("click",".dropdown-toggle-filter",(function(e){e.preventDefault();var t=this.nextElementSibling;t&&(t.classList.toggle("show"),t.parentNode.querySelector(".dropdown-backdrop")||t.parentNode.insertAdjacentHTML("beforeend",'<div class="dropdown-backdrop"></div>'),on("click",".dropdown-backdrop",(function(e){t.classList.remove("show")})))})),window.addEventListener("call:plugin",(function(){plugin()})),window.addEventListener("pjax:complete",(function(){init()})),init()}(); -
loops-block/trunk/build/loop/block.json
r3622994 r3725635 178 178 "default": false 179 179 }, 180 "transient_cache":{ 181 "type" : "boolean", 182 "default": false 183 }, 180 184 "className" : { 181 185 "type" : "string", -
loops-block/trunk/build/loop/index.js
r3622994 r3725635 1 !function(e,o){const{createElement:t,useState:l}=e.element,{RichText:a,BlockControls:n,InnerBlocks:s,AlignmentToolbar:i,MediaUpload:r,InspectorControls:u,useBlockProps: b}=e.blockEditor,{TextControl:p,Button:c,SelectControl:d,RangeControl:m,ToggleControl:v,RadioControl:g,CheckboxControl:k,TextareaControl:f,FormTokenField:h,DatePicker:y,Autocomplete:C,Dropdown:A,Placeholder:x,PanelBody:T}=e.components,D=e.apiFetch,_=e.serverSideRender,N=e.blocks.registerBlockType,w=e.i18n.__;var L=t("svg",{width:16,height:20,viewBox:"0 0 16 16"},t("path",{d:"M5.68 5.792 7.345 7.75 5.681 9.708a2.75 2.75 0 1 1 0-3.916ZM8 6.978 6.416 5.113l-.014-.015a3.75 3.75 0 1 0 0 5.304l.014-.015L8 8.522l1.584 1.865.014.015a3.75 3.75 0 1 0 0-5.304l-.014.015zm.656.772 1.663-1.958a2.75 2.75 0 1 1 0 3.916z"}));N("block/loop",{title:w("Loops","loops-block"),description:w("An advanced block that allows displaying posts, taxonomies and users based on different query parameters and visual configurations.","loops-block"),icon:L,category:"common",edit:function(a){var n=a.attributes,s=b(),i=e.hooks.applyFilters("hook_orderby",[{label:"No order",value:"none"},{label:"ID",value:"ID"},{label:"Title",value:"title"},{label:"Author",value:"author"},{label:"Published date",value:"date"},{label:"Modified date",value:"modified"},{label:"By parent",value:"parent"},{label:"Random order",value:"rand"},{label:"Comment count",value:"comment_count"},{label:"Menu order",value:"menu_order"},{label:"Meta value",value:"meta_value"},{label:"Numeric meta value",value:"meta_value_num"},{label:"By include order",value:"post__in"}]);const[k,C]=l([]),[N,I]=l([]),[S,M]=l([]);return[t(u,{key:"inspector"},t(T,{title:w("General","loops-block"),className:"block-display",initialOpen:!0},t(p,{label:w("ID","loops-block"),value:n.id,onChange:function(e){a.setAttributes({id:e})}}),t(d,{label:w("Type","loops-block"),options:loopsblock.types,value:n.type,onChange:function(e){a.setAttributes({type:e})}}),"taxonomy"==n.type&&t(d,{label:w("Taxonomies","loops-block"),options:loopsblock.taxonomies,value:n.taxonomy,onChange:function(e){a.setAttributes({taxonomy:e})}}),t(d,{label:w("Template","loops-block"),options:loopsblock.templates,value:n.template,onChange:function(e){a.setAttributes({template:e})}}),"user"!==n.type&&"taxonomy"!==n.type&&t(d,{label:w("Order by","loops-block"),options:i,value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),"user"==n.type&&t(d,{label:w("Order by","loops-block"),options:[{label:"No order",value:"none"},{label:"ID",value:"ID"},{label:"Display Name",value:"display_name"},{label:"Name",value:"user_name"},{label:"Login",value:"user_login"},{label:"Nicename",value:"user_nicename"},{label:"Email",value:"user_email"},{label:"URL",value:"user_url"},{label:"Registered",value:"user_registered"},{label:"Post count",value:"post_count"},{label:"Include",value:"include"},{label:"Meta value",value:"meta_value"},{label:"Numeric meta value",value:"meta_value_num"}],value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),"taxonomy"==n.type&&t(d,{label:w("Order by","loops-block"),options:[{label:"No order",value:"none"},{label:"ID",value:"term_id"},{label:"Name",value:"name"},{label:"Count",value:"count"}],value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),t(d,{label:w("Order","loops-block"),options:[{label:"Descending",value:"DESC"},{label:"Ascending",value:"ASC"}],value:n.order,onChange:function(e){a.setAttributes({order:e})}}),t(v,{label:w("Debug","loops-block"),checked:n.debug,onChange:function(e){a.setAttributes({debug:e})}})),t(T,{title:w("Query","loops-block"),initialOpen:!1},t("div",{},t(h,{label:w("IDs in","loops-block"),value:n.ids,suggestions:k,onChange:function(e){a.setAttributes({ids:e})},saveTransform:function(e){return e.split(":")[0]},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;D({path:"/loop/ids"+o}).then((function(e){C(e)}))}}})),"user"!==n.type&&"taxonomy"!==n.type&&t("div",{},t(h,{label:w("Taxonomies (taxonomy:term:operator)","loops-block"),value:n.taxQuery,suggestions:N,onChange:function(e){a.setAttributes({taxQuery:e})},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;D({path:"/loop/terms"+o}).then((function(e){I(e)}))}}})),"taxonomy"!==n.type&&t("div",{},t(h,{label:w("Meta (key:value:compare:type)","loops-block"),value:n.metaQuery,onChange:function(e){a.setAttributes({metaQuery:e})}})),"taxonomy"!==n.type&&t(g,{label:w("Date","loops-block"),options:[{label:w("Anytime","loops-block"),value:"0"},{label:w("Specific","loops-block"),value:"1"},{label:w("Relative","loops-block"),value:"2"}],selected:n.date.type,onChange:function(e){var o=lodash.cloneDeep(n.date);o.type=e,a.setAttributes({date:o})}}),"1"==n.date.type&&t("div",{className:"components-panel__row components-loop-date"},t(A,{position:"bottom right",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("From","loops-block")),t(c,{isLink:!0},n.date.after))},renderContent:function(e){return t(y,{currentDate:n.date.after,onChange:function(e){var o=lodash.cloneDeep(n.date);o.after=moment(e).format("YYYY-MM-DD"),a.setAttributes({date:o})}})}}),t(A,{position:"bottom right",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("To","loops-block")),t(c,{isLink:!0},n.date.before))},renderContent:function(e){return t(y,{currentDate:n.date.before,onChange:function(e){var o=lodash.cloneDeep(n.date);o.before=moment(e).format("YYYY-MM-DD"),a.setAttributes({date:o})}})}})),"2"==n.date.type&&t("div",{className:"components-panel__row components-loop-date"},t(A,{position:"bottom right",contentClassName:"components-loop-date-popup",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("From","loops-block")),t(c,{isLink:!0},n.date.afterNum+" "+n.date.afterUnit))},renderContent:function(e){return t("div",{className:"components-loop-date-dialog"},t(p,{type:"number",value:n.date.afterNum,onChange:function(e){var o=lodash.cloneDeep(n.date);o.afterNum=e,a.setAttributes({date:o})}}),t(d,{options:[{label:"Days",value:"days ago"},{label:"Weeks",value:"weeks ago"},{label:"Months",value:"months ago"},{label:"Years",value:"years ago"}],value:n.date.afterUnit,onChange:function(e){var o=lodash.cloneDeep(n.date);o.afterUnit=e,a.setAttributes({date:o})}}),t("span",{},w("ago","loops-block")))}}),t(A,{position:"bottom right",contentClassName:"components-loop-date-popup",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("To","loops-block")),t(c,{isLink:!0},n.date.beforeNum+" "+n.date.beforeUnit))},renderContent:function(e){return t("div",{className:"components-loop-date-dialog"},t(p,{type:"number",value:n.date.beforeNum,onChange:function(e){var o=lodash.cloneDeep(n.date);o.beforeNum=e,a.setAttributes({date:o})}}),t(d,{options:[{label:"Days",value:"days ago"},{label:"Weeks",value:"weeks ago"},{label:"Months",value:"months ago"},{label:"Years",value:"years ago"}],value:n.date.beforeUnit,onChange:function(e){var o=lodash.cloneDeep(n.date);o.beforeUnit=e,a.setAttributes({date:o})}}),t("span",{},w("ago","loops-block")))}})),t(p,{label:w("Query arguments","loops-block"),value:n.query,rows:1,help:w("eg: post_type=any. See WP_Query, WP_User_Query and WP_Term_Query","loops-block"),onChange:function(e){a.setAttributes({query:e})}})),t(T,{title:w("Title & Link","loops-block"),className:"block-display",initialOpen:!1},t(p,{label:w("Title","loops-block"),value:n.title,onChange:function(e){a.setAttributes({title:e})}}),t(p,{label:w("Subtitle","loops-block"),value:n.subtitle,onChange:function(e){a.setAttributes({subtitle:e})}}),t(p,{label:w("Link Text","loops-block"),value:n.linkText,onChange:function(e){a.setAttributes({linkText:e})}}),t(p,{label:w("Link URL","loops-block"),value:n.link,placeholder:"http://",onChange:function(e){a.setAttributes({link:e})}})),t(T,{title:w("Display","loops-block"),className:"block-display",initialOpen:!1},t(d,{label:w("Display","loops-block"),options:[{label:"Grid",value:"grid"},{label:"List",value:"row"},{label:"Mixed",value:"mixed"}],value:n.display,onChange:function(e){a.setAttributes({display:e})}}),t(v,{label:w("Index style","loops-block"),checked:n.index,onChange:function(e){a.setAttributes({index:e})}}),"mixed"!==n.display&&t(m,{label:w("Columns","loops-block"),value:n.cols,min:-1,max:12,onChange:function(e){a.setAttributes({cols:e})}}),t(m,{label:w("Rows","loops-block"),value:n.rows,min:-1,max:12,onChange:function(e){a.setAttributes({rows:e})}}),t(m,{label:w("Gap","loops-block"),value:n.gap,min:-1,max:100,onChange:function(e){a.setAttributes({gap:e})}}),t(m,{label:w("Thumbnail ratio","loops-block"),value:n.ratio,min:0,max:3,step:.01,onChange:function(e){a.setAttributes({ratio:e})}}),t(d,{label:w("Thumbnail size","loops-block"),options:loopsblock.image_sizes,value:n.image,onChange:function(e){a.setAttributes({image:e})}}),t(m,{label:w("Post per page","loops-block"),value:n.pages,onChange:function(e){a.setAttributes({pages:e})}}),t(d,{label:w("Pager","loops-block"),options:[{label:"None",value:""},{label:"Pagination",value:"pagination"},{label:"Load More",value:"more"},{label:"Scroll",value:"scroll"}],value:n.pager,onChange:function(e){a.setAttributes({pager:e})}}),t(v,{label:w("Enable slider","loops-block"),checked:n.slider,onChange:function(e){a.setAttributes({slider:e})}}),n.slider&&t("div",{className:""},t(v,{label:w("Prev/Next arrows","loops-block"),checked:n.sliderArrows,onChange:function(e){a.setAttributes({sliderArrows:e})}}),t(v,{label:w("Show dot indicators","loops-block"),checked:n.sliderDots,onChange:function(e){a.setAttributes({sliderDots:e})}}),t(v,{label:w("Enable autoplay","loops-block"),checked:n.sliderAutoplay,onChange:function(e){a.setAttributes({sliderAutoplay:e})}}),t(v,{label:w("Loop slider","loops-block"),checked:n.sliderLoop,onChange:function(e){a.setAttributes({sliderLoop:e})}}),t("p")),t(v,{label:w("Show empty","loops-block"),checked:n.empty,onChange:function(e){a.setAttributes({empty:e})}}),n.empty&&t(f,{label:w("Empty content","loops-block"),value:n.emptyContent,onChange:function(e){a.setAttributes({emptyContent:e})}})),t(T,{title:w("Filter","loops-block"),className:"block-display",initialOpen:!1},t(d,{label:w("Style","loops-block"),options:[{label:"Dropdown",value:"dropdown"},{label:"List",value:"list"}],value:n.filterStyle,onChange:function(e){a.setAttributes({filterStyle:e})}}),t(v,{label:w("Show filter keys","loops-block"),checked:n.filterKeys,onChange:function(e){a.setAttributes({filterKeys:e})}}),n.filterKeys&&t(f,{label:w("Clear filters text","loops-block"),value:n.filterClearText,onChange:function(e){a.setAttributes({filterClearText:e})}}),t(h,{label:w("filter::value[name]","loops-block"),value:n.filter,suggestions:S,className:"components-form-token-filter",onChange:function(e){a.setAttributes({filter:e})},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;D({path:"/loop/filter"+o}).then((function(e){M(e)}))}},onFocus:function(e){var t=o(".components-form-token-filter .components-flex");t.sortable({items:"> div",update:function(e,l){var n=t.find("> div").map((function(){return o.trim(o(this).find("> span > span > span:last").text())})).get();a.setAttributes({filter:n})}})}}),t("p",{className:"components-base-control__help"},w("Enter 3 or more characters","loops-block"))),t(T,{title:w("AD","loops-block"),className:"block-display",initialOpen:!1},t(p,{label:w("Image","loops-block"),placeholder:w("Enter, upload, choose from Media Library","loops-block"),value:n.adImage,onChange:function(e){a.setAttributes({adImage:e})}}),t(r,{allowedTypes:"image/jpeg,image/png,image/webp,image/gif,video/mp4,video/quicktime",onSelect:function(e){return a.setAttributes({adImage:e.url})},render:function(e){return t("div",{style:{display:"inline-flex",margin:"-1.5rem 0 1rem 0"}},t(c,{icon:"upload",label:w("Upload","loops-block"),onClick:e.open}),t(c,{icon:"no-alt",label:w("Clear","loops-block"),onClick:function(){a.setAttributes({adImage:""})}}))}}),t(p,{label:w("Title","loops-block"),value:n.adTitle,onChange:function(e){a.setAttributes({adTitle:e})}}),t(p,{label:w("Subtitle","loops-block"),value:n.adSubtitle,onChange:function(e){a.setAttributes({adSubtitle:e})}}),t(p,{label:w("Sponsor","loops-block"),value:n.adSponsor,onChange:function(e){a.setAttributes({adSponsor:e})}}),t(p,{label:w("Link URL","loops-block"),value:n.adLink,placeholder:"http://",onChange:function(e){a.setAttributes({adLink:e})}}),t(p,{label:w("Order","loops-block"),value:n.adOrder,type:"number",onChange:function(e){a.setAttributes({adOrder:e})}}))),t("div",s,""===n.type?t(x,{icon:L,label:w("Loops","loops-block"),instructions:w("Display post taxonomy & user items in loop.","loops-block")},t(d,{label:w("Choose loop type","loops-block"),options:loopsblock.types,value:n.type,onChange:function(e){a.setAttributes({type:e})}})):t(_,{block:"block/loop",attributes:n}))]},save:function(){return null}})}(window.wp,jQuery);1 !function(e,o){const{createElement:t,useState:l}=e.element,{RichText:a,BlockControls:n,InnerBlocks:s,AlignmentToolbar:i,MediaUpload:r,InspectorControls:u,useBlockProps:c}=e.blockEditor,{TextControl:b,Button:p,SelectControl:d,RangeControl:m,ToggleControl:v,RadioControl:g,CheckboxControl:k,TextareaControl:f,FormTokenField:h,DatePicker:y,Autocomplete:C,Dropdown:A,Placeholder:x,PanelBody:T}=e.components,_=e.apiFetch,D=e.serverSideRender,N=e.blocks.registerBlockType,w=e.i18n.__;var L=t("svg",{width:16,height:20,viewBox:"0 0 16 16"},t("path",{d:"M5.68 5.792 7.345 7.75 5.681 9.708a2.75 2.75 0 1 1 0-3.916ZM8 6.978 6.416 5.113l-.014-.015a3.75 3.75 0 1 0 0 5.304l.014-.015L8 8.522l1.584 1.865.014.015a3.75 3.75 0 1 0 0-5.304l-.014.015zm.656.772 1.663-1.958a2.75 2.75 0 1 1 0 3.916z"}));N("block/loop",{title:w("Loops","loops-block"),description:w("An advanced block that allows displaying posts, taxonomies and users based on different query parameters and visual configurations.","loops-block"),icon:L,category:"common",edit:function(a){var n=a.attributes,s=c(),i=e.hooks.applyFilters("hook_orderby",[{label:"No order",value:"none"},{label:"ID",value:"ID"},{label:"Title",value:"title"},{label:"Author",value:"author"},{label:"Published date",value:"date"},{label:"Modified date",value:"modified"},{label:"By parent",value:"parent"},{label:"Random order",value:"rand"},{label:"Comment count",value:"comment_count"},{label:"Menu order",value:"menu_order"},{label:"Meta value",value:"meta_value"},{label:"Numeric meta value",value:"meta_value_num"},{label:"By include order",value:"post__in"}]);const[k,C]=l([]),[N,I]=l([]),[S,M]=l([]);return[t(u,{key:"inspector"},t(T,{title:w("General","loops-block"),className:"block-display",initialOpen:!0},t(b,{label:w("ID","loops-block"),value:n.id,onChange:function(e){a.setAttributes({id:e})}}),t(d,{label:w("Type","loops-block"),options:loopsblock.types,value:n.type,onChange:function(e){a.setAttributes({type:e})}}),"taxonomy"==n.type&&t(d,{label:w("Taxonomies","loops-block"),options:loopsblock.taxonomies,value:n.taxonomy,onChange:function(e){a.setAttributes({taxonomy:e})}}),t(d,{label:w("Template","loops-block"),options:loopsblock.templates,value:n.template,onChange:function(e){a.setAttributes({template:e})}}),"user"!==n.type&&"taxonomy"!==n.type&&t(d,{label:w("Order by","loops-block"),options:i,value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),"user"==n.type&&t(d,{label:w("Order by","loops-block"),options:[{label:"No order",value:"none"},{label:"ID",value:"ID"},{label:"Display Name",value:"display_name"},{label:"Name",value:"user_name"},{label:"Login",value:"user_login"},{label:"Nicename",value:"user_nicename"},{label:"Email",value:"user_email"},{label:"URL",value:"user_url"},{label:"Registered",value:"user_registered"},{label:"Post count",value:"post_count"},{label:"Include",value:"include"},{label:"Meta value",value:"meta_value"},{label:"Numeric meta value",value:"meta_value_num"}],value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),"taxonomy"==n.type&&t(d,{label:w("Order by","loops-block"),options:[{label:"No order",value:"none"},{label:"ID",value:"term_id"},{label:"Name",value:"name"},{label:"Count",value:"count"}],value:n.orderby,onChange:function(e){a.setAttributes({orderby:e})}}),t(d,{label:w("Order","loops-block"),options:[{label:"Descending",value:"DESC"},{label:"Ascending",value:"ASC"}],value:n.order,onChange:function(e){a.setAttributes({order:e})}}),t(v,{label:w("Debug","loops-block"),checked:n.debug,onChange:function(e){a.setAttributes({debug:e})}}),t(v,{label:w("Enable transient cache","loops-block"),checked:n.transient_cache,onChange:function(e){a.setAttributes({transient_cache:e})}})),t(T,{title:w("Query","loops-block"),initialOpen:!1},t("div",{},t(h,{label:w("IDs in","loops-block"),value:n.ids,suggestions:k,onChange:function(e){a.setAttributes({ids:e})},saveTransform:function(e){return e.split(":")[0]},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;_({path:"/loop/ids"+o}).then((function(e){C(e)}))}}})),"user"!==n.type&&"taxonomy"!==n.type&&t("div",{},t(h,{label:w("Taxonomies (taxonomy:term:operator)","loops-block"),value:n.taxQuery,suggestions:N,onChange:function(e){a.setAttributes({taxQuery:e})},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;_({path:"/loop/terms"+o}).then((function(e){I(e)}))}}})),"taxonomy"!==n.type&&t("div",{},t(h,{label:w("Meta (key:value:compare:type)","loops-block"),value:n.metaQuery,onChange:function(e){a.setAttributes({metaQuery:e})}})),"taxonomy"!==n.type&&t(g,{label:w("Date","loops-block"),options:[{label:w("Anytime","loops-block"),value:"0"},{label:w("Specific","loops-block"),value:"1"},{label:w("Relative","loops-block"),value:"2"}],selected:n.date.type,onChange:function(e){var o=lodash.cloneDeep(n.date);o.type=e,a.setAttributes({date:o})}}),"1"==n.date.type&&t("div",{className:"components-panel__row components-loop-date"},t(A,{position:"bottom right",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("From","loops-block")),t(p,{isLink:!0},n.date.after))},renderContent:function(e){return t(y,{currentDate:n.date.after,onChange:function(e){var o=lodash.cloneDeep(n.date);o.after=moment(e).format("YYYY-MM-DD"),a.setAttributes({date:o})}})}}),t(A,{position:"bottom right",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("To","loops-block")),t(p,{isLink:!0},n.date.before))},renderContent:function(e){return t(y,{currentDate:n.date.before,onChange:function(e){var o=lodash.cloneDeep(n.date);o.before=moment(e).format("YYYY-MM-DD"),a.setAttributes({date:o})}})}})),"2"==n.date.type&&t("div",{className:"components-panel__row components-loop-date"},t(A,{position:"bottom right",contentClassName:"components-loop-date-popup",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("From","loops-block")),t(p,{isLink:!0},n.date.afterNum+" "+n.date.afterUnit))},renderContent:function(e){return t("div",{className:"components-loop-date-dialog"},t(b,{type:"number",value:n.date.afterNum,onChange:function(e){var o=lodash.cloneDeep(n.date);o.afterNum=e,a.setAttributes({date:o})}}),t(d,{options:[{label:"Days",value:"days ago"},{label:"Weeks",value:"weeks ago"},{label:"Months",value:"months ago"},{label:"Years",value:"years ago"}],value:n.date.afterUnit,onChange:function(e){var o=lodash.cloneDeep(n.date);o.afterUnit=e,a.setAttributes({date:o})}}),t("span",{},w("ago","loops-block")))}}),t(A,{position:"bottom right",contentClassName:"components-loop-date-popup",renderToggle:function(e){e.isOpen;var o=e.onToggle;return t("div",{onClick:o},t("label",{},w("To","loops-block")),t(p,{isLink:!0},n.date.beforeNum+" "+n.date.beforeUnit))},renderContent:function(e){return t("div",{className:"components-loop-date-dialog"},t(b,{type:"number",value:n.date.beforeNum,onChange:function(e){var o=lodash.cloneDeep(n.date);o.beforeNum=e,a.setAttributes({date:o})}}),t(d,{options:[{label:"Days",value:"days ago"},{label:"Weeks",value:"weeks ago"},{label:"Months",value:"months ago"},{label:"Years",value:"years ago"}],value:n.date.beforeUnit,onChange:function(e){var o=lodash.cloneDeep(n.date);o.beforeUnit=e,a.setAttributes({date:o})}}),t("span",{},w("ago","loops-block")))}})),t(b,{label:w("Query arguments","loops-block"),value:n.query,rows:1,help:w("eg: post_type=any. See WP_Query, WP_User_Query and WP_Term_Query","loops-block"),onChange:function(e){a.setAttributes({query:e})}})),t(T,{title:w("Title & Link","loops-block"),className:"block-display",initialOpen:!1},t(b,{label:w("Title","loops-block"),value:n.title,onChange:function(e){a.setAttributes({title:e})}}),t(b,{label:w("Subtitle","loops-block"),value:n.subtitle,onChange:function(e){a.setAttributes({subtitle:e})}}),t(b,{label:w("Link Text","loops-block"),value:n.linkText,onChange:function(e){a.setAttributes({linkText:e})}}),t(b,{label:w("Link URL","loops-block"),value:n.link,placeholder:"http://",onChange:function(e){a.setAttributes({link:e})}})),t(T,{title:w("Display","loops-block"),className:"block-display",initialOpen:!1},t(d,{label:w("Display","loops-block"),options:[{label:"Grid",value:"grid"},{label:"List",value:"row"},{label:"Mixed",value:"mixed"}],value:n.display,onChange:function(e){a.setAttributes({display:e})}}),t(v,{label:w("Index style","loops-block"),checked:n.index,onChange:function(e){a.setAttributes({index:e})}}),"mixed"!==n.display&&t(m,{label:w("Columns","loops-block"),value:n.cols,min:-1,max:12,onChange:function(e){a.setAttributes({cols:e})}}),t(m,{label:w("Rows","loops-block"),value:n.rows,min:-1,max:12,onChange:function(e){a.setAttributes({rows:e})}}),t(m,{label:w("Gap","loops-block"),value:n.gap,min:-1,max:100,onChange:function(e){a.setAttributes({gap:e})}}),t(m,{label:w("Thumbnail ratio","loops-block"),value:n.ratio,min:0,max:3,step:.01,onChange:function(e){a.setAttributes({ratio:e})}}),t(d,{label:w("Thumbnail size","loops-block"),options:loopsblock.image_sizes,value:n.image,onChange:function(e){a.setAttributes({image:e})}}),t(m,{label:w("Post per page","loops-block"),value:n.pages,onChange:function(e){a.setAttributes({pages:e})}}),t(d,{label:w("Pager","loops-block"),options:[{label:"None",value:""},{label:"Pagination",value:"pagination"},{label:"Load More",value:"more"},{label:"Scroll",value:"scroll"}],value:n.pager,onChange:function(e){a.setAttributes({pager:e})}}),t(v,{label:w("Enable slider","loops-block"),checked:n.slider,onChange:function(e){a.setAttributes({slider:e})}}),n.slider&&t("div",{className:""},t(v,{label:w("Prev/Next arrows","loops-block"),checked:n.sliderArrows,onChange:function(e){a.setAttributes({sliderArrows:e})}}),t(v,{label:w("Show dot indicators","loops-block"),checked:n.sliderDots,onChange:function(e){a.setAttributes({sliderDots:e})}}),t(v,{label:w("Enable autoplay","loops-block"),checked:n.sliderAutoplay,onChange:function(e){a.setAttributes({sliderAutoplay:e})}}),t(v,{label:w("Loop slider","loops-block"),checked:n.sliderLoop,onChange:function(e){a.setAttributes({sliderLoop:e})}}),t("p")),t(v,{label:w("Show empty","loops-block"),checked:n.empty,onChange:function(e){a.setAttributes({empty:e})}}),n.empty&&t(f,{label:w("Empty content","loops-block"),value:n.emptyContent,onChange:function(e){a.setAttributes({emptyContent:e})}})),t(T,{title:w("Filter","loops-block"),className:"block-display",initialOpen:!1},t(d,{label:w("Style","loops-block"),options:[{label:"Dropdown",value:"dropdown"},{label:"List",value:"list"}],value:n.filterStyle,onChange:function(e){a.setAttributes({filterStyle:e})}}),t(v,{label:w("Show filter keys","loops-block"),checked:n.filterKeys,onChange:function(e){a.setAttributes({filterKeys:e})}}),n.filterKeys&&t(f,{label:w("Clear filters text","loops-block"),value:n.filterClearText,onChange:function(e){a.setAttributes({filterClearText:e})}}),t(h,{label:w("filter::value[name]","loops-block"),value:n.filter,suggestions:S,className:"components-form-token-filter",onChange:function(e){a.setAttributes({filter:e})},onInputChange:function(e){if(!(e.length<2||/^https?:/.test(e))){var o="?search="+encodeURIComponent(e)+"&type="+n.type;_({path:"/loop/filter"+o}).then((function(e){M(e)}))}},onFocus:function(e){var t=o(".components-form-token-filter .components-flex");t.sortable({items:"> div",update:function(e,l){var n=t.find("> div").map((function(){return o.trim(o(this).find("> span > span > span:last").text())})).get();a.setAttributes({filter:n})}})}}),t("p",{className:"components-base-control__help"},w("Enter 3 or more characters","loops-block"))),t(T,{title:w("AD","loops-block"),className:"block-display",initialOpen:!1},t(b,{label:w("Image","loops-block"),placeholder:w("Enter, upload, choose from Media Library","loops-block"),value:n.adImage,onChange:function(e){a.setAttributes({adImage:e})}}),t(r,{allowedTypes:"image/jpeg,image/png,image/webp,image/gif,video/mp4,video/quicktime",onSelect:function(e){return a.setAttributes({adImage:e.url})},render:function(e){return t("div",{style:{display:"inline-flex",margin:"-1.5rem 0 1rem 0"}},t(p,{icon:"upload",label:w("Upload","loops-block"),onClick:e.open}),t(p,{icon:"no-alt",label:w("Clear","loops-block"),onClick:function(){a.setAttributes({adImage:""})}}))}}),t(b,{label:w("Title","loops-block"),value:n.adTitle,onChange:function(e){a.setAttributes({adTitle:e})}}),t(b,{label:w("Subtitle","loops-block"),value:n.adSubtitle,onChange:function(e){a.setAttributes({adSubtitle:e})}}),t(b,{label:w("Sponsor","loops-block"),value:n.adSponsor,onChange:function(e){a.setAttributes({adSponsor:e})}}),t(b,{label:w("Link URL","loops-block"),value:n.adLink,placeholder:"http://",onChange:function(e){a.setAttributes({adLink:e})}}),t(b,{label:w("Order","loops-block"),value:n.adOrder,type:"number",onChange:function(e){a.setAttributes({adOrder:e})}}))),t("div",s,""===n.type?t(x,{icon:L,label:w("Loops","loops-block"),instructions:w("Display post taxonomy & user items in loop.","loops-block")},t(d,{label:w("Choose loop type","loops-block"),options:loopsblock.types,value:n.type,onChange:function(e){a.setAttributes({type:e})}})):t(D,{block:"block/loop",attributes:n}))]},save:function(){return null}})}(window.wp,jQuery); -
loops-block/trunk/build/style.css
r3622994 r3725635 828 828 .block-loop-row .entry-description, 829 829 .block-loop-row .entry-info, 830 .is-series . entry-description,831 .is-series . entry-info{830 .is-series .block-loop-item .entry-description, 831 .is-series .block-loop-item .entry-info{ 832 832 margin-bottom: 0; 833 833 } 834 834 .block-loop-row .entry-info .play-duration, 835 .is-series . entry-info .play-duration{835 .is-series .block-loop-item .entry-info .play-duration{ 836 836 padding: 0; 837 837 } -
loops-block/trunk/build/style.min.css
r3622994 r3725635 1 :root{--loop-cols:5;--loop-xs-cols:2;--loop-rows:1;--loop-columns:max( var(--loop-cols) - 4, var(--loop-xs-cols) );--loop-grid-gap:1.5rem;--loop-row-gap:1rem;--loop-max-width:100%;--loop-min-width:0;--loop-line:2;--loop-line-height:1.3;--loop-ratio:1;--loop-radius:6px;--loop-center-width:70%;--loop-font-size:0.9375rem}.is-loop-icon{display:inline-flex;align-items:center;grid-gap:.25em}.is-loop-icon:after,.is-loop-icon:before{content:'';display:block;width:1em;height:1em;border:.125em solid currentColor;transform:rotate(45deg);border-radius:100%;order:-1}.is-loop-icon:before{border-top-right-radius:0}.is-loop-icon:after{border-bottom-left-radius:0}.wp-block-loop{position:relative}.block-loop-items{margin-bottom:1.5rem;list-style:none;display:grid;grid-gap:var(--loop-grid-gap);--loop--cols:calc((var(--loop-max-width) - (var(--loop-columns) - 1) * var(--loop-grid-gap)) / var(--loop-columns));grid-template-columns:repeat(auto-fill,minmax(var(--loop--cols),1fr))}.block-loop-slider,[data-plugin=slider]{display:grid;overflow-x:auto;border-radius:var(--loop-radius);scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;scroll-behavior:smooth;overscroll-behavior-x:none;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;grid-auto-flow:column;--loop--cols:calc((var(--loop-max-width) - (var(--loop-columns) - 1) * var(--loop-grid-gap)) / var(--loop-columns));grid-auto-columns:var(--loop--cols);grid-template-rows:repeat(var(--loop-rows),max-content);grid-template-columns:inherit!important;box-sizing:border-box}.block-loop-slider::-webkit-scrollbar,.block-loop-snaps .block-loop-items::-webkit-scrollbar{display:none}.block-loop-snaps .block-loop-items{position:fixed;z-index:2;left:0;right:0;top:var(--navbar-height);bottom:var(--mobile-menu-height);display:flex;flex-direction:column;align-items:center;overflow-y:auto;scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;scroll-behavior:smooth;overscroll-behavior-y:none;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;border-radius:var(--loop-radius);margin-bottom:0}.block-slider-scrolling{-ms-scroll-snap-type:none;scroll-snap-type:none;scroll-behavior:inherit}.block-slider-scrolling video{display:none!important}.block-loop-slider .entry-content>*,[data-plugin=slider] .entry-content>*{width:100%!important;max-width:100%!important}.block-loop-slider>*,.block-loop-snaps>*{scroll-snap-align:start}.column-sm-gap{--column-gap:var(--loop-grid-gap, 1rem)}@media (max-width:1000px){.is-stacked-tablet{flex-wrap:wrap!important}.is-stacked-tablet>.wp-block-column{flex-basis:100%!important}}@media (min-width:420px){.wp-block-loop{--loop-columns:max( min(var(--loop-cols), 5) - 3, 2 )}}@media (min-width:640px){.wp-block-loop{--loop-columns:max( var(--loop-cols) - 2, 2 )}}@media (min-width:960px){.wp-block-loop{--loop-columns:max( var(--loop-cols) - 1, 3 )}}@media (min-width:1260px){.wp-block-loop{--loop-columns:var(--loop-cols)}}.grid-1{--loop-columns:1!important}.grid-2{--loop-columns:2!important}.grid-3{--loop-columns:3!important}@media (max-width:419px){.grid-xs-1{--loop-columns:1!important}.grid-xs-2{--loop-columns:2!important}.grid-xs-3{--loop-columns:3!important}}@media (max-width:781px){.grid-sm-1{--loop-columns:1!important}.grid-sm-2{--loop-columns:2!important}.grid-sm-3{--loop-columns:3!important}}@media (max-width:991px){.grid-md-1{--loop-columns:1!important}.grid-md-2{--loop-columns:2!important}.grid-md-3{--loop-columns:3!important}}@media (min-width:1400px){.grid-xl-1{--loop-columns:1!important}.grid-xl-2{--loop-columns:2!important}.grid-xl-3{--loop-columns:3!important}}.block-loop-title{display:flex;flex-wrap:wrap;align-items:center}.block-loop-heading{width:1%;flex:1}.block-loop-more{font-size:14px;font-weight:400}.block-loop-subtitle{color:var(--text-secondary-color,#888);line-height:1.1;text-transform:none;display:block;width:100%}.block-loop-nav{opacity:0;transition:opacity .2s;position:absolute;display:flex;align-items:center;z-index:5;height:0;width:calc(100% + 2.5rem);left:-1.25rem;top:var(--top,50%)}.alignfull>.block-loop-nav{width:calc(100% - 2.5rem);left:1.25rem}.block-loop-nav span{flex:1}.wp-block-loop:hover .block-loop-nav{opacity:1}.block-loop-nav button{width:2.5rem;height:2.5rem;padding:0;border-radius:100%;display:inline-flex;justify-content:center;align-items:center;border:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.block-loop-nav button svg{pointer-events:none;transform:rotate(var(--transform-rotate,0))}.block-loop-dot-overlay .block-loop-dot{position:absolute;z-index:5;left:50%;bottom:1rem;transform:translate(-50%,0);color:#fff}.block-loop-dot-left .block-loop-dot{margin:-4rem auto 0 auto;text-align:left;max-width:var(--content-width);width:calc(100% - var(--x-gap) * 2)}.block-loop-dot{text-align:center}.block-loop-dot button{width:1.5rem;height:1.5rem;padding:0;border-radius:2rem;border:none;background-color:transparent;color:inherit}.block-loop-dot button:after{content:"";display:inline-block;width:6px;height:6px;border-radius:6px;margin:0 auto;background-color:currentColor;opacity:.5}.block-loop-dot button.active:after{opacity:1}.block-loop-center{--loop-columns:1;--loop-max-width:var(--loop-center-width)!important}.block-loop-center .block-loop-item{scroll-snap-align:center}.block-loop-center .block-loop-nav>div{height:var(--height);width:calc(50% - var(--loop-center-width)/ 2);display:flex;align-items:center}.block-loop-center .block-loop-nav .slider-right-btn{justify-content:flex-end}.scroller{width:15rem;font-size:12px!important;display:inline-flex;justify-content:center;margin:0 auto;text-decoration:none}.scroller.is-loading{cursor:wait;pointer-events:none}.block-loop-empty,.wp-block-loop .pagination,.wp-block-loop .scroller{grid-column:1/-1;order:10000}.pagination .nav-links{display:flex;align-items:center;justify-content:center}.pagination .page-numbers{padding:.25em;text-decoration:none}.wp-block-loop .navigation .next,.wp-block-loop .navigation .prev{line-height:0}.wp-block-loop .navigation .nav-next-text,.wp-block-loop .navigation .nav-prev-text,.wp-block-loop .navigation .next:before,.wp-block-loop .navigation .prev:before{display:none}.block-loop-item{position:relative;padding:0;max-width:100%;border-radius:var(--loop-radius);display:flex;flex-direction:column;flex-wrap:wrap;scroll-snap-align:start;order:10;font-size:var(--loop-font-size)}.block-loop-item:nth-child(1){order:0}.block-loop-item:nth-child(2){order:1}.block-loop-item:nth-child(3){order:2}.block-loop-item:nth-child(4){order:3}.block-loop-item:nth-child(5){order:4}.block-loop-item:nth-child(6){order:5}.block-loop-item:nth-child(7){order:6}.block-loop-item:nth-child(8){order:7}.block-loop-item:nth-child(9){order:8}.block-loop-item .entry-content,.block-loop-item .entry-footer,.block-loop-item .entry-header,.block-loop-item .post-thumbnail{width:100%;box-sizing:border-box;padding-left:0;padding-right:0}.block-loop-item .entry-header{margin-bottom:1rem}.block-loop-item .entry-footer{margin-bottom:1rem}.block-loop-item .entry-header{padding:var(--loop-header-gap,.5rem) 0;margin:0;flex:1;display:flex;align-items:flex-start;grid-gap:var(--loop-header-gap,.5rem)}.block-loop-item .entry-title{margin:0;font-weight:500;letter-spacing:0}.block-loop-item .entry-subtitle{color:var(--text-secondary-color,#888)}.block-loop-item a{text-decoration:none}.block-loop-item .entry-meta{display:flex;flex-wrap:wrap;grid-gap:0;margin:0;color:var(--text-secondary-color,#888)}.block-loop-item .byline .author,.block-loop-item .entry-artist,.block-loop-item .entry-excerpt,.block-loop-item .entry-title,.wp-block-loop-user .entry-title a{display:block;display:-webkit-box;-webkit-box-orient:vertical;text-overflow:ellipsis;white-space:normal;-webkit-line-clamp:var(--loop-line);line-height:var(--loop-line-height);font-size:inherit;overflow:hidden;padding-bottom:.1em;word-break:break-word;word-wrap:break-word}.block-loop-item .entry-excerpt{--loop-line:2}.wp-block-loop-user .entry-title{display:flex;overflow:visible}.block-loop-item .byline .author,.wp-block-loop-user .entry-title a{--loop-line:1}.block-loop-item .entry-meta>span{margin:0}.block-loop-item .wp-video,.block-loop-item .wp-video video{width:100%!important;height:auto;border-radius:inherit}.block-loop-item .attachment,.block-loop-item.attachment{float:none;width:100%}.block-loop-item.attachment audio~p{display:none}.block-loop-item .post-thumbnail br,.block-loop-item .post-thumbnail p{display:none}.block-loop-item .post-thumbnail{width:100%;position:relative;margin:0;padding:0;border-radius:inherit;background-color:rgba(110,120,130,.2)}.block-loop-item .btn-follow{padding:.25em .75em;font-size:12px;vertical-align:text-bottom;margin:.25rem 0}.block-loop-item .post-thumbnail a{border-radius:inherit}.block-loop-item .post-thumbnail .avatar,.block-loop-item .post-thumbnail img,.block-loop-item .post-thumbnail video{border-radius:inherit;position:absolute;width:100%;height:100%;object-fit:cover;display:inline-flex;justify-content:center;align-items:center}.block-loop-item .post-thumbnail:after{padding-top:calc(100% / var(--loop-ratio));min-height:auto;content:"";width:100%;display:block}.block-loop-item .entry-action{opacity:0;pointer-events:none;color:#fff;background-color:rgba(0,0,0,.2);position:absolute;z-index:3;left:50%;top:50%;width:100%;height:100%;padding:0 5%;border-radius:inherit;transform:translate(-50%,-50%);transition:opacity .3s;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;justify-content:space-around;box-sizing:border-box}.block-loop-item .entry-action .count{display:none}.block-loop-item .entry-action.show{z-index:10}.block-loop-item .entry-action button,.block-loop-item .entry-action button:hover{flex-shrink:0}.entry-action-link{position:absolute;width:100%;height:100%}.block-loop-item-link{padding:.75rem 1rem;background-color:var(--btn-background,rgba(150,155,160,.2));border-radius:var(--btn-radius,.5rem)}.block-loop-item-link.active,.block-loop-item-link:hover{background-color:var(--btn-background-hover,rgba(150,155,160,.3))}.block-loop-item.active .entry-action,.block-loop-item:active .entry-action,.block-loop-item:hover .entry-action,.block-loop-item:hover .entry-header-inner~.btn-more{opacity:1;pointer-events:initial}.block-loop-item .count,.comment-toolbar .count,.entry-meta .count{color:var(--text-secondary-color,#888);padding-inline-start:.25rem;-webkit-padding-start:.25rem;font-size:.85rem;font-weight:400}.block-loop-row .play-count{padding:0 .5rem}.block-loop-item .entry-avatar{width:36px;flex-shrink:0}.block-loop-item .entry-footer{display:none;margin:0}.block-loop-item .entry-description{font-size:.875rem}.block-loop-item .entry-description p{margin-bottom:0}.block-loop-item .waveform{width:100%}.block-loop-index.block-loop-row .waveform:before{content:"";display:inline-block;min-width:1rem}.wp-block-loop .btn-play{font-size:1.125rem}.block-loop-row .btn-play{font-size:.875rem}.wp-block-loop-user .post-thumbnail{width:80%;margin:10% 10% 0 10%;border-radius:50%}.wp-block-loop-user .entry-header{text-align:center;flex-direction:column;align-items:center;grid-gap:0}.wp-block-loop-user .post-thumbnail{--loop-ratio:1;border-radius:50%!important}.wp-block-loop-user.block-loop-row{--loop-grid-gap:0.75rem}.wp-block-loop-user.block-loop-row .block-loop-item{align-items:center}.wp-block-loop-user.block-loop-row .post-thumbnail{margin:0;min-width:0;width:3rem}.wp-block-loop-user.block-loop-row .entry-header{align-items:center;text-align:inherit;display:flex;flex-direction:row;gap:.5rem}.wp-block-loop-user .entry-title{font-size:.8125rem;font-weight:600;align-items:center;justify-content:center;flex:1}.wp-block-loop-user.block-loop-row .entry-title{justify-content:flex-start}.wp-block-loop-user .user-followers{font-weight:400;font-size:.85em;color:var(--text-secondary-color);width:100%}.block-loop-row{--loop-columns:1}.hide-more-actions .entry-footer>:not(.btn-more){display:none}.block-loop-row .block-loop-item{display:flex;grid-gap:var(--loop-row-gap);flex-direction:row;align-items:flex-start}.block-loop-row .entry-header{flex:1;display:flex;flex-wrap:wrap;padding:0;align-items:center;align-self:stretch;grid-gap:0}.block-loop-row .entry-avatar{display:none}.block-loop-row .post-thumbnail{width:6rem;min-width:var(--loop-min-width)}.block-loop-mixed .block-loop-item{display:flex;grid-gap:var(--loop-row-gap);flex-direction:row;--loop-header-gap:0;align-items:center}.block-loop-mixed .block-loop-item:first-child{grid-column:span calc(var(--loop-columns)/2);grid-row:span var(--loop-rows,4);align-items:stretch}.block-loop-mixed .block-loop-item:not(:first-child){grid-column:span calc(var(--loop-columns)/2)}.block-loop-mixed .block-loop-item:not(:first-child) .post-thumbnail{width:33%}@media (max-width:576px){.block-loop-mixed .block-loop-items{--loop-columns:1}}.block-loop-xs{--loop-line:1}.block-loop-xs .btn-play{font-size:.75rem}.block-loop-xs .post-thumbnail{width:3rem;border-radius:5px;min-width:auto}.block-loop-sm .post-thumbnail{width:4rem;border-radius:7px;min-width:auto}.block-loop-lg .post-thumbnail{width:10rem;min-width:auto}.block-loop-autotype .block-loop-items{--loop-columns:1}.has-loop-posts .block-loop-items{grid-gap:0;--loop-columns:1}.has-loop-posts .block-loop-item{padding:.5rem .5rem}.has-loop-posts .entry-header{flex-wrap:nowrap;padding:0}.has-loop-posts .post-thumbnail{border-radius:2px;width:3rem;flex-shrink:0}.has-loop-posts.block-loop-index .icon-play{display:none;padding:.5rem;position:absolute;top:50%;transform:translateY(-50%);line-height:0}.has-loop-posts.block-loop-index .block-loop-item.active:before,.has-loop-posts.block-loop-index .block-loop-item:hover:before{color:transparent}.has-loop-posts.block-loop-index .block-loop-item.active .icon-play,.has-loop-posts.block-loop-index .block-loop-item:hover .icon-play{display:block}.has-loop-posts .block-loop-item:hover{background-color:var(--tracks-item-odd-color,rgba(150,155,160,.1))}.has-loop-posts .block-loop-item.active{background-color:var(--tracks-item-hover-color,rgba(150,155,160,.2))}.has-loop-posts .icon-plus{display:none}.is-album .has-loop-posts .entry-meta a,.is-album .has-loop-posts .entry-title a{pointer-events:none}.has-loop-posts .entry-meta{justify-content:flex-start!important}.is-album .has-loop-posts .post-thumbnail{display:none}.is-series .has-loop-posts .block-loop-items{margin:0 -1rem}.is-series .has-loop-posts .block-loop-item{padding:.75rem 1rem;border:none!important}.is-series .has-loop-posts .block-loop-item .entry-header{padding-bottom:1rem;border-bottom:1px solid var(--color-border)}.is-series .has-loop-posts .block-loop-item.active .entry-header,.is-series .has-loop-posts .block-loop-item:hover .entry-header{border-color:transparent}.is-series .has-loop-posts .btn-play{border:1px solid var(--color-border);background-clip:padding-box}.is-series .has-loop-posts .block-loop-item>.btn-play{align-self:flex-start}.block-loop-row .entry-description,.block-loop-row .entry-info,.is-series . entry-description,.is-series .entry-info{margin-bottom:0}.block-loop-row .entry-info .play-duration,.is-series .entry-info .play-duration{padding:0}.block-loop-inline .entry-header{grid-gap:1.5rem}.block-loop-inline>button.btn-play{transform:scale(1)}.block-loop-inline .btn-play-waveform{display:none}.block-loop-inline .waveform{flex:1}.entry-header-inner{flex:1;max-width:100%}.entry-header-inner~.btn-more{margin:-.375rem -.5rem;opacity:0}.entry-header-inner .byline,.entry-header-inner .entry-artist{width:100%;justify-content:inherit}.entry-header-inner .byline{display:flex;align-items:center}.entry-meta-date{font-size:.75rem}.entry-header-inner .play-count+.entry-meta-date:before{display:inline-block;text-align:center;content:'\00B7';color:var(--text-secondary-color);width:1rem;font-weight:700}.block-loop-item .add_to_cart_inline,.block-loop-item .entry-header-inner .btn-purchase{margin:4px 0}.block-loop-item .add_to_cart_inline .btn-purchase,.block-loop-item form{margin:0!important}.block-loop-xs .add_to_cart_inline,.block-loop-xs .btn-purchase,.has-loop-posts .add_to_cart_inline,.has-loop-posts .btn-purchase{display:none}.block-loop-item .added_to_cart,.block-loop-item .btn-purchase,.plyr-playlist .btn-purchase{font-size:12px}.block-loop-item .entry-action .btn-more{position:absolute;padding:.75em;bottom:0;right:0}.block-loop-row .entry-action{justify-content:center}.block-loop-row .post-thumbnail .entry-action .btn-like,.block-loop-row .post-thumbnail .entry-action .btn-more{display:none}.block-loop-row .entry-footer{display:flex;align-items:center;padding-left:0;padding-right:0;width:auto}.block-loop-row .count,.block-loop-row .play-duration{font-size:.875em}.block-loop-row .play-duration{padding:0 .5rem}.play-count{white-space:nowrap;display:inline-flex;align-items:center;white-space:nowrap}.play-count:before{display:inline-block;width:0;height:0;content:"";border-left:.5em solid;border-top:.3em solid transparent;border-bottom:.3em solid transparent;opacity:.5}.btn-play+.play-count:before{display:none}.entry-badge .play-duration{background-color:#000;color:#fff;font-size:11px;font-weight:500;border-radius:4px;padding:1px 4px;position:absolute;right:.5rem;bottom:.5rem}.block-loop-index{counter-reset:li}.block-loop-index:not(.block-loop-row) .block-loop-item .entry-header:before{content:counter(li);counter-increment:li;font-weight:400;-ms-flex-negative:0;flex-shrink:0;opacity:.75;min-width:1rem}.block-loop-index.block-loop-row .block-loop-item:before{content:counter(li);counter-increment:li;min-width:1.5rem;font-weight:400;-ms-flex-negative:0;flex-shrink:0;opacity:.5;text-align:center;font-size:.9em;white-space:nowrap;align-self:center}.block-loop-overlay .entry-header{position:absolute;bottom:0;left:0;width:100%!important;padding:.75rem 1rem!important;box-sizing:border-box;color:#fff;background:linear-gradient(180deg,transparent,rgba(0,0,0,.85));border-radius:inherit;border-top-right-radius:0;border-top-left-radius:0;opacity:0;pointer-events:none}.block-loop-overlay .entry-header .entry-title{color:inherit;font-weight:700}.block-loop-overlay .entry-header .entry-meta,.block-loop-overlay .entry-header .entry-subtitle{color:rgba(255,255,255,.75)}.block-loop-overlay .entry-header a:hover{color:inherit}.block-loop-overlay .block-loop-item:hover .entry-header,.block-loop-overlay.block-loop-show-header .entry-header{opacity:1;pointer-events:initial;z-index:2}.block-loop-overlay-center .entry-header{top:0;opacity:1;font-weight:700;font-size:1rem;text-align:center;display:flex!important;align-items:center;justify-content:center}.block-loop-overlay-center .entry-meta{justify-content:center}.block-loop-ad .entry-meta{font-size:.75rem}.block-loop-ad.block-loop-item .post-thumbnail{background-color:var(--color-primary)}.block-loop-overlay .block-loop-ad .entry-header{background:0 0;bottom:auto}.block-loop-hero{--text-secondary-color:rgba(255,255,255,0.95);--button-radius:3rem;--loop-hero-min-height:15rem}.block-loop-hero.wp-block-loop.alignfull{margin-left:0;margin-right:0;--loop-radius:0;--loop-max-width:100%;--loop-hero-min-height:clamp(20rem, 50vh, 30rem)}.entry-content>.block-loop-hero.wp-block-loop.alignfull .block-loop-items{padding:0}.block-loop-hero .block-loop-nav{top:auto;right:2rem;bottom:5rem;width:auto;justify-content:flex-end;gap:.5rem}.block-loop-hero .block-loop-nav span,.block-loop-hero .count{display:none}.block-loop-hero .entry-header{position:absolute;top:0;left:0;bottom:0;width:100%;padding:var(--x-gap,1.5rem);color:#fff;background:linear-gradient(-135deg,transparent 0,transparent 25%,rgba(0,0,0,.6) 70%,rgba(0,0,0,1) 100%);border-radius:inherit;border-top-right-radius:0;border-bottom-right-radius:0;flex-direction:column}.block-loop-hero .entry-header-inner{flex:none;margin-top:auto}.block-loop-hero video{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;display:none}.block-loop-hero .slider-active video{display:block}.block-loop-hero .entry-meta{grid-gap:1rem}.block-loop-hero .entry-header .entry-title{font-size:clamp(1.75rem,2.5vw,3rem);font-weight:600;line-height:1;max-width:40rem;margin-bottom:1rem}.block-loop-hero .byline{width:auto}.block-loop-hero .btn-purchase{border-color:#fff;padding:.5rem 1rem}.block-loop-hero .post-thumbnail{min-height:var(--loop-hero-min-height)}.block-loop-hero .btn-play{font-size:inherit}.block-loop-hero.alignfull .entry-header .entry-title{font-size:clamp(1.75rem,5vw,5rem);max-width:30rem}.block-loop-hero .entry-header{z-index:2;background:linear-gradient(180deg,transparent 0,transparent 25%,rgba(0,0,0,.7) 75%,var(--color-grey-800))}.block-loop-hero .post-thumbnail:before{content:'';display:block;position:absolute;z-index:1;top:0;left:0;right:0;bottom:0;background:linear-gradient(-80deg,transparent 50%,rgba(0,0,0,1) 100%)}.block-loop-hero .block-loop-dot{position:absolute;z-index:3;right:2rem;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;color:#fff}.block-loop-hero .byline,.block-loop-hero .byline+:before{display:none}.block-loop-hide-byline .byline{display:none}.block-loop-hide-footer .entry-footer{display:none}.block-loop-hide-avatar .entry-avatar{display:none}.block-loop-hide-meta .entry-footer>:not(.btn-more){display:none}.block-loop-short-item{--loop-ratio:calc(9/16);--loop-radius:1rem;--loop-line:3;--height:calc( 100vh - var(--navbar-height) - var(--mobile-menu-height) - var(--loop-short-bottom-padding, 2rem) );height:var(--height);width:calc(var(--height) * .5625)}.block-loop-short-item .entry-header{position:absolute;z-index:99;bottom:0;width:100%;color:#fff;background:linear-gradient(180deg,transparent,rgba(0,0,0,.4));padding:3rem 1rem 1rem;border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.block-loop-short-item .entry-meta{grid-gap:.5rem;margin-top:1rem}.block-loop-short-item .btn-follow{padding:1rem;border:none}.block-loop-short-item .btn-follow:not(.active){color:#000;background-color:#fff}.block-loop-short-item .byline{color:#fff;width:auto;flex:1}.block-loop-short-item.active .entry-action{opacity:0}.block-loop-short-item.active:hover .entry-action{opacity:1}.block-loop-short-item .post-thumbnail{border-radius:inherit!important;z-index:2}.block-loop-short-item.active .post-thumbnail .post-thumbnail-inner,.block-loop-short-item.is-current .post-thumbnail .post-thumbnail-inner{display:none}.block-loop-short-item .post-thumbnail .entry-action{background:linear-gradient(0deg,transparent,transparent 90%,rgba(0,0,0,.2));align-items:flex-start;justify-content:space-between;width:100%;height:auto;transform:none;left:0;top:0;padding:0}.block-loop-short-item .btn-play{position:relative!important;box-shadow:none!important;background-color:transparent!important;border:none;color:#fff}.block-loop-short-item .btn-play:after{display:none}.block-loop-short-item .entry-actions{position:absolute;left:100%;bottom:0;padding:0 1rem;grid-gap:.75rem;display:flex;flex-direction:column}.block-loop-short-item .entry-action-link{pointer-events:none}.block-loop-short-item .entry-actions .btn-comment,.block-loop-short-item .entry-actions button{display:inline-flex!important;flex-direction:column;padding:0;margin:0!important;position:relative!important}.block-loop-short-item .entry-actions .count{padding:.25rem 0 0 0;font-size:12px;font-weight:600}.block-loop-short-item .entry-actions .btn-svg-icon{padding:1rem;background-color:rgba(150,150,150,.15);border-radius:2rem}.block-loop-short-item .entry-actions .btn-svg-icon svg{width:20px;height:20px;fill:currentColor}.block-loop-snaps .scroller{margin-top:-1.25rem;margin-bottom:.25rem;border:none;background:0 0}@media (max-width:419px){.block-loop-slider{--loop-columns:1}.block-loop-snaps{--x-gap:0;--loop-radius:0;--loop-grid-gap:0;z-index:2}.block-loop-short-item{--loop-ratio:auto;--loop-radius:0;--text-secondary-color:#fff;width:100vw;height:inherit;flex-shrink:0}.plyr-short{--loop-radius:0}.block-loop-short-item .post-thumbnail{height:100%}.block-loop-short-item .entry-actions{left:auto;right:0;top:4rem;bottom:auto;z-index:999;color:#fff}}.block-loop-hover .entry-header{padding:.5rem .5rem 1rem .5rem!important}.block-loop-hover .entry-header-inner{display:flex;align-items:center;flex-direction:column;text-align:center}.block-loop-hover .block-loop-item.active,.block-loop-hover .block-loop-item:focus,.block-loop-hover .block-loop-item:hover{--text-secondary-color:#fff;background-color:#222;color:#fff}.block-loop-hover .block-loop-item.active .post-thumbnail:after,.block-loop-hover .block-loop-item:focus .post-thumbnail:after,.block-loop-hover .block-loop-item:hover .post-thumbnail:after{position:relative;z-index:1;background-color:#222;background:linear-gradient(180deg,rgba(22,22,22,.2),#222);border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}.block-loop-hover .entry-action{background-color:transparent}.block-loop-reverse .block-loop-item{flex-direction:column-reverse}.block-loop-reverse .block-loop-item .entry-header{padding-top:0}.block-loop-divider .block-loop-title{padding-top:1.5rem;border-top:.5px solid var(--color-border,rgba(150,160,170,.1))}.wp-block-loop.alignfull{margin-left:2rem;margin-right:2rem}.entry-title-lg .block-loop-item .entry-header-inner{font-size:clamp(1rem,3vw,1.25rem)}.wp-admin .display{font-weight:900;line-height:1;margin-top:0;margin-bottom:1rem}.wp-admin .circle{border-radius:50%}.wp-admin .rounded{border-radius:6px}.wp-admin .h-auto{min-height:auto}.white{color:#222;background-color:#fff}.text-white{color:#fff}.m-auto{margin-left:auto;margin-right:auto}.h-auto{min-height:auto}.border{border:1px solid var(--color-border,#eee)}.rounded,.rounded.wp-block-cover>span,.rounded:before{border-radius:var(--border-radius,8px)}.circle{border-radius:100%}.wp-block-cover{--y-gap:0}.wp-block-cover mark{padding:3px 4px;line-height:1;display:inline-flex;align-items:center;border-radius:3px}.is-position-top-bottom .wp-block-cover__inner-container{display:flex;flex-direction:column;justify-content:space-between;align-self:stretch;width:100%!important;position:static}.is-position-top-bottom .wp-block-video,.is-position-top-bottom .wp-block-video div,.is-position-top-bottom .wp-block-video video{position:absolute;top:0;bottom:0;left:0;right:0;margin:0;z-index:-1}.is-position-top-bottom .wp-block-video video{object-fit:cover;width:100%;height:100%}.is-align-self-start{align-self:flex-start}.is-align-self-end{align-self:flex-end;margin-bottom:0}.no-border{border:none}.no-padding{padding:0!important}.no-margin{margin:0!important}.no-gap{gap:0!important}.has-padding{padding:clamp(1rem,3vw,3rem)}.has-small-padding{padding:clamp(.5rem,2vw,1.5rem)}.has-large-padding{padding:clamp(2rem,4vw,5rem)}.has-container{--content-width:640px}#ffl-settings .postbox-header{border-bottom:none}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:var(--dropdown-menu-width,10rem);padding:.25rem;margin:.125rem 0 0;font-size:.875rem;color:#212529;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.05);box-shadow:0 3px 5px rgba(0,0,0,.05);border-radius:var(--dropdown-menu-radius,.5rem);text-shadow:none;text-align:initial}.dropdown-toggle{cursor:pointer;display:inline-block;text-align:center;min-width:1.5rem;text-decoration:none;outline:0}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-inline-start:.3em;-webkit-margin-start:.3em;vertical-align:middle;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-left:.3em solid transparent;opacity:.5}.dropdown-menu.show{display:block}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-menu[x-out-of-boundaries]{display:none}.dropdown-menu ul{display:block!important;list-style:none;padding:0;margin-bottom:0}.dropdown-item,.dropdown-menu li a{display:block;width:100%;padding:.5rem 1rem;box-sizing:border-box;clear:both;font-weight:400;border-radius:6px;cursor:pointer;text-decoration:none;outline:0}.dropdown-item:hover,.dropdown-menu .cat-item a:hover,.dropdown-menu .play-notification-item:hover{color:inherit;background-color:var(--dropdown-menu-item-background,rgba(150,150,150,.1))}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid var(--dropdown-menu-item-background)}.dropdown-menu .play-notification-item{border:none}.dropdown-term-filter,.loop-filter-item .dropdown-menu{max-height:15rem;overflow-y:scroll;-webkit-overflow-scrolling:touch;overflow:-moz-scrollbars-none;-ms-overflow-style:none;outline:0}.dropdown-term-filter::-webkit-scrollbar{display:none}.dropdown-term-filter ul ul a{padding-inline-start:2rem;-webkit-padding-start:2rem}.loop-filter{display:flex;flex-wrap:wrap;margin-bottom:1.5rem;grid-gap:1rem}.loop-filter-list{flex-direction:column}.loop-filter-item{position:relative}.loop-filter-list .loop-filter-item{display:flex;grid-gap:1rem}.loop-filter .list-menu{display:flex;flex-wrap:wrap;grid-gap:.5rem;grid-row-gap:.5rem}.loop-filter .list-item{white-space:nowrap;display:inline-flex;align-items:center;padding:1px 5px;border-radius:4px;text-decoration:none}.loop-filter .list-menu .selected{background-color:rgba(150,150,150,.2)}.loop-filter .loop-filter-item-heading{font-weight:600}.loop-filter .dropdown-menu .selected{position:relative}.loop-filter .loop-filter-item-search input{margin:0}.loop-toggle-hide{display:none!important}.loop-filter-more-less{cursor:pointer;font-weight:500}.loop-filter .dropdown-menu .selected:after{content:'';display:inline-block;width:.65em;height:.35em;border-left:.1em solid currentColor;border-bottom:.1em solid currentColor;transform:translate(-50%,-50%) rotate(-45deg);position:absolute;right:.5rem;top:45%;opacity:.6}.loop-filter-count{display:inline-block;background-color:rgba(150,160,170,.2);padding:0 .45em;margin-inline-start:.125rem;-webkit-margin-start:.125rem;font-size:11px;border-radius:1rem}.loop-filter-count:empty{display:none}.dropdown-menu .multi-range{margin:1rem}input[type=range].multirange{-webkit-appearance:none;height:2px;padding:0;margin:1rem 0 0;width:calc(100% - 0px);display:inline-block;vertical-align:top;background-color:rgba(150,150,150,.5);color:currentColor;outline:0;border:0;border-radius:6px}input[type=range].multirange.original{position:absolute}input[type=range].multirange::-webkit-slider-thumb{-webkit-appearance:none;position:relative;z-index:2;border:none;width:12px;height:12px;border-radius:100%;background-color:currentColor}input[type=range].multirange::-moz-range-thumb{border:none;width:12px;height:12px;border-radius:100%;background-color:currentColor}input[type=range].multirange.original::-moz-range-thumb{z-index:2}input[type=range].multirange.ghost{position:relative;background:var(--track-background);--track-background:linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 100%/100% 100%;--range-color:currentColor}input[type=range].multirange.ghost::-webkit-slider-thumb{position:relative;z-index:2}input[type=range].multirange.ghost::-moz-range-thumb{z-index:2}.multi-range{position:relative}.range-max,.range-min{position:absolute;top:-6px;font-size:10px;width:10px;display:flex;justify-content:center;text-align:center;left:calc(var(--left) * 1%);margin-left:calc(0px - var(--left)/ 100 * 10px)}.spinner{display:inline-block;width:1rem;height:1rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner .75s linear infinite;animation:spinner .75s linear infinite}.loop-filter-keys{width:100%;display:flex;grid-gap:.5rem;flex-wrap:wrap}.loop-filter-keys a{font-weight:600;font-size:.9em;display:inline-flex;text-decoration:none}.loop-filter-keys a:after{content:'\00d7';font-family:arial;font-weight:400;display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;line-height:0;border-radius:100%;background-color:#666;color:#fff;opacity:0;margin:-4px -7px 0 -7px;transition:opacity .2s}.loop-filter-keys a:hover:after{opacity:1}.loop-filter-total{width:100%}a.loop-filter-clear{font-weight:400;align-items:center;opacity:.7}a.loop-filter-clear:hover{opacity:1}a.loop-filter-clear:after{order:-1;margin:2px;opacity:1}@keyframes spinner{0%{transform:scale(0)}50%{opacity:1}}@media (max-width:576px){:root{--loop-grid-gap:1rem}.block-loop-row .block-loop-items{--loop-columns:1}.block-loop-row:not(.has-loop-posts):not(.block-loop-xs):not(.block-loop-inline) .block-loop-item:not(.block-loop-inline) .entry-footer{flex:auto;width:100%}.block-loop-row:not(.has-loop-posts):not(.block-loop-xs):not(.block-loop-inline) .block-loop-item:not(.block-loop-inline) .post-thumbnail{width:4.5rem}.block-loop-row .entry-footer>:first-child:not(.btn-add){padding-inline-start:0}.block-loop-row .add_to_cart_inline,.block-loop-row .btn-purchase,.block-loop-row .entry-description,.block-loop-row .entry-info{display:none}.block-loop-inline .waveform,.block-loop-nav,.has-loop-posts .btn-download,.has-loop-posts .btn-like,.has-loop-posts .play-count{display:none}.modal-open .wp-block-loop-product .block-loop-slider{overflow:visible}.entry-content>.wp-block-loop-slider:not(.block-loop-center) .block-loop-items{padding:0 var(--x-gap,var(--wp--style--root--padding-left,1rem));margin:0 calc(var(--x-gap,var(--wp--style--root--padding-left,1rem)) * -1);scroll-snap-type:none;--loop-max-width:85%}}@media (min-width:577px){.block-loop-with-filter{display:flex;align-items:flex-start;height:100%}.block-loop-with-filter .block-loop-items{flex:1}.block-loop-with-filter .loop-filter{flex-direction:column;min-width:15rem;margin:0;height:100%}.is-series .has-loop-posts .post-thumbnail{border-radius:5px;width:5rem;height:5rem}}1 :root{--loop-cols:5;--loop-xs-cols:2;--loop-rows:1;--loop-columns:max( var(--loop-cols) - 4, var(--loop-xs-cols) );--loop-grid-gap:1.5rem;--loop-row-gap:1rem;--loop-max-width:100%;--loop-min-width:0;--loop-line:2;--loop-line-height:1.3;--loop-ratio:1;--loop-radius:6px;--loop-center-width:70%;--loop-font-size:0.9375rem}.is-loop-icon{display:inline-flex;align-items:center;grid-gap:.25em}.is-loop-icon:after,.is-loop-icon:before{content:'';display:block;width:1em;height:1em;border:.125em solid currentColor;transform:rotate(45deg);border-radius:100%;order:-1}.is-loop-icon:before{border-top-right-radius:0}.is-loop-icon:after{border-bottom-left-radius:0}.wp-block-loop{position:relative}.block-loop-items{margin-bottom:1.5rem;list-style:none;display:grid;grid-gap:var(--loop-grid-gap);--loop--cols:calc((var(--loop-max-width) - (var(--loop-columns) - 1) * var(--loop-grid-gap)) / var(--loop-columns));grid-template-columns:repeat(auto-fill,minmax(var(--loop--cols),1fr))}.block-loop-slider,[data-plugin=slider]{display:grid;overflow-x:auto;border-radius:var(--loop-radius);scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;scroll-behavior:smooth;overscroll-behavior-x:none;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;grid-auto-flow:column;--loop--cols:calc((var(--loop-max-width) - (var(--loop-columns) - 1) * var(--loop-grid-gap)) / var(--loop-columns));grid-auto-columns:var(--loop--cols);grid-template-rows:repeat(var(--loop-rows),max-content);grid-template-columns:inherit!important;box-sizing:border-box}.block-loop-slider::-webkit-scrollbar,.block-loop-snaps .block-loop-items::-webkit-scrollbar{display:none}.block-loop-snaps .block-loop-items{position:fixed;z-index:2;left:0;right:0;top:var(--navbar-height);bottom:var(--mobile-menu-height);display:flex;flex-direction:column;align-items:center;overflow-y:auto;scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;scroll-behavior:smooth;overscroll-behavior-y:none;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;border-radius:var(--loop-radius);margin-bottom:0}.block-slider-scrolling{-ms-scroll-snap-type:none;scroll-snap-type:none;scroll-behavior:inherit}.block-slider-scrolling video{display:none!important}.block-loop-slider .entry-content>*,[data-plugin=slider] .entry-content>*{width:100%!important;max-width:100%!important}.block-loop-slider>*,.block-loop-snaps>*{scroll-snap-align:start}.column-sm-gap{--column-gap:var(--loop-grid-gap, 1rem)}@media (max-width:1000px){.is-stacked-tablet{flex-wrap:wrap!important}.is-stacked-tablet>.wp-block-column{flex-basis:100%!important}}@media (min-width:420px){.wp-block-loop{--loop-columns:max( min(var(--loop-cols), 5) - 3, 2 )}}@media (min-width:640px){.wp-block-loop{--loop-columns:max( var(--loop-cols) - 2, 2 )}}@media (min-width:960px){.wp-block-loop{--loop-columns:max( var(--loop-cols) - 1, 3 )}}@media (min-width:1260px){.wp-block-loop{--loop-columns:var(--loop-cols)}}.grid-1{--loop-columns:1!important}.grid-2{--loop-columns:2!important}.grid-3{--loop-columns:3!important}@media (max-width:419px){.grid-xs-1{--loop-columns:1!important}.grid-xs-2{--loop-columns:2!important}.grid-xs-3{--loop-columns:3!important}}@media (max-width:781px){.grid-sm-1{--loop-columns:1!important}.grid-sm-2{--loop-columns:2!important}.grid-sm-3{--loop-columns:3!important}}@media (max-width:991px){.grid-md-1{--loop-columns:1!important}.grid-md-2{--loop-columns:2!important}.grid-md-3{--loop-columns:3!important}}@media (min-width:1400px){.grid-xl-1{--loop-columns:1!important}.grid-xl-2{--loop-columns:2!important}.grid-xl-3{--loop-columns:3!important}}.block-loop-title{display:flex;flex-wrap:wrap;align-items:center}.block-loop-heading{width:1%;flex:1}.block-loop-more{font-size:14px;font-weight:400}.block-loop-subtitle{color:var(--text-secondary-color,#888);line-height:1.1;text-transform:none;display:block;width:100%}.block-loop-nav{opacity:0;transition:opacity .2s;position:absolute;display:flex;align-items:center;z-index:5;height:0;width:calc(100% + 2.5rem);left:-1.25rem;top:var(--top,50%)}.alignfull>.block-loop-nav{width:calc(100% - 2.5rem);left:1.25rem}.block-loop-nav span{flex:1}.wp-block-loop:hover .block-loop-nav{opacity:1}.block-loop-nav button{width:2.5rem;height:2.5rem;padding:0;border-radius:100%;display:inline-flex;justify-content:center;align-items:center;border:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.block-loop-nav button svg{pointer-events:none;transform:rotate(var(--transform-rotate,0))}.block-loop-dot-overlay .block-loop-dot{position:absolute;z-index:5;left:50%;bottom:1rem;transform:translate(-50%,0);color:#fff}.block-loop-dot-left .block-loop-dot{margin:-4rem auto 0 auto;text-align:left;max-width:var(--content-width);width:calc(100% - var(--x-gap) * 2)}.block-loop-dot{text-align:center}.block-loop-dot button{width:1.5rem;height:1.5rem;padding:0;border-radius:2rem;border:none;background-color:transparent;color:inherit}.block-loop-dot button:after{content:"";display:inline-block;width:6px;height:6px;border-radius:6px;margin:0 auto;background-color:currentColor;opacity:.5}.block-loop-dot button.active:after{opacity:1}.block-loop-center{--loop-columns:1;--loop-max-width:var(--loop-center-width)!important}.block-loop-center .block-loop-item{scroll-snap-align:center}.block-loop-center .block-loop-nav>div{height:var(--height);width:calc(50% - var(--loop-center-width)/ 2);display:flex;align-items:center}.block-loop-center .block-loop-nav .slider-right-btn{justify-content:flex-end}.scroller{width:15rem;font-size:12px!important;display:inline-flex;justify-content:center;margin:0 auto;text-decoration:none}.scroller.is-loading{cursor:wait;pointer-events:none}.block-loop-empty,.wp-block-loop .pagination,.wp-block-loop .scroller{grid-column:1/-1;order:10000}.pagination .nav-links{display:flex;align-items:center;justify-content:center}.pagination .page-numbers{padding:.25em;text-decoration:none}.wp-block-loop .navigation .next,.wp-block-loop .navigation .prev{line-height:0}.wp-block-loop .navigation .nav-next-text,.wp-block-loop .navigation .nav-prev-text,.wp-block-loop .navigation .next:before,.wp-block-loop .navigation .prev:before{display:none}.block-loop-item{position:relative;padding:0;max-width:100%;border-radius:var(--loop-radius);display:flex;flex-direction:column;flex-wrap:wrap;scroll-snap-align:start;order:10;font-size:var(--loop-font-size)}.block-loop-item:nth-child(1){order:0}.block-loop-item:nth-child(2){order:1}.block-loop-item:nth-child(3){order:2}.block-loop-item:nth-child(4){order:3}.block-loop-item:nth-child(5){order:4}.block-loop-item:nth-child(6){order:5}.block-loop-item:nth-child(7){order:6}.block-loop-item:nth-child(8){order:7}.block-loop-item:nth-child(9){order:8}.block-loop-item .entry-content,.block-loop-item .entry-footer,.block-loop-item .entry-header,.block-loop-item .post-thumbnail{width:100%;box-sizing:border-box;padding-left:0;padding-right:0}.block-loop-item .entry-header{margin-bottom:1rem}.block-loop-item .entry-footer{margin-bottom:1rem}.block-loop-item .entry-header{padding:var(--loop-header-gap,.5rem) 0;margin:0;flex:1;display:flex;align-items:flex-start;grid-gap:var(--loop-header-gap,.5rem)}.block-loop-item .entry-title{margin:0;font-weight:500;letter-spacing:0}.block-loop-item .entry-subtitle{color:var(--text-secondary-color,#888)}.block-loop-item a{text-decoration:none}.block-loop-item .entry-meta{display:flex;flex-wrap:wrap;grid-gap:0;margin:0;color:var(--text-secondary-color,#888)}.block-loop-item .byline .author,.block-loop-item .entry-artist,.block-loop-item .entry-excerpt,.block-loop-item .entry-title,.wp-block-loop-user .entry-title a{display:block;display:-webkit-box;-webkit-box-orient:vertical;text-overflow:ellipsis;white-space:normal;-webkit-line-clamp:var(--loop-line);line-height:var(--loop-line-height);font-size:inherit;overflow:hidden;padding-bottom:.1em;word-break:break-word;word-wrap:break-word}.block-loop-item .entry-excerpt{--loop-line:2}.wp-block-loop-user .entry-title{display:flex;overflow:visible}.block-loop-item .byline .author,.wp-block-loop-user .entry-title a{--loop-line:1}.block-loop-item .entry-meta>span{margin:0}.block-loop-item .wp-video,.block-loop-item .wp-video video{width:100%!important;height:auto;border-radius:inherit}.block-loop-item .attachment,.block-loop-item.attachment{float:none;width:100%}.block-loop-item.attachment audio~p{display:none}.block-loop-item .post-thumbnail br,.block-loop-item .post-thumbnail p{display:none}.block-loop-item .post-thumbnail{width:100%;position:relative;margin:0;padding:0;border-radius:inherit;background-color:rgba(110,120,130,.2)}.block-loop-item .btn-follow{padding:.25em .75em;font-size:12px;vertical-align:text-bottom;margin:.25rem 0}.block-loop-item .post-thumbnail a{border-radius:inherit}.block-loop-item .post-thumbnail .avatar,.block-loop-item .post-thumbnail img,.block-loop-item .post-thumbnail video{border-radius:inherit;position:absolute;width:100%;height:100%;object-fit:cover;display:inline-flex;justify-content:center;align-items:center}.block-loop-item .post-thumbnail:after{padding-top:calc(100% / var(--loop-ratio));min-height:auto;content:"";width:100%;display:block}.block-loop-item .entry-action{opacity:0;pointer-events:none;color:#fff;background-color:rgba(0,0,0,.2);position:absolute;z-index:3;left:50%;top:50%;width:100%;height:100%;padding:0 5%;border-radius:inherit;transform:translate(-50%,-50%);transition:opacity .3s;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;justify-content:space-around;box-sizing:border-box}.block-loop-item .entry-action .count{display:none}.block-loop-item .entry-action.show{z-index:10}.block-loop-item .entry-action button,.block-loop-item .entry-action button:hover{flex-shrink:0}.entry-action-link{position:absolute;width:100%;height:100%}.block-loop-item-link{padding:.75rem 1rem;background-color:var(--btn-background,rgba(150,155,160,.2));border-radius:var(--btn-radius,.5rem)}.block-loop-item-link.active,.block-loop-item-link:hover{background-color:var(--btn-background-hover,rgba(150,155,160,.3))}.block-loop-item.active .entry-action,.block-loop-item:active .entry-action,.block-loop-item:hover .entry-action,.block-loop-item:hover .entry-header-inner~.btn-more{opacity:1;pointer-events:initial}.block-loop-item .count,.comment-toolbar .count,.entry-meta .count{color:var(--text-secondary-color,#888);padding-inline-start:.25rem;-webkit-padding-start:.25rem;font-size:.85rem;font-weight:400}.block-loop-row .play-count{padding:0 .5rem}.block-loop-item .entry-avatar{width:36px;flex-shrink:0}.block-loop-item .entry-footer{display:none;margin:0}.block-loop-item .entry-description{font-size:.875rem}.block-loop-item .entry-description p{margin-bottom:0}.block-loop-item .waveform{width:100%}.block-loop-index.block-loop-row .waveform:before{content:"";display:inline-block;min-width:1rem}.wp-block-loop .btn-play{font-size:1.125rem}.block-loop-row .btn-play{font-size:.875rem}.wp-block-loop-user .post-thumbnail{width:80%;margin:10% 10% 0 10%;border-radius:50%}.wp-block-loop-user .entry-header{text-align:center;flex-direction:column;align-items:center;grid-gap:0}.wp-block-loop-user .post-thumbnail{--loop-ratio:1;border-radius:50%!important}.wp-block-loop-user.block-loop-row{--loop-grid-gap:0.75rem}.wp-block-loop-user.block-loop-row .block-loop-item{align-items:center}.wp-block-loop-user.block-loop-row .post-thumbnail{margin:0;min-width:0;width:3rem}.wp-block-loop-user.block-loop-row .entry-header{align-items:center;text-align:inherit;display:flex;flex-direction:row;gap:.5rem}.wp-block-loop-user .entry-title{font-size:.8125rem;font-weight:600;align-items:center;justify-content:center;flex:1}.wp-block-loop-user.block-loop-row .entry-title{justify-content:flex-start}.wp-block-loop-user .user-followers{font-weight:400;font-size:.85em;color:var(--text-secondary-color);width:100%}.block-loop-row{--loop-columns:1}.hide-more-actions .entry-footer>:not(.btn-more){display:none}.block-loop-row .block-loop-item{display:flex;grid-gap:var(--loop-row-gap);flex-direction:row;align-items:flex-start}.block-loop-row .entry-header{flex:1;display:flex;flex-wrap:wrap;padding:0;align-items:center;align-self:stretch;grid-gap:0}.block-loop-row .entry-avatar{display:none}.block-loop-row .post-thumbnail{width:6rem;min-width:var(--loop-min-width)}.block-loop-mixed .block-loop-item{display:flex;grid-gap:var(--loop-row-gap);flex-direction:row;--loop-header-gap:0;align-items:center}.block-loop-mixed .block-loop-item:first-child{grid-column:span calc(var(--loop-columns)/2);grid-row:span var(--loop-rows,4);align-items:stretch}.block-loop-mixed .block-loop-item:not(:first-child){grid-column:span calc(var(--loop-columns)/2)}.block-loop-mixed .block-loop-item:not(:first-child) .post-thumbnail{width:33%}@media (max-width:576px){.block-loop-mixed .block-loop-items{--loop-columns:1}}.block-loop-xs{--loop-line:1}.block-loop-xs .btn-play{font-size:.75rem}.block-loop-xs .post-thumbnail{width:3rem;border-radius:5px;min-width:auto}.block-loop-sm .post-thumbnail{width:4rem;border-radius:7px;min-width:auto}.block-loop-lg .post-thumbnail{width:10rem;min-width:auto}.block-loop-autotype .block-loop-items{--loop-columns:1}.has-loop-posts .block-loop-items{grid-gap:0;--loop-columns:1}.has-loop-posts .block-loop-item{padding:.5rem .5rem}.has-loop-posts .entry-header{flex-wrap:nowrap;padding:0}.has-loop-posts .post-thumbnail{border-radius:2px;width:3rem;flex-shrink:0}.has-loop-posts.block-loop-index .icon-play{display:none;padding:.5rem;position:absolute;top:50%;transform:translateY(-50%);line-height:0}.has-loop-posts.block-loop-index .block-loop-item.active:before,.has-loop-posts.block-loop-index .block-loop-item:hover:before{color:transparent}.has-loop-posts.block-loop-index .block-loop-item.active .icon-play,.has-loop-posts.block-loop-index .block-loop-item:hover .icon-play{display:block}.has-loop-posts .block-loop-item:hover{background-color:var(--tracks-item-odd-color,rgba(150,155,160,.1))}.has-loop-posts .block-loop-item.active{background-color:var(--tracks-item-hover-color,rgba(150,155,160,.2))}.has-loop-posts .icon-plus{display:none}.is-album .has-loop-posts .entry-meta a,.is-album .has-loop-posts .entry-title a{pointer-events:none}.has-loop-posts .entry-meta{justify-content:flex-start!important}.is-album .has-loop-posts .post-thumbnail{display:none}.is-series .has-loop-posts .block-loop-items{margin:0 -1rem}.is-series .has-loop-posts .block-loop-item{padding:.75rem 1rem;border:none!important}.is-series .has-loop-posts .block-loop-item .entry-header{padding-bottom:1rem;border-bottom:1px solid var(--color-border)}.is-series .has-loop-posts .block-loop-item.active .entry-header,.is-series .has-loop-posts .block-loop-item:hover .entry-header{border-color:transparent}.is-series .has-loop-posts .btn-play{border:1px solid var(--color-border);background-clip:padding-box}.is-series .has-loop-posts .block-loop-item>.btn-play{align-self:flex-start}.block-loop-row .entry-description,.block-loop-row .entry-info,.is-series .block-loop-item .entry-description,.is-series .block-loop-item .entry-info{margin-bottom:0}.block-loop-row .entry-info .play-duration,.is-series .block-loop-item .entry-info .play-duration{padding:0}.block-loop-inline .entry-header{grid-gap:1.5rem}.block-loop-inline>button.btn-play{transform:scale(1)}.block-loop-inline .btn-play-waveform{display:none}.block-loop-inline .waveform{flex:1}.entry-header-inner{flex:1;max-width:100%}.entry-header-inner~.btn-more{margin:-.375rem -.5rem;opacity:0}.entry-header-inner .byline,.entry-header-inner .entry-artist{width:100%;justify-content:inherit}.entry-header-inner .byline{display:flex;align-items:center}.entry-meta-date{font-size:.75rem}.entry-header-inner .play-count+.entry-meta-date:before{display:inline-block;text-align:center;content:'\00B7';color:var(--text-secondary-color);width:1rem;font-weight:700}.block-loop-item .add_to_cart_inline,.block-loop-item .entry-header-inner .btn-purchase{margin:4px 0}.block-loop-item .add_to_cart_inline .btn-purchase,.block-loop-item form{margin:0!important}.block-loop-xs .add_to_cart_inline,.block-loop-xs .btn-purchase,.has-loop-posts .add_to_cart_inline,.has-loop-posts .btn-purchase{display:none}.block-loop-item .added_to_cart,.block-loop-item .btn-purchase,.plyr-playlist .btn-purchase{font-size:12px}.block-loop-item .entry-action .btn-more{position:absolute;padding:.75em;bottom:0;right:0}.block-loop-row .entry-action{justify-content:center}.block-loop-row .post-thumbnail .entry-action .btn-like,.block-loop-row .post-thumbnail .entry-action .btn-more{display:none}.block-loop-row .entry-footer{display:flex;align-items:center;padding-left:0;padding-right:0;width:auto}.block-loop-row .count,.block-loop-row .play-duration{font-size:.875em}.block-loop-row .play-duration{padding:0 .5rem}.play-count{white-space:nowrap;display:inline-flex;align-items:center;white-space:nowrap}.play-count:before{display:inline-block;width:0;height:0;content:"";border-left:.5em solid;border-top:.3em solid transparent;border-bottom:.3em solid transparent;opacity:.5}.btn-play+.play-count:before{display:none}.entry-badge .play-duration{background-color:#000;color:#fff;font-size:11px;font-weight:500;border-radius:4px;padding:1px 4px;position:absolute;right:.5rem;bottom:.5rem}.block-loop-index{counter-reset:li}.block-loop-index:not(.block-loop-row) .block-loop-item .entry-header:before{content:counter(li);counter-increment:li;font-weight:400;-ms-flex-negative:0;flex-shrink:0;opacity:.75;min-width:1rem}.block-loop-index.block-loop-row .block-loop-item:before{content:counter(li);counter-increment:li;min-width:1.5rem;font-weight:400;-ms-flex-negative:0;flex-shrink:0;opacity:.5;text-align:center;font-size:.9em;white-space:nowrap;align-self:center}.block-loop-overlay .entry-header{position:absolute;bottom:0;left:0;width:100%!important;padding:.75rem 1rem!important;box-sizing:border-box;color:#fff;background:linear-gradient(180deg,transparent,rgba(0,0,0,.85));border-radius:inherit;border-top-right-radius:0;border-top-left-radius:0;opacity:0;pointer-events:none}.block-loop-overlay .entry-header .entry-title{color:inherit;font-weight:700}.block-loop-overlay .entry-header .entry-meta,.block-loop-overlay .entry-header .entry-subtitle{color:rgba(255,255,255,.75)}.block-loop-overlay .entry-header a:hover{color:inherit}.block-loop-overlay .block-loop-item:hover .entry-header,.block-loop-overlay.block-loop-show-header .entry-header{opacity:1;pointer-events:initial;z-index:2}.block-loop-overlay-center .entry-header{top:0;opacity:1;font-weight:700;font-size:1rem;text-align:center;display:flex!important;align-items:center;justify-content:center}.block-loop-overlay-center .entry-meta{justify-content:center}.block-loop-ad .entry-meta{font-size:.75rem}.block-loop-ad.block-loop-item .post-thumbnail{background-color:var(--color-primary)}.block-loop-overlay .block-loop-ad .entry-header{background:0 0;bottom:auto}.block-loop-hero{--text-secondary-color:rgba(255,255,255,0.95);--button-radius:3rem;--loop-hero-min-height:15rem}.block-loop-hero.wp-block-loop.alignfull{margin-left:0;margin-right:0;--loop-radius:0;--loop-max-width:100%;--loop-hero-min-height:clamp(20rem, 50vh, 30rem)}.entry-content>.block-loop-hero.wp-block-loop.alignfull .block-loop-items{padding:0}.block-loop-hero .block-loop-nav{top:auto;right:2rem;bottom:5rem;width:auto;justify-content:flex-end;gap:.5rem}.block-loop-hero .block-loop-nav span,.block-loop-hero .count{display:none}.block-loop-hero .entry-header{position:absolute;top:0;left:0;bottom:0;width:100%;padding:var(--x-gap,1.5rem);color:#fff;background:linear-gradient(-135deg,transparent 0,transparent 25%,rgba(0,0,0,.6) 70%,rgba(0,0,0,1) 100%);border-radius:inherit;border-top-right-radius:0;border-bottom-right-radius:0;flex-direction:column}.block-loop-hero .entry-header-inner{flex:none;margin-top:auto}.block-loop-hero video{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;display:none}.block-loop-hero .slider-active video{display:block}.block-loop-hero .entry-meta{grid-gap:1rem}.block-loop-hero .entry-header .entry-title{font-size:clamp(1.75rem,2.5vw,3rem);font-weight:600;line-height:1;max-width:40rem;margin-bottom:1rem}.block-loop-hero .byline{width:auto}.block-loop-hero .btn-purchase{border-color:#fff;padding:.5rem 1rem}.block-loop-hero .post-thumbnail{min-height:var(--loop-hero-min-height)}.block-loop-hero .btn-play{font-size:inherit}.block-loop-hero.alignfull .entry-header .entry-title{font-size:clamp(1.75rem,5vw,5rem);max-width:30rem}.block-loop-hero .entry-header{z-index:2;background:linear-gradient(180deg,transparent 0,transparent 25%,rgba(0,0,0,.7) 75%,var(--color-grey-800))}.block-loop-hero .post-thumbnail:before{content:'';display:block;position:absolute;z-index:1;top:0;left:0;right:0;bottom:0;background:linear-gradient(-80deg,transparent 50%,rgba(0,0,0,1) 100%)}.block-loop-hero .block-loop-dot{position:absolute;z-index:3;right:2rem;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;color:#fff}.block-loop-hero .byline,.block-loop-hero .byline+:before{display:none}.block-loop-hide-byline .byline{display:none}.block-loop-hide-footer .entry-footer{display:none}.block-loop-hide-avatar .entry-avatar{display:none}.block-loop-hide-meta .entry-footer>:not(.btn-more){display:none}.block-loop-short-item{--loop-ratio:calc(9/16);--loop-radius:1rem;--loop-line:3;--height:calc( 100vh - var(--navbar-height) - var(--mobile-menu-height) - var(--loop-short-bottom-padding, 2rem) );height:var(--height);width:calc(var(--height) * .5625)}.block-loop-short-item .entry-header{position:absolute;z-index:99;bottom:0;width:100%;color:#fff;background:linear-gradient(180deg,transparent,rgba(0,0,0,.4));padding:3rem 1rem 1rem;border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.block-loop-short-item .entry-meta{grid-gap:.5rem;margin-top:1rem}.block-loop-short-item .btn-follow{padding:1rem;border:none}.block-loop-short-item .btn-follow:not(.active){color:#000;background-color:#fff}.block-loop-short-item .byline{color:#fff;width:auto;flex:1}.block-loop-short-item.active .entry-action{opacity:0}.block-loop-short-item.active:hover .entry-action{opacity:1}.block-loop-short-item .post-thumbnail{border-radius:inherit!important;z-index:2}.block-loop-short-item.active .post-thumbnail .post-thumbnail-inner,.block-loop-short-item.is-current .post-thumbnail .post-thumbnail-inner{display:none}.block-loop-short-item .post-thumbnail .entry-action{background:linear-gradient(0deg,transparent,transparent 90%,rgba(0,0,0,.2));align-items:flex-start;justify-content:space-between;width:100%;height:auto;transform:none;left:0;top:0;padding:0}.block-loop-short-item .btn-play{position:relative!important;box-shadow:none!important;background-color:transparent!important;border:none;color:#fff}.block-loop-short-item .btn-play:after{display:none}.block-loop-short-item .entry-actions{position:absolute;left:100%;bottom:0;padding:0 1rem;grid-gap:.75rem;display:flex;flex-direction:column}.block-loop-short-item .entry-action-link{pointer-events:none}.block-loop-short-item .entry-actions .btn-comment,.block-loop-short-item .entry-actions button{display:inline-flex!important;flex-direction:column;padding:0;margin:0!important;position:relative!important}.block-loop-short-item .entry-actions .count{padding:.25rem 0 0 0;font-size:12px;font-weight:600}.block-loop-short-item .entry-actions .btn-svg-icon{padding:1rem;background-color:rgba(150,150,150,.15);border-radius:2rem}.block-loop-short-item .entry-actions .btn-svg-icon svg{width:20px;height:20px;fill:currentColor}.block-loop-snaps .scroller{margin-top:-1.25rem;margin-bottom:.25rem;border:none;background:0 0}@media (max-width:419px){.block-loop-slider{--loop-columns:1}.block-loop-snaps{--x-gap:0;--loop-radius:0;--loop-grid-gap:0;z-index:2}.block-loop-short-item{--loop-ratio:auto;--loop-radius:0;--text-secondary-color:#fff;width:100vw;height:inherit;flex-shrink:0}.plyr-short{--loop-radius:0}.block-loop-short-item .post-thumbnail{height:100%}.block-loop-short-item .entry-actions{left:auto;right:0;top:4rem;bottom:auto;z-index:999;color:#fff}}.block-loop-hover .entry-header{padding:.5rem .5rem 1rem .5rem!important}.block-loop-hover .entry-header-inner{display:flex;align-items:center;flex-direction:column;text-align:center}.block-loop-hover .block-loop-item.active,.block-loop-hover .block-loop-item:focus,.block-loop-hover .block-loop-item:hover{--text-secondary-color:#fff;background-color:#222;color:#fff}.block-loop-hover .block-loop-item.active .post-thumbnail:after,.block-loop-hover .block-loop-item:focus .post-thumbnail:after,.block-loop-hover .block-loop-item:hover .post-thumbnail:after{position:relative;z-index:1;background-color:#222;background:linear-gradient(180deg,rgba(22,22,22,.2),#222);border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}.block-loop-hover .entry-action{background-color:transparent}.block-loop-reverse .block-loop-item{flex-direction:column-reverse}.block-loop-reverse .block-loop-item .entry-header{padding-top:0}.block-loop-divider .block-loop-title{padding-top:1.5rem;border-top:.5px solid var(--color-border,rgba(150,160,170,.1))}.wp-block-loop.alignfull{margin-left:2rem;margin-right:2rem}.entry-title-lg .block-loop-item .entry-header-inner{font-size:clamp(1rem,3vw,1.25rem)}.wp-admin .display{font-weight:900;line-height:1;margin-top:0;margin-bottom:1rem}.wp-admin .circle{border-radius:50%}.wp-admin .rounded{border-radius:6px}.wp-admin .h-auto{min-height:auto}.white{color:#222;background-color:#fff}.text-white{color:#fff}.m-auto{margin-left:auto;margin-right:auto}.h-auto{min-height:auto}.border{border:1px solid var(--color-border,#eee)}.rounded,.rounded.wp-block-cover>span,.rounded:before{border-radius:var(--border-radius,8px)}.circle{border-radius:100%}.wp-block-cover{--y-gap:0}.wp-block-cover mark{padding:3px 4px;line-height:1;display:inline-flex;align-items:center;border-radius:3px}.is-position-top-bottom .wp-block-cover__inner-container{display:flex;flex-direction:column;justify-content:space-between;align-self:stretch;width:100%!important;position:static}.is-position-top-bottom .wp-block-video,.is-position-top-bottom .wp-block-video div,.is-position-top-bottom .wp-block-video video{position:absolute;top:0;bottom:0;left:0;right:0;margin:0;z-index:-1}.is-position-top-bottom .wp-block-video video{object-fit:cover;width:100%;height:100%}.is-align-self-start{align-self:flex-start}.is-align-self-end{align-self:flex-end;margin-bottom:0}.no-border{border:none}.no-padding{padding:0!important}.no-margin{margin:0!important}.no-gap{gap:0!important}.has-padding{padding:clamp(1rem,3vw,3rem)}.has-small-padding{padding:clamp(.5rem,2vw,1.5rem)}.has-large-padding{padding:clamp(2rem,4vw,5rem)}.has-container{--content-width:640px}#ffl-settings .postbox-header{border-bottom:none}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:var(--dropdown-menu-width,10rem);padding:.25rem;margin:.125rem 0 0;font-size:.875rem;color:#212529;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.05);box-shadow:0 3px 5px rgba(0,0,0,.05);border-radius:var(--dropdown-menu-radius,.5rem);text-shadow:none;text-align:initial}.dropdown-menu.show~.dropdown-backdrop{background-color:transparent;position:fixed;width:100vw;height:100vh;left:0;top:0;z-index:100000}.dropdown-toggle{cursor:pointer;display:inline-block;text-align:center;min-width:1.5rem;text-decoration:none;outline:0}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-inline-start:.3em;-webkit-margin-start:.3em;vertical-align:middle;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-left:.3em solid transparent;opacity:.5}.dropdown-menu.show{display:block}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-menu[x-out-of-boundaries]{display:none}.dropdown-menu ul{display:block!important;list-style:none;padding:0;margin-bottom:0}.dropdown-item,.dropdown-menu li a{display:block;width:100%;padding:.5rem 1rem;box-sizing:border-box;clear:both;font-weight:400;border-radius:6px;cursor:pointer;text-decoration:none;outline:0}.dropdown-item:hover,.dropdown-menu .cat-item a:hover,.dropdown-menu .play-notification-item:hover{color:inherit;background-color:var(--dropdown-menu-item-background,rgba(150,150,150,.1))}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid var(--dropdown-menu-item-background)}.dropdown-menu .play-notification-item{border:none}.dropdown-term-filter,.loop-filter-item .dropdown-menu{max-height:15rem;overflow-y:scroll;-webkit-overflow-scrolling:touch;overflow:-moz-scrollbars-none;-ms-overflow-style:none;outline:0}.dropdown-term-filter::-webkit-scrollbar{display:none}.dropdown-term-filter ul ul a{padding-inline-start:2rem;-webkit-padding-start:2rem}.loop-filter{display:flex;flex-wrap:wrap;margin-bottom:1.5rem;grid-gap:1rem}.loop-filter-list{flex-direction:column}.loop-filter-item{position:relative}.loop-filter-list .loop-filter-item{display:flex;grid-gap:1rem}.loop-filter .list-menu{display:flex;flex-wrap:wrap;grid-gap:.5rem;grid-row-gap:.5rem}.loop-filter .list-item{white-space:nowrap;display:inline-flex;align-items:center;padding:1px 5px;border-radius:4px;text-decoration:none}.loop-filter .list-menu .selected{background-color:rgba(150,150,150,.2)}.loop-filter .loop-filter-item-heading{font-weight:600}.loop-filter .dropdown-menu .selected{position:relative}.loop-filter .loop-filter-item-search input{margin:0}.loop-toggle-hide{display:none!important}.loop-filter-more-less{cursor:pointer;font-weight:500}.loop-filter .dropdown-menu .selected:after{content:'';display:inline-block;width:.65em;height:.35em;border-left:.1em solid currentColor;border-bottom:.1em solid currentColor;transform:translate(-50%,-50%) rotate(-45deg);position:absolute;right:.5rem;top:45%;opacity:.6}.loop-filter-count{display:inline-block;background-color:rgba(150,160,170,.2);padding:0 .45em;margin-inline-start:.125rem;-webkit-margin-start:.125rem;font-size:11px;border-radius:1rem}.loop-filter-count:empty{display:none}.dropdown-menu .multi-range{margin:1rem}input[type=range].multirange{-webkit-appearance:none;height:2px;padding:0;margin:1rem 0 0;width:calc(100% - 0px);display:inline-block;vertical-align:top;background-color:rgba(150,150,150,.5);color:currentColor;outline:0;border:0;border-radius:6px}input[type=range].multirange.original{position:absolute}input[type=range].multirange::-webkit-slider-thumb{-webkit-appearance:none;position:relative;z-index:2;border:none;width:12px;height:12px;border-radius:100%;background-color:currentColor}input[type=range].multirange::-moz-range-thumb{border:none;width:12px;height:12px;border-radius:100%;background-color:currentColor}input[type=range].multirange.original::-moz-range-thumb{z-index:2}input[type=range].multirange.ghost{position:relative;background:var(--track-background);--track-background:linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 100%/100% 100%;--range-color:currentColor}input[type=range].multirange.ghost::-webkit-slider-thumb{position:relative;z-index:2}input[type=range].multirange.ghost::-moz-range-thumb{z-index:2}.multi-range{position:relative}.range-max,.range-min{position:absolute;top:-6px;font-size:10px;width:10px;display:flex;justify-content:center;text-align:center;left:calc(var(--left) * 1%);margin-left:calc(0px - var(--left)/ 100 * 10px)}.spinner{display:inline-block;width:1rem;height:1rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner .75s linear infinite;animation:spinner .75s linear infinite}.loop-filter-keys{width:100%;display:flex;grid-gap:.5rem;flex-wrap:wrap}.loop-filter-keys a{font-weight:600;font-size:.9em;display:inline-flex;text-decoration:none}.loop-filter-keys a:after{content:'\00d7';font-family:arial;font-weight:400;display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;line-height:0;border-radius:100%;background-color:#666;color:#fff;opacity:0;margin:-4px -7px 0 -7px;transition:opacity .2s}.loop-filter-keys a:hover:after{opacity:1}.loop-filter-total{width:100%}a.loop-filter-clear{font-weight:400;align-items:center;opacity:.7}a.loop-filter-clear:hover{opacity:1}a.loop-filter-clear:after{order:-1;margin:2px;opacity:1}@keyframes spinner{0%{transform:scale(0)}50%{opacity:1}}@media (max-width:576px){:root{--loop-grid-gap:1rem}.block-loop-row .block-loop-items{--loop-columns:1}.block-loop-row:not(.has-loop-posts):not(.block-loop-xs):not(.block-loop-inline) .block-loop-item:not(.block-loop-inline) .entry-footer{flex:auto;width:100%}.block-loop-row:not(.has-loop-posts):not(.block-loop-xs):not(.block-loop-inline) .block-loop-item:not(.block-loop-inline) .post-thumbnail{width:4.5rem}.block-loop-row .entry-footer>:first-child:not(.btn-add){padding-inline-start:0}.block-loop-row .add_to_cart_inline,.block-loop-row .btn-purchase,.block-loop-row .entry-description,.block-loop-row .entry-info{display:none}.block-loop-inline .waveform,.block-loop-nav,.has-loop-posts .btn-download,.has-loop-posts .btn-like,.has-loop-posts .play-count{display:none}.modal-open .wp-block-loop-product .block-loop-slider{overflow:visible}.entry-content>.wp-block-loop-slider:not(.block-loop-center) .block-loop-items{padding:0 var(--x-gap,var(--wp--style--root--padding-left,1rem));margin:0 calc(var(--x-gap,var(--wp--style--root--padding-left,1rem)) * -1);scroll-snap-type:none;--loop-max-width:85%}}@media (min-width:577px){.block-loop-with-filter{display:flex;align-items:flex-start;height:100%}.block-loop-with-filter .block-loop-items{flex:1}.block-loop-with-filter .loop-filter{flex-direction:column;min-width:15rem;margin:0;height:100%}.is-series .has-loop-posts .post-thumbnail{border-radius:5px;width:5rem;height:5rem}} -
loops-block/trunk/includes/class-loopsblock.php
r3669702 r3725635 2 2 3 3 /** 4 * Loops base class.4 * LoopsBlock class 5 5 * 6 6 * @since 1.0.0 … … 15 15 16 16 /** 17 * Nonce action for filter click protection. 18 */ 19 const NONCE_ACTION = 'loopsblock_filter_click'; 20 21 /** 22 * cache group 23 */ 24 const CACHE_GROUP_RENDER = 'loopsblock_render'; 25 const CACHE_GROUP_TERMS = 'loopsblock_terms'; 26 27 /** 17 28 * The name from the plugin file 18 29 * … … 69 80 private $query_string = ''; 70 81 /** 82 * Cache version (self-incrementing int) 83 * 84 * @var int|null 85 */ 86 private static $cache_version = null; 87 /** 88 * Per-request memo for is_user_context() 89 * 90 * @var array 91 */ 92 private static $user_context_memo = array(); 93 /** 94 * Per-request memo for get_normalized_query_string() 95 * 96 * @var string|null 97 */ 98 private $normalized_qs = null; 99 /** 71 100 * Instance. 72 * 101 * 73 102 * @var object 74 103 */ … … 120 149 add_action( 'ffl_loop_template', array( $this, 'get_loopsblock_template' ) ); 121 150 151 /* ---------------- Cache invalidation hooks ---------------- */ 152 add_action( 'save_post', array( $this, 'flush_cache' ) ); 153 add_action( 'clean_post_cache', array( $this, 'flush_cache' ) ); 154 add_action( 'set_object_terms', array( $this, 'flush_cache' ) ); 155 add_action( 'created_term', array( $this, 'flush_cache' ) ); 156 add_action( 'edited_term', array( $this, 'flush_cache' ) ); 157 add_action( 'delete_term', array( $this, 'flush_cache' ) ); 158 add_action( 'profile_update', array( $this, 'flush_cache' ) ); 159 add_action( 'user_register', array( $this, 'flush_cache' ) ); 160 add_action( 'delete_user', array( $this, 'flush_cache' ) ); 161 add_action( 'switch_theme', array( $this, 'flush_all_caches' ) ); 162 add_action( 'activated_plugin', array( $this, 'flush_all_caches' ) ); 163 add_action( 'deactivated_plugin', array( $this, 'flush_all_caches' ) ); 164 122 165 do_action( 'loopsblock_init', $this ); 123 166 } 167 168 /* ================================================================== */ 169 /* Cache helpers */ 170 /* ================================================================== */ 171 172 /** 173 * Cache version (self-incrementing int). 174 * 175 * @return int 176 */ 177 private static function cache_version() { 178 if ( null === self::$cache_version ) { 179 self::$cache_version = (int) get_option( 'loopsblock_cache_version', 1 ); 180 } 181 return self::$cache_version; 182 } 183 184 /** 185 * Build a versioned cache key. 186 * Payload is recursively ksort'd so key order in arrays doesn't matter. 187 * 188 * @param string $prefix 189 * @param mixed $payload 190 * @return string 191 */ 192 private static function cache_key( $prefix, $payload ) { 193 return $prefix . '_v' . self::cache_version() . '_' . md5( wp_json_encode( self::ksort_recursive( $payload ) ) ); 194 } 195 196 /** 197 * Recursively sort arrays by key so json_encode is stable. 198 * 199 * @param mixed $array 200 * @return mixed 201 */ 202 private static function ksort_recursive( $array ) { 203 if ( ! is_array( $array ) ) { 204 return $array; 205 } 206 ksort( $array ); 207 foreach ( $array as $k => $v ) { 208 $array[ $k ] = self::ksort_recursive( $v ); 209 } 210 return $array; 211 } 212 213 /** 214 * Bump cache version → invalidates all group caches at once. 215 */ 216 public function flush_cache() { 217 $v = (int) get_option( 'loopsblock_cache_version', 1 ); 218 $v++; 219 update_option( 'loopsblock_cache_version', $v, false ); 220 self::$cache_version = $v; 221 222 // WP 6.1+ supports flushing a cache group (only with persistent cache). 223 if ( function_exists( 'wp_cache_supports' ) && wp_cache_supports( 'flush_group' ) ) { 224 wp_cache_flush_group( self::CACHE_GROUP_RENDER ); 225 wp_cache_flush_group( self::CACHE_GROUP_TERMS ); 226 } 227 } 228 229 /** 230 * Flush everything including editor transients. 231 */ 232 public function flush_all_caches() { 233 $this->flush_cache(); 234 delete_transient( 'loopsblock_tpls' ); 235 delete_transient( 'loopsblock_types' ); 236 delete_transient( 'loopsblock_taxonomies' ); 237 delete_transient( 'loopsblock_images' ); 238 delete_transient( 'loopsblock_user_roles' ); 239 } 240 241 /** 242 * Is a persistent object cache available? 243 * 244 * @return bool 245 */ 246 private static function has_persistent_object_cache() { 247 return function_exists( 'wp_using_ext_object_cache' ) && wp_using_ext_object_cache(); 248 } 249 250 /** 251 * Is transient caching allowed for this key/group/attributes? 252 * 253 * Behavior: 254 * - When a persistent object cache (Redis/Memcached) is available, 255 * transient is NEVER used — wp_cache_* is sufficient and we avoid 256 * polluting wp_options. 257 * - Otherwise (no persistent object cache), transient is written ONLY 258 * when the calling block opts in via `$attributes['transient_cache']`, 259 * or a filter forces it on. 260 * 261 * @param string $key 262 * @param string $group 263 * @param array $attributes 264 * @return bool 265 */ 266 private static function is_transient_available( $key = '', $group = '', $attributes = array() ) { 267 // Redis/Memcached present → always skip transient. 268 if ( self::has_persistent_object_cache() ) { 269 return false; 270 } 271 272 $default = ! empty( $attributes['transient_cache'] ); 273 return (bool) apply_filters( 'loopsblock_enable_transient_cache', $default, $key, $group, $attributes ); 274 } 275 276 /** 277 * Is filter-click nonce verification enabled? 278 * 279 * Default: enabled. 280 * 281 * Disable globally: 282 * add_filter( 'loopsblock_enable_filter_nonce', '__return_false' ); 283 * 284 * @return bool 285 */ 286 private static function is_filter_nonce_enabled() { 287 return (bool) apply_filters( 'loopsblock_enable_filter_nonce', true ); 288 } 289 290 /** 291 * Cache get: wp_cache_* first; transient fallback (opt-in, no-persistent-cache only). 292 * 293 * @param string $key 294 * @param string $group 295 * @param array $attributes Block attributes (for transient opt-in). 296 * @return mixed|false 297 */ 298 private static function cache_get( $key, $group, $attributes = array() ) { 299 $v = wp_cache_get( $key, $group ); 300 if ( false !== $v ) { 301 return $v; 302 } 303 if ( self::is_transient_available( $key, $group, $attributes ) ) { 304 $v = get_transient( $key ); 305 if ( false !== $v ) { 306 // warm the per-request object cache 307 wp_cache_set( $key, $v, $group, MINUTE_IN_SECONDS * 5 ); 308 return $v; 309 } 310 } 311 return false; 312 } 313 314 /** 315 * Cache set: write wp_cache_*; write transient only when opted in 316 * AND no persistent object cache is available. 317 * 318 * Empty string / null / empty array values are skipped to avoid polluting wp_options. 319 * 320 * @param string $key 321 * @param mixed $val 322 * @param string $group 323 * @param int $ttl 324 * @param array $attributes Block attributes (for transient opt-in). 325 */ 326 private static function cache_set( $key, $val, $group, $ttl, $attributes = array() ) { 327 // FIX: don't pollute wp_options with empty values 328 if ( '' === $val || null === $val || array() === $val ) { 329 return; 330 } 331 wp_cache_set( $key, $val, $group, $ttl ); 332 if ( self::is_transient_available( $key, $group, $attributes ) ) { 333 set_transient( $key, $val, $ttl ); 334 } 335 } 336 337 /* ================================================================== */ 338 /* Query string normalization (nonce-aware) */ 339 /* ================================================================== */ 340 341 /** 342 * Get the normalized query string for cache key + query building. 343 * 344 * Behavior: 345 * - Strips `click` (nonce) from the returned string. 346 * - If filter nonce is enabled and the request lacks a valid `click`, 347 * all filter params (taxQuery/metaQuery/order/search/sort) are 348 * dropped, keeping only `id`. The resulting page is identical to a 349 * fresh (unfiltered) visit and shares the same cache entry. 350 * - If filter nonce is disabled, only `click` is stripped. 351 * 352 * Memoized per-request. 353 * 354 * @return string 355 */ 356 private function get_normalized_query_string() { 357 if ( null !== $this->normalized_qs ) { 358 return $this->normalized_qs; 359 } 360 361 $query_string = $this->query_string; 362 if ( '' === $query_string ) { 363 $this->normalized_qs = ''; 364 return ''; 365 } 366 367 parse_str( $query_string, $query ); 368 369 // Extract block discriminator `id` (never subject to nonce check). 370 $id = isset( $query['id'] ) ? $query['id'] : null; 371 372 if ( ! self::is_filter_nonce_enabled() ) { 373 // Nonce disabled → just strip `click`, keep everything else. 374 unset( $query['click'] ); 375 $this->normalized_qs = http_build_query( $query ); 376 return $this->normalized_qs; 377 } 378 379 // Determine whether the request carries filter params 380 // (excluding `id` and `click`). 381 $filter_params = array_diff_key( $query, array( 'id' => 1, 'click' => 1 ) ); 382 383 if ( empty( $filter_params ) ) { 384 // No filter params → strip stray click, keep as-is. 385 unset( $query['click'] ); 386 $this->normalized_qs = http_build_query( $query ); 387 return $this->normalized_qs; 388 } 389 390 // Has filter params → require valid nonce. 391 $nonce_ok = isset( $query['click'] ) && wp_verify_nonce( $query['click'], self::NONCE_ACTION ); 392 393 if ( ! $nonce_ok ) { 394 // Invalid / missing nonce → drop all filter params, keep `id`. 395 $query = array(); 396 if ( null !== $id ) { 397 $query['id'] = $id; 398 } 399 400 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 401 error_log( '[loopsblock] invalid or missing filter nonce from ' . ( $_SERVER['REMOTE_ADDR'] ?? '?' ) ); 402 } 403 } else { 404 // Valid nonce → strip it, keep filter params + id. 405 unset( $query['click'] ); 406 } 407 408 $this->normalized_qs = http_build_query( $query ); 409 return $this->normalized_qs; 410 } 411 412 /** 413 * Does this block declare a permission filter? 414 * If yes → must NOT be cached. 415 * 416 * @param array $attributes 417 * @return bool 418 */ 419 private function has_permission_filter( $attributes ) { 420 if ( empty( $attributes['displayPermission'] ) ) { 421 return false; 422 } 423 return in_array( 424 $attributes['displayPermission'], 425 array( 'users', 'user_roles', 'php_func' ), 426 true 427 ); 428 } 429 430 /** 431 * Contexts that must not be cached because they depend on the current user. 432 * 433 * @return array 434 */ 435 private function get_user_contexts() { 436 return apply_filters( 'loopsblock_user_contexts', array( 437 'user_followers', 'user_following', 'user_likes', 'user_dislikes', 438 'user_downloads', 'user_notifications', 'user_posts', 439 ) ); 440 } 441 442 /** 443 * Does this loop depend on the current user via its `context` attribute? 444 * Memoized per-request. 445 * 446 * @param array $attributes 447 * @return bool 448 */ 449 private function is_user_context( $attributes ) { 450 if ( empty( $attributes['context'] ) ) { 451 return false; 452 } 453 $ctx = strtolower( (string) $attributes['context'] ); 454 if ( ! isset( self::$user_context_memo[ $ctx ] ) ) { 455 self::$user_context_memo[ $ctx ] = in_array( $ctx, $this->get_user_contexts(), true ); 456 } 457 return self::$user_context_memo[ $ctx ]; 458 } 459 460 /** 461 * User salt for cache key: anon vs. user_id + role hash. 462 * 463 * @return string 464 */ 465 private function user_salt() { 466 if ( ! is_user_logged_in() ) { 467 return 'anon'; 468 } 469 $u = wp_get_current_user(); 470 return 'u' . $u->ID . '_' . md5( implode( ',', (array) $u->roles ) ); 471 } 472 473 /* ================================================================== */ 474 /* Registration */ 475 /* ================================================================== */ 124 476 125 477 /** … … 162 514 */ 163 515 public function get_user_roles(){ 516 $cache_key = 'loopsblock_user_roles_v' . self::cache_version(); 517 $cached = get_transient( $cache_key ); 518 if ( false !== $cached ) { 519 return $cached; 520 } 521 164 522 global $wp_roles; 165 523 $wp_roles_names = array_reverse( $wp_roles->role_names ); 166 return array_keys($wp_roles_names); 524 $roles = array_keys( $wp_roles_names ); 525 526 set_transient( $cache_key, $roles, DAY_IN_SECONDS ); 527 return $roles; 167 528 } 168 529 169 530 /** 170 531 * filter the permission from attributes. 171 *172 * @param object block attributes173 532 */ 174 533 public function isPermissionFiltered($atts){ … … 212 571 /** 213 572 * render the permission block 214 *215 * @param object block attributes216 * @param string block content217 573 */ 218 574 public function render_permission_block( $atts, $content ){ … … 226 582 $filtered_bool = (bool) $filtered; 227 583 228 if ( $display xor $filtered ) {584 if ( $display xor $filtered_bool ) { 229 585 return ''; 230 586 } … … 233 589 } 234 590 591 /* ================================================================== */ 592 /* Assets */ 593 /* ================================================================== */ 594 235 595 /** 236 596 * enqueue styles 237 597 */ 238 598 public function enqueue_styles() { 599 if ( wp_style_is( $this->name . '-style', 'registered' ) ) { 600 wp_enqueue_style( $this->name . '-style' ); 601 return; 602 } 239 603 wp_register_style( 240 604 $this->name . '-style', … … 243 607 $this->version 244 608 ); 245 246 609 wp_enqueue_style( $this->name . '-style' ); 247 610 } … … 260 623 true 261 624 ); 262 263 625 wp_enqueue_script( $this->name ); 264 626 } 265 627 266 /** 267 * render the loop block 268 * 269 * @param object block attributes 628 /* ================================================================== */ 629 /* Render */ 630 /* ================================================================== */ 631 632 /** 633 * render the loop block (cached decorator). 634 * 635 * @param array $attributes 636 * @return string 270 637 */ 271 638 public function render_loop_block( $attributes ) { 639 // permission-gated blocks are never cached 640 $cacheable = ! $this->has_permission_filter( $attributes ); 641 642 // user-context loops (my likes / my followers / …) are never cached 643 if ( $this->is_user_context( $attributes ) ) { 644 $cacheable = false; 645 } 646 647 // admin debug / context messages are dynamic → skip cache 648 if ( current_user_can( 'manage_options' ) 649 && ( ! empty( $_REQUEST['context'] ) || ! empty( $attributes['debug'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended 650 $cacheable = false; 651 } 652 653 $cacheable = apply_filters( 'loopsblock_enable_render_cache', $cacheable, $attributes ); 654 655 $attributes = apply_filters( 'loopsblock_attributes', $attributes ); 656 657 // Normalized query string (nonce-aware, no `click`) 658 $normalized_qs = $this->get_normalized_query_string(); 659 $query_args = $this->get_query_params( $attributes, $normalized_qs ); 660 661 $cache_key = ''; 662 if ( $cacheable ) { 663 // Cache key must include BOTH: 664 // - $attributes → affects display (title, cols, slider, template, …) 665 // - $query_args → affects query (post_type, tax_query, …) 666 $cache_key = self::cache_key( 'loopsblock_render', array( 667 'attr' => $attributes, 668 'q' => $query_args, 669 'qs' => $normalized_qs, 670 'url' => $this->query_url, 671 'user' => $this->user_salt(), 672 ) ); 673 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_RENDER, $attributes ); 674 if ( false !== $cached ) { 675 return apply_filters( 'loopsblock_content', $cached ); 676 } 677 } 678 679 $block_content = $this->do_render_loop_block( $attributes, $query_args ); 680 681 if ( $cacheable && '' !== $cache_key && '' !== $block_content ) { 682 self::cache_set( $cache_key, $block_content, self::CACHE_GROUP_RENDER, 10 * MINUTE_IN_SECONDS, $attributes ); 683 } 684 685 return apply_filters( 'loopsblock_content', $block_content ); 686 } 687 688 /** 689 * The actual render logic. 690 * 691 * @param array $attributes 692 * @param array $query_args 693 * @return string 694 */ 695 private function do_render_loop_block( $attributes, $query_args ) { 272 696 $block_content = $className = $slick = $jscroll = $more = $pager = $title = $filter = $items = ''; 273 697 $query = false; 274 $attributes = apply_filters( 'loopsblock_attributes', $attributes );275 698 276 699 do_action( 'loopsblock_before_render', $attributes ); … … 279 702 $block_content = __( 'No loop type.', 'loops-block' ); 280 703 } else { 281 $query_args = $this->get_query_params($attributes);282 704 $total_pages = 0; 283 705 if ( $attributes[ 'type' ] == 'user' ) { … … 370 792 371 793 if (isset($attributes[ 'pager' ]) && $attributes[ 'pager' ] == 'pagination' ) { 372 $pager = $this->get_pagination( $total_pages, $query_args[ 'paged' ] ); 794 $paged_arg = isset( $query_args[ 'paged' ] ) ? $query_args[ 'paged' ] : 1; 795 $pager = $this->get_pagination( $total_pages, $paged_arg ); 373 796 } 374 797 … … 386 809 $jscroll = 'data-plugin="scroller" data-option="' . sprintf( '{autoTrigger: %1$s}"', $attributes[ 'pager' ] == 'scroll' ? 'true' : 'false' ); 387 810 } else { 388 // overide wrapper389 811 $wrapper = '%1$s%2$s%3$s%4$s%5$s'; 390 812 } 391 if ( $total_pages > $query_args[ 'paged' ] ) { 392 $attributes[ 'paged' ] = $query_args[ 'paged' ] + 1; 813 $paged_arg = isset( $query_args[ 'paged' ] ) ? $query_args[ 'paged' ] : 1; 814 if ( $total_pages > $paged_arg ) { 815 $attributes[ 'paged' ] = $paged_arg + 1; 393 816 $attributes = $this->normalize_load_more_attributes( $attributes ); 394 $url = get_rest_url( null, '/loop/more' ). sprintf( '?%s', $this-> http_build_query( $attributes ) );817 $url = get_rest_url( null, '/loop/more' ). sprintf( '?%s', $this->build_more_query( $attributes ) ); 395 818 $url = apply_filters( 'loopsblock_more_link', $url, $attributes, $this ); 396 819 $more = '<a href="' . esc_url( $url ) . '" class="scroller no-ajax button"><span>• • •</span><span class="screen-reader-text">' . __( 'More', 'loops-block' ) . '</span></a>'; 397 $more = apply_filters( 'loopsblock_more_button', $more, $url, $this ); 820 $more = apply_filters( 'loopsblock_more_button', $more, $url, $this ); 398 821 } 399 822 } … … 409 832 $block_content .= '<p>'.__( 'No loop item.', 'loops-block' ).'</p>'; 410 833 } 411 if(!empty( $attributes[ 'debug' ] ) ){412 $block_content .= '<pre style="font-size: 11px;order:10; white-space:normal">' . json_encode( $query_args) . '</pre>';834 if(!empty( $attributes[ 'debug' ] ) && defined( 'WP_DEBUG' ) && WP_DEBUG ){ 835 $block_content .= '<pre style="font-size: 11px;order:10; white-space:normal">' . esc_html( wp_json_encode( $query_args ) ) . '</pre>'; 413 836 } 414 837 } 415 838 } 416 839 do_action( 'loopsblock_after_render', $attributes, $query ); 417 return apply_filters( 'loopsblock_content', $block_content );840 return $block_content; 418 841 } 419 842 420 843 /** 421 844 * output the loop block 422 *423 * @param object block attributes424 * @param bolean echo content or not425 845 */ 426 846 public function the_block( $attributes, $echo = true ) { … … 436 856 /** 437 857 * output the filter 438 *439 * @param object block attributes440 * @param bolean echo filter or not441 858 */ 442 859 public function the_filter( $attributes, $echo = true ) { … … 448 865 } 449 866 450 /** 451 * get the filter content 452 * 453 * @param object block attributes 867 /* ================================================================== */ 868 /* Filter (cached) */ 869 /* ================================================================== */ 870 871 /** 872 * get the filter content (cached) 873 * 874 * @param array $attributes 875 * @return string 454 876 */ 455 877 private function get_filter( $attributes ) { … … 457 879 return ''; 458 880 } 459 881 882 // user-context filters are never cached 883 $cacheable = ! $this->is_user_context( $attributes ); 884 885 $cache_key = ''; 886 if ( $cacheable ) { 887 // Only filter-relevant attributes affect the output. 888 $filter_keys = array( 'filter', 'id', 'url', 'ids' ); 889 $filter_attr = array_intersect_key( $attributes, array_flip( $filter_keys ) ); 890 891 $cache_key = self::cache_key( 'loopsblock_filter', array( 892 'attr' => $filter_attr, 893 'qs' => $this->get_normalized_query_string(), 894 'url' => $this->query_url, 895 ) ); 896 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_RENDER, $attributes ); 897 if ( false !== $cached ) { 898 return $cached; 899 } 900 } 901 902 $html = $this->do_get_filter( $attributes ); 903 904 if ( $cacheable && '' !== $cache_key && '' !== $html ) { 905 self::cache_set( $cache_key, $html, self::CACHE_GROUP_RENDER, 10 * MINUTE_IN_SECONDS, $attributes ); 906 } 907 return $html; 908 } 909 910 /** 911 * Actually build filter HTML. 912 * 913 * Uses the normalized query string — nonce is already verified there. 914 * 915 * @param array $attributes 916 * @return string 917 */ 918 private function do_get_filter( $attributes ) { 460 919 $filter = $attributes[ 'filter' ]; 461 920 $url = isset($attributes[ 'url' ]) ? $attributes[ 'url' ] : $this->query_url; … … 463 922 $url = preg_replace($pattern, '', $url); 464 923 $id = isset($attributes[ 'id' ]) ? $attributes[ 'id' ] : ''; 465 // parse query string 466 $query_string = $this->query_string; 924 925 // Use normalized query string — no `click`, already nonce-verified. 926 $query_string = $this->get_normalized_query_string(); 467 927 parse_str( $query_string, $query ); 468 928 array_walk_recursive($query, 'sanitize_text_field'); … … 473 933 } 474 934 } 475 // todo: parse the attribute meta/tax/order to menu 476 477 // if we got ?s= and not on search page 935 478 936 if(isset($query['s']) && !is_search()){ 479 937 $query['search'] = $query['s']; … … 515 973 516 974 // all taxonomy 517 if( strpos( strtolower($value), '__all' ) ){975 if( strpos( strtolower($value), '__all' ) !== false ){ 518 976 $reg = '/(.*?)__all\[(.*?)\]/'; 519 977 if( preg_match($reg, $v, $m) ){ … … 521 979 $default = (object) array( 'name' => (isset($m[2]) ? $m[2] : 'All'), 'slug' => '', 'count' => '' ); 522 980 if(!empty($attributes['ids'])) { 523 // get terms by ids to use connect filter524 981 $terms = $this->get_terms($i, $attributes['ids']); 525 982 }else{ 526 // get all terms 527 $terms = get_terms( $i ); 983 $terms = $this->get_terms_cached( $i ); 528 984 } 529 985 if( !empty($terms) && !is_wp_error( $terms ) ){ … … 546 1002 $j = isset($term[1]) ? $term[1] : $term[0]; 547 1003 $item = array( 'name' => $ma[2] ); 548 // set value for ranges549 1004 $ranges = preg_match( '/^\d+-\d+$/', $j ); 550 1005 if( $ranges ){ … … 561 1016 562 1017 if( empty($filters) ){ 563 return ;1018 return ''; 564 1019 } 565 1020 … … 576 1031 577 1032 /** 1033 * Cached wrapper for get_terms() used by the filter. 1034 * 1035 * Note: term lists are global (not block-specific), so we don't pass 1036 * block attributes. Transient opt-in must be done via filter if needed. 1037 */ 1038 private function get_terms_cached( $taxonomy ) { 1039 $cache_key = 'loopsblock_filter_terms_v' . self::cache_version() . '_' . $taxonomy; 1040 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_TERMS ); 1041 if ( false !== $cached ) { 1042 return $cached; 1043 } 1044 1045 $terms = get_terms( array( 1046 'taxonomy' => $taxonomy, 1047 'hide_empty' => false, 1048 ) ); 1049 1050 if ( is_wp_error( $terms ) ) { 1051 return $terms; 1052 } 1053 1054 self::cache_set( $cache_key, $terms, self::CACHE_GROUP_TERMS, HOUR_IN_SECONDS ); 1055 return $terms; 1056 } 1057 1058 /** 578 1059 * build the filter item 579 *580 * @param object filter item581 * @param string582 * @param string583 * @param array584 * @param string filter url585 * @param string attributes id586 1060 */ 587 1061 private function build_filter_item(&$item, $key, $term, $value, $q, $url, $id){ … … 598 1072 unset( $q[$key][$term] ); 599 1073 } 600 1074 601 1075 $q[$key][$term][$value] = ''; 602 1076 } … … 626 1100 } 627 1101 1102 // Add nonce for filter click protection 1103 if ( ! empty( $str ) && self::is_filter_nonce_enabled() ) { 1104 $str['click'] = wp_create_nonce( self::NONCE_ACTION ); 1105 } 1106 628 1107 $url = $url . '?' . http_build_query($str); 629 1108 $url = apply_filters( 'loopsblock_filter_link', $url, $item, $key, $term, $value, $q, $str ); … … 633 1112 /** 634 1113 * build the filter keys 635 *636 * @param array637 * @param object638 * @param array639 1114 */ 640 1115 public function build_filter_keys($filters, $attributes, $keys){ … … 648 1123 $sep = apply_filters('loopsblock_filter_sep', ','); 649 1124 $clear = $attributes['filterClearText']; 650 1125 651 1126 foreach ( $keys as $key ){ 652 1127 if($key == end($keys)){ … … 668 1143 } 669 1144 670 /** 671 * get the ad content 672 * 673 * @param object 1145 /* ================================================================== */ 1146 /* Ad (cached) */ 1147 /* ================================================================== */ 1148 1149 /** 1150 * get the ad content (cached) 674 1151 */ 675 1152 private function get_ad_content($attributes){ 676 1153 if(!isset($attributes['adTitle']) || $attributes['adTitle']===''){ 677 return; 1154 return ''; 1155 } 1156 1157 $cacheable = ! $this->is_user_context( $attributes ); 1158 1159 $cache_key = ''; 1160 if ( $cacheable ) { 1161 $ad_keys = array( 'adImage', 'adTitle', 'adSubtitle', 'adSponsor', 'adLink', 'adOrder' ); 1162 $ad_attr = array_intersect_key( $attributes, array_flip( $ad_keys ) ); 1163 1164 $cache_key = self::cache_key( 'loopsblock_ad', $ad_attr ); 1165 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_RENDER, $attributes ); 1166 if ( false !== $cached ) { 1167 return $cached; 1168 } 678 1169 } 679 1170 … … 696 1187 include plugin_dir_path( dirname( __FILE__ ) ) . $tpl; 697 1188 } 698 699 return ob_get_clean(); 700 } 1189 $html = ob_get_clean(); 1190 1191 if ( $cacheable && '' !== $cache_key && '' !== $html ) { 1192 self::cache_set( $cache_key, $html, self::CACHE_GROUP_RENDER, 10 * MINUTE_IN_SECONDS, $attributes ); 1193 } 1194 return $html; 1195 } 1196 1197 /* ================================================================== */ 1198 /* Content / templates */ 1199 /* ================================================================== */ 701 1200 702 1201 /** 703 1202 * get the content 704 *705 * @param object query results706 * @param object block attributes707 * @param array query args708 1203 */ 709 1204 private function get_content( $query, $attributes, $query_args ) { … … 734 1229 } else { 735 1230 foreach ( $query->posts as $post ) { 736 // avoid loop in loop737 1231 $post->post_content = str_replace( "wp:block/loop", "wp:block/loop-disabled", $post->post_content ); 738 1232 setup_postdata( $post ); … … 747 1241 /** 748 1242 * get the loop content 749 *750 * @param object query results751 * @param object block attributes752 * @param array query args753 1243 */ 754 1244 public function get_loopsblock_template() { … … 760 1250 /** 761 1251 * get the loop template 762 *763 * @param string template file764 * @param string post/user/taxonomy765 1252 */ 766 1253 private function get_template( $tpl, $type ) { … … 784 1271 785 1272 /** 786 * locate the template file 787 * 788 * @param string template name 789 * @param string template path 790 * @param string default template path 1273 * locate the template file (per-request static cache) 791 1274 */ 792 1275 public function locate_template( $template_name, $template_path = '', $default_path = '' ) { 1276 static $runtime = array(); 1277 1278 $cache_key = $template_name . '|' . $template_path . '|' . $default_path; 1279 if ( isset( $runtime[ $cache_key ] ) ) { 1280 return $runtime[ $cache_key ]; 1281 } 1282 793 1283 if ( ! $template_path ) { 794 1284 $template_path = '/templates/'; … … 799 1289 } 800 1290 801 // Look within passed path within the theme - this is priority.802 1291 $template = locate_template( 803 1292 array( … … 807 1296 ); 808 1297 809 // Get default template/.810 1298 if ( ! $template ) { 811 812 1299 $tpl_name = basename( $template_name ); 813 1300 814 // Force .php extension if template name is tampered with815 1301 if ( 'php' != pathinfo( $tpl_name, PATHINFO_EXTENSION ) ) { 816 1302 $info = pathinfo( $tpl_name ); … … 818 1304 } 819 1305 820 // Rebuild the template path removing anything nasty821 1306 $tpl = $default_path . trailingslashit( $template_path ) . $tpl_name; 822 1307 … … 826 1311 } 827 1312 828 // Return what we found. 829 return apply_filters( 'loopsblock_locate_template', $template, $template_name, $template_path ); 830 } 1313 $template = apply_filters( 'loopsblock_locate_template', $template, $template_name, $template_path ); 1314 1315 $runtime[ $cache_key ] = $template; 1316 return $template; 1317 } 1318 1319 /* ================================================================== */ 1320 /* Query params */ 1321 /* ================================================================== */ 831 1322 832 1323 /** 833 1324 * get loop query parameters 834 * 835 * @param object attributes 836 */ 837 private function get_query_params( $args ) { 1325 * 1326 * @param array $args 1327 * @param string|null $query_string Optional. Pre-normalized query string. 1328 * @return array 1329 */ 1330 private function get_query_params( $args, $query_string = null ) { 1331 return $this->do_get_query_params( $args, $query_string ); 1332 } 1333 1334 /** 1335 * Build query params. 1336 */ 1337 private function do_get_query_params( $args, $query_string = null ) { 838 1338 $args = apply_filters( 'loopsblock_get_query_params_attributes', $args); 1339 1340 if ( null === $query_string ) { 1341 $query_string = $this->get_normalized_query_string(); 1342 } 1343 839 1344 $query_args = []; 840 1345 if ( $args[ 'type' ] == 'user' || $args[ 'type' ] == 'taxonomy' ) { … … 849 1354 $query_args[ 'posts_per_page' ] = $args[ 'pages' ]; 850 1355 $include = 'post__in'; 851 // ignore sticky post852 1356 $query_args[ 'ignore_sticky_posts' ] = 1; 853 1357 } … … 862 1366 } 863 1367 864 // ids865 1368 if ( !empty( $args[ 'ids' ] ) ) { 866 1369 $query_args[ $include ] = $args[ 'ids' ]; 867 1370 } 868 1371 869 // query (admin query field OR front-end 'query' arg)870 1372 if ( !empty( $args[ 'query' ] ) ) { 871 1373 $query_args = wp_parse_args( $args[ 'query' ], $query_args ); 872 1374 } 873 1375 874 // get parameter from query_string 875 // add the taxQuery/metaQuery 876 // override order/orderby 877 $query_string = $this->query_string; 1376 // query_string → tax / meta / order 878 1377 parse_str( $query_string, $query ); 879 1378 array_walk_recursive($query, 'sanitize_text_field'); 880 1379 $query = apply_filters( 'loopsblock_query_string_raw', $query, $args ); 881 // only apply the front-end query on loop base on attribute id882 1380 if(!empty($query['id'])){ 883 1381 if(empty($args['id']) || $args['id'] !== $query['id']){ … … 886 1384 } 887 1385 888 // build the params from the $query;889 // search890 1386 if(!empty($query['search'])){ 891 1387 $args['search'] = $query['search']; 892 1388 } 893 // replace894 1389 if(!empty($query['order'])){ 895 1390 $args['order'] = $query['order']; … … 906 1401 } 907 1402 908 // add tax and meta from front-end query909 1403 if(!empty($query['taxQuery'])){ 910 1404 if(!is_array($args['taxQuery'])){ … … 921 1415 // taxonomy 922 1416 if ( ! empty( $args[ 'taxQuery' ] ) ) { 923 // nested taxonomy handling, same using OR, diff using AND924 1417 if(empty($query_args[ 'tax_query' ])){ 925 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- use tax_query for filter926 1418 $query_args[ 'tax_query' ] = []; 927 1419 } 928 1420 $queries = []; 929 // parse taxonomy (admin/front)930 // taxQuery=genre__electronic,ambient+mood__feeling-blue,focus+station_tag__dance-hit931 932 1421 foreach($args[ 'taxQuery' ] as $tax){ 933 1422 if(is_string($tax)){ … … 937 1426 } 938 1427 } 939 // prepare taxonomy940 1428 $ts = []; 941 1429 foreach ($queries as $q) { … … 948 1436 $ts[$key][] = implode(':', $matches); 949 1437 } 950 // build taxonomy951 1438 foreach ( $ts as $key => $value ) { 952 1439 $a = []; … … 978 1465 // meta 979 1466 if ( ! empty( $args[ 'metaQuery' ] ) ) { 980 // no nested meta handling981 1467 if(empty($query_args[ 'meta_query' ])){ 982 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- use meta_query for filter983 1468 $query_args[ 'meta_query' ] = []; 984 1469 } … … 992 1477 } 993 1478 foreach ( $queries as $q ) { 994 //match : or __995 //eg: key:value:compare:type996 1479 $matches = preg_split( '/\:|__/', $q ); 997 1480 if(count( $matches ) < 2){ … … 1002 1485 'value' => $matches[ 1 ] 1003 1486 ); 1004 // in1005 1487 if(strpos($matches[ 1 ], ',') !== false){ 1006 1488 $arr['value'] = explode(',', $matches[ 1 ]); 1007 1489 $arr['compare'] = 'IN'; 1008 1490 } 1009 // range1010 1491 $ranges = preg_match( '/^\d+-\d+$/', $matches[ 1 ] ); 1011 1492 if($ranges){ … … 1045 1526 $query_args[ 'order' ] = $args[ 'order' ]; 1046 1527 } 1047 // orderby1048 1528 if ( ! empty( $args[ 'orderby' ] ) ) { 1049 1529 $query_args[ 'orderby' ] = $args[ 'orderby' ]; … … 1057 1537 if ( isset( $args[ 'pager' ] ) ) { 1058 1538 $query_args[ 'paged' ] = $this->get_paged($query_args[ 'paged' ]); 1059 // use offset for taxonomy1060 1539 if ( $args[ 'type' ] == 'taxonomy' ) { 1061 1540 $query_args[ 'offset' ] = ( $this->get_paged($query_args[ 'paged' ]) - 1 ) * $query_args[ 'number' ]; 1062 1541 } 1063 1542 } 1064 // reset to page 1 if not set pager1065 1543 if(empty($args['pager'])){ 1066 1544 $query_args[ 'paged' ] = 1; … … 1069 1547 $query_args = apply_filters( 'loopsblock_query_args', $query_args, $args ); 1070 1548 1071 // fix long query string1072 1549 foreach ($this->http_query_arr as $value) { 1073 1550 if( isset($query_args[$value]) && !is_array($query_args[$value]) ){ … … 1076 1553 } 1077 1554 1078 // search1079 1555 if ( ! empty( $args[ 'search' ] ) ) { 1080 1556 $query_args[ 's' ] = $args[ 'search' ]; … … 1095 1571 /** 1096 1572 * get loop sql query 1097 *1098 * @param object attributes1099 1573 */ 1100 1574 private function get_sql_query( $args = array() ) { … … 1103 1577 } 1104 1578 1105 /** 1106 * get loop types 1107 * 1579 /* ================================================================== */ 1580 /* Editor lists (cached via transient) */ 1581 /* ================================================================== */ 1582 1583 /** 1584 * get loop types (cached 1 day) 1108 1585 */ 1109 1586 private function get_types() { 1587 $cache_key = 'loopsblock_types_v' . self::cache_version(); 1588 $cached = get_transient( $cache_key ); 1589 if ( false !== $cached ) { 1590 return $cached; 1591 } 1592 1110 1593 $types = [ array( 'label' => '— Select —' ) ]; 1111 1594 foreach ( get_post_types( array( 'public' => true ), 'objects' ) as $id => $type ) { … … 1118 1601 $types[] = array( 'label' => 'Taxonomies', 'value' => 'taxonomy' ); 1119 1602 1120 return apply_filters( 'loopsblock_types', $types, $this ); 1121 } 1122 1123 /** 1124 * get loop taxonomies 1125 * 1603 $types = apply_filters( 'loopsblock_types', $types, $this ); 1604 set_transient( $cache_key, $types, DAY_IN_SECONDS ); 1605 return $types; 1606 } 1607 1608 /** 1609 * get loop taxonomies (cached 1 day) 1126 1610 */ 1127 1611 private function get_taxonomies() { 1612 $cache_key = 'loopsblock_taxonomies_v' . self::cache_version(); 1613 $cached = get_transient( $cache_key ); 1614 if ( false !== $cached ) { 1615 return $cached; 1616 } 1617 1128 1618 $taxonomies = []; 1129 1619 foreach ( get_taxonomies( array( 'public' => true ) ) as $taxonomy ) { … … 1131 1621 } 1132 1622 1133 return apply_filters( 'loopsblock_taxonomies', $taxonomies, $this ); 1134 } 1135 1136 /** 1137 * get image sizes 1138 * 1623 $taxonomies = apply_filters( 'loopsblock_taxonomies', $taxonomies, $this ); 1624 set_transient( $cache_key, $taxonomies, DAY_IN_SECONDS ); 1625 return $taxonomies; 1626 } 1627 1628 /** 1629 * get image sizes (cached 1 day) 1139 1630 */ 1140 1631 private function get_images() { 1632 $cache_key = 'loopsblock_images_v' . self::cache_version(); 1633 $cached = get_transient( $cache_key ); 1634 if ( false !== $cached ) { 1635 return $cached; 1636 } 1637 1141 1638 $arr = []; 1142 1639 foreach ( get_intermediate_image_sizes() as $size ) { … … 1144 1641 } 1145 1642 1146 return apply_filters( 'loopsblock_image_sizes', $arr ); 1147 } 1148 1149 /** 1150 * get template files 1151 * 1643 $arr = apply_filters( 'loopsblock_image_sizes', $arr ); 1644 set_transient( $cache_key, $arr, DAY_IN_SECONDS ); 1645 return $arr; 1646 } 1647 1648 /** 1649 * get template files (cached 1 day; glob scan is expensive) 1152 1650 */ 1153 1651 private function get_tpls() { 1652 $cache_key = 'loopsblock_tpls_v' . self::cache_version(); 1653 $cached = get_transient( $cache_key ); 1654 if ( false !== $cached ) { 1655 return $cached; 1656 } 1657 1154 1658 $tpls = [ array( 'label' => '— Select —' ) ]; 1155 1659 $tpl_files = apply_filters( 'loopsblock_template_files', array( 1156 // '*/content*.php',1157 // '*/*/content*.php',1158 1660 '*/loop*.php', 1159 1661 '*/*/loop*.php', … … 1183 1685 sort( $tpls ); 1184 1686 1185 return apply_filters( 'loopsblock_templates', $tpls ); 1186 } 1187 1188 /** 1189 * get pagination 1190 * 1191 * @param int total results 1192 * @param int paged 1193 * @param string block id 1687 $tpls = apply_filters( 'loopsblock_templates', $tpls ); 1688 set_transient( $cache_key, $tpls, DAY_IN_SECONDS ); 1689 return $tpls; 1690 } 1691 1692 /* ================================================================== */ 1693 /* Pagination (cached) */ 1694 /* ================================================================== */ 1695 1696 /** 1697 * get pagination (cached) 1698 * 1699 * Note: pagination is global (not block-specific). Transient opt-in 1700 * must be done via filter if needed. 1194 1701 */ 1195 1702 private function get_pagination( $total, $paged, $id='' ) { 1703 $cache_key = self::cache_key( 'loopsblock_pager', array( $total, $paged, $id, $this->query_url ) ); 1704 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_RENDER ); 1705 if ( false !== $cached ) { 1706 return $cached; 1707 } 1708 1196 1709 if ( get_option( 'permalink_structure' ) ) { 1197 1710 $base = str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ); … … 1225 1738 $pagination = sprintf( '<nav class="navigation pagination"><div class="nav-links">%1$s</div></nav>', $pagination ); 1226 1739 } 1227 return apply_filters( 'loopsblock_pagination', $pagination, $total, $paged, $this ); 1740 $pagination = apply_filters( 'loopsblock_pagination', $pagination, $total, $paged, $this ); 1741 1742 if ( '' !== $pagination ) { 1743 self::cache_set( $cache_key, $pagination, self::CACHE_GROUP_RENDER, 10 * MINUTE_IN_SECONDS ); 1744 } 1745 return $pagination; 1228 1746 } 1229 1747 1230 1748 /** 1231 1749 * get paged 1232 *1233 1750 */ 1234 1751 private function get_paged($paged) { … … 1243 1760 } 1244 1761 1762 /* ================================================================== */ 1763 /* Misc */ 1764 /* ================================================================== */ 1765 1245 1766 /** 1246 1767 * set pages 1247 *1248 1768 */ 1249 1769 public function set_pages(){ … … 1252 1772 $page = ( int ) $wp_query->get( 'page' ); 1253 1773 if ( $page > 1 ) { 1254 // convert 'page' to 'paged'1255 1774 $wp_query->set( 'page', 1 ); 1256 1775 $wp_query->set( 'paged', $page ); 1257 1776 } 1258 // prevent redirect1259 1777 remove_action( 'template_redirect', 'redirect_canonical' ); 1260 1778 } … … 1262 1780 1263 1781 /** 1264 * load more content 1265 * 1266 * @param array 1782 * load more content (cached for anonymous users) 1267 1783 */ 1268 1784 public function load_more( $request ) { 1269 if ( isset( $request[ 'paged' ] ) ) { 1270 $args = $request->get_params(); 1271 $args[ 'ajax' ] = 1; 1272 return wp_send_json( 1273 array( 'content' => $this->render_loop_block( apply_filters( 'loopsblock_ajax_more', $args, $this ) ) ) 1274 ); 1275 } 1276 } 1277 1278 /** 1279 * get terms for filter to use connect terms 1280 * 1281 * @param string 1282 * @param array 1785 if ( ! isset( $request[ 'paged' ] ) ) { 1786 return; 1787 } 1788 1789 $args = $request->get_params(); 1790 // sanitize: paged must be a positive integer 1791 $args[ 'paged' ] = absint( $args[ 'paged' ] ); 1792 if ( ! $args[ 'paged' ] ) { 1793 $args[ 'paged' ] = 1; 1794 } 1795 $args[ 'ajax' ] = 1; 1796 1797 // cache only for anonymous, non-user-context requests 1798 $cache_enabled = ! is_user_logged_in() 1799 && ! $this->is_user_context( $args ) 1800 && apply_filters( 'loopsblock_enable_more_cache', true, $args ); 1801 1802 $cache_key = ''; 1803 if ( $cache_enabled ) { 1804 $cache_key = self::cache_key( 'loopsblock_more', $args ); 1805 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_RENDER, $args ); 1806 if ( false !== $cached ) { 1807 return wp_send_json( $cached ); 1808 } 1809 } 1810 1811 $data = array( 1812 'content' => $this->render_loop_block( 1813 apply_filters( 'loopsblock_ajax_more', $args, $this ) 1814 ) 1815 ); 1816 1817 if ( $cache_enabled && '' !== $cache_key && ! empty( $data['content'] ) ) { 1818 self::cache_set( $cache_key, $data, self::CACHE_GROUP_RENDER, 5 * MINUTE_IN_SECONDS, $args ); 1819 } 1820 1821 return wp_send_json( $data ); 1822 } 1823 1824 /* ================================================================== */ 1825 /* get_terms (FIXED + cached) */ 1826 /* ================================================================== */ 1827 1828 /** 1829 * get terms for filter to use connect terms. 1830 * 1831 * Note: global resource, no block attributes. Transient opt-in via filter. 1283 1832 */ 1284 1833 public function get_terms($taxonomy, $ids){ … … 1287 1836 return []; 1288 1837 } 1289 $arr = implode(',', array_map( 'absint', $ids )); 1290 $cache_key = $taxonomy.$arr; 1291 $cached_terms = wp_cache_get( $cache_key, 'loopsblock_term_cache' ); 1292 if ( false !== $cached_terms ) { 1293 return $cached_terms; 1838 $arr = implode(',', array_map( 'absint', (array) $ids )); 1839 $cache_key = 'loopsblock_terms_rel_v' . self::cache_version() . '_' . $taxonomy . '_' . md5( $arr ); 1840 1841 $cached = self::cache_get( $cache_key, self::CACHE_GROUP_TERMS ); 1842 if ( false !== $cached ) { 1843 return $cached; 1294 1844 } 1295 1845 1296 1846 // phpcs:ignore WordPress.DB.DirectDatabaseQuery 1297 $ cached_terms = $wpdb->query(1847 $results = $wpdb->get_results( 1298 1848 $wpdb->prepare( 1299 " SELECT t erms.name, terms.slug, COUNT(tr.object_id) as count FROM {$wpdb->terms} terms" .1300 " INNER JOIN {$wpdb->term_taxonomy} tt ON (tt.term_id = t erms.term_id) " .1849 " SELECT t.name, t.slug, COUNT(tr.object_id) AS count FROM {$wpdb->terms} t " . 1850 " INNER JOIN {$wpdb->term_taxonomy} tt ON (tt.term_id = t.term_id) " . 1301 1851 " INNER JOIN {$wpdb->term_relationships} tr ON (tr.term_taxonomy_id = tt.term_taxonomy_id) " . 1302 " WHERE tr.object_id IN ( %s) AND tt.taxonomy = %s GROUP BY terms.term_id ",1303 $arr,1852 " WHERE tr.object_id IN ({$arr}) AND tt.taxonomy = %s " . 1853 " GROUP BY t.term_id, t.name, t.slug ", 1304 1854 $taxonomy ) 1305 1855 ); 1306 1856 1307 wp_cache_set( $cache_key, $cached_terms, 'loopsblock_term_cache' ); 1308 return $cached_terms; 1309 } 1310 1311 /** 1312 * add groupby filter 1313 * 1314 * @param array 1315 */ 1857 self::cache_set( $cache_key, $results, self::CACHE_GROUP_TERMS, HOUR_IN_SECONDS ); 1858 return $results; 1859 } 1860 1861 /* ================================================================== */ 1862 /* Query filters */ 1863 /* ================================================================== */ 1864 1316 1865 public function add_query_filter( $query_args ){ 1317 1866 $this->args = $query_args; … … 1320 1869 } 1321 1870 1322 /**1323 * remove groupby filter1324 *1325 * @param array1326 */1327 1871 public function remove_query_filter( $query_args ){ 1328 1872 remove_filter( 'posts_groupby', array($this, 'posts_groupby') ); 1329 1873 remove_filter( 'posts_where', array( $this, 'posts_where' ), 10, 2 ); 1330 1874 } 1331 1332 /** 1333 * posts groupby 1334 * https://developer.wordpress.org/reference/hooks/posts_groupby/ 1335 * 1336 * @param string 1337 */ 1875 1338 1876 public function posts_groupby($groupby){ 1339 1877 global $wpdb; … … 1343 1881 return $groupby; 1344 1882 } 1345 1346 /** 1347 * posts where 1348 * 1349 * @param string 1350 * @param object 1351 */ 1883 1352 1884 public function posts_where( $where, $query ) { 1353 // find_in_set for featured on1354 1885 global $wpdb; 1886 // FIX: guard against null or empty meta_query 1887 if ( empty( $query->meta_query ) || empty( $query->meta_query->queries ) ) { 1888 return $where; 1889 } 1355 1890 foreach ( $query->meta_query->queries as $index => $meta_query ) { 1356 1891 if ( isset( $meta_query[ 'compare' ] ) && 'find_in_set' == strtolower( $meta_query[ 'compare' ] ) ) { … … 1362 1897 } 1363 1898 1364 /** 1365 * normalize arrtributes 1366 * 1367 * @param object 1368 */ 1899 /* ================================================================== */ 1900 /* Helpers */ 1901 /* ================================================================== */ 1902 1369 1903 public function normalize_load_more_attributes( $attributes = array() ) { 1904 // IMPORTANT: do NOT add 'context' here — load_more() relies on it 1905 // to skip user-context requests from caching. 1370 1906 $exclusions = apply_filters( 'loopsblock_attribute_exclusions', array( 1371 1907 'title', … … 1375 1911 'sliderOption', 1376 1912 'align', 1377 'action' // added automatically so can be removed to avoid duplicates1913 'action' 1378 1914 ) ); 1379 1915 … … 1392 1928 1393 1929 /** 1394 * build http query 1395 * 1396 * @param array 1397 */ 1398 private function http_build_query($query_args){ 1399 // get query_string for load more / scroll 1400 $query_string = $this->query_string; 1930 * Build more query string. 1931 * 1932 * @param array $query_args 1933 * @return string 1934 */ 1935 private function build_more_query($query_args){ 1936 // Use normalized query string — nonce already verified/stripped. 1937 $query_string = $this->get_normalized_query_string(); 1401 1938 parse_str( $query_string, $query ); 1402 1939 if( !empty($query['paged']) ){ 1403 1940 unset($query['paged']); 1404 1941 } 1942 // Defensive: strip click in case any leak 1943 unset( $query['click'] ); 1405 1944 $query_args = array_merge( $query_args, $query ); 1406 1945 array_walk_recursive($query_args, 'sanitize_text_field'); 1407 1946 1408 // fixed long query1409 1947 foreach ($this->http_query_arr as $value) { 1410 1948 if( isset($query_args[$value]) && is_array($query_args[$value]) ){ … … 1417 1955 return http_build_query($query_args); 1418 1956 } 1957 1958 /** 1959 * Backward-compat wrapper (private). 1960 */ 1961 private function http_build_query($query_args){ 1962 return $this->build_more_query( $query_args ); 1963 } 1419 1964 } 1420 1965 -
loops-block/trunk/loops-block.php
r3671635 r3725635 5 5 * Description: An advanced block that allows displaying posts, taxonomies and users based on different query parameters and visual configurations. 6 6 * Author: wooscroll 7 * Version: 1.0. 48 * Tested up to: 7.1 7 * Version: 1.0.6 8 * Tested up to: 7.1.2 9 9 * License: GPLv3 10 10 * License URI: https://www.gnu.org/licenses/gpl-3.0.html -
loops-block/trunk/readme.txt
r3671635 r3725635 4 4 Requires at least: 6.0 5 5 Requires PHP: 7.4 6 Tested up to: 7.1 7 Stable tag: 1.0. 46 Tested up to: 7.1.2 7 Stable tag: 1.0.6 8 8 License: GPLv3 9 9 License URI: https://www.gnu.org/licenses/gpl-3.0.html
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)