Changeset 3748403
- Timestamp:
- 10/15/2026 12:10:58 PM (3 weeks ago)
- Location:
- 4wp-faq/trunk
- Files:
-
- 2 added
- 33 edited
-
4wp-faq.php (modified) (2 diffs)
-
assets/admin-dashboard.css (modified) (5 diffs)
-
assets/faq-view.js (modified) (10 diffs)
-
blocks/faq-card/block.json (modified) (1 diff)
-
blocks/faq-categories/block.json (modified) (1 diff)
-
blocks/faq-list/block.json (modified) (2 diffs)
-
blocks/faq-no-results (added)
-
blocks/faq-no-results/block.json (added)
-
build/admin/index.asset.php (modified) (1 diff)
-
build/admin/index.js (modified) (1 diff)
-
build/admin/style-index-rtl.css (modified) (1 diff)
-
build/admin/style-index.css (modified) (1 diff)
-
build/faq-card.asset.php (modified) (1 diff)
-
build/faq-card.js (modified) (1 diff)
-
build/faq-categories.asset.php (modified) (1 diff)
-
build/faq-categories.js (modified) (1 diff)
-
build/faq-count.asset.php (modified) (1 diff)
-
build/faq-count.js (modified) (1 diff)
-
build/faq-list.asset.php (modified) (1 diff)
-
build/faq-list.js (modified) (1 diff)
-
build/index.asset.php (modified) (1 diff)
-
build/index.js (modified) (1 diff)
-
build/style-faq-card-rtl.css (modified) (1 diff)
-
build/style-faq-card.css (modified) (1 diff)
-
build/style-faq-categories-rtl.css (modified) (1 diff)
-
build/style-faq-categories.css (modified) (1 diff)
-
build/style-faq-list-rtl.css (modified) (1 diff)
-
build/style-faq-list.css (modified) (1 diff)
-
includes/class-admin-dashboard.php (modified) (2 diffs)
-
includes/class-dashboard-setup.php (modified) (2 diffs)
-
includes/class-display-blocks.php (modified) (31 diffs)
-
includes/class-plugin.php (modified) (4 diffs)
-
includes/class-registry-content.php (modified) (3 diffs)
-
includes/integrations/class-polylang.php (modified) (1 diff)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
4wp-faq/trunk/4wp-faq.php
r3704354 r3748403 4 4 * Plugin URI: https://github.com/4wpdev/4wp-faq 5 5 * Description: FAQ wrapper for core Accordion: JSON-LD, optional registry you can edit or add from (writes back onto pages), hub blocks, usage context. Site content stays the source of truth. 6 * Version: 2.6. 16 * Version: 2.6.5 7 7 * Requires at least: 6.6 8 8 * Requires PHP: 7.4 … … 20 20 } 21 21 22 define( 'FORWP_FAQ_VERSION', '2.6. 1' );22 define( 'FORWP_FAQ_VERSION', '2.6.5' ); 23 23 define( 'FORWP_FAQ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 24 24 define( 'FORWP_FAQ_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
4wp-faq/trunk/assets/admin-dashboard.css
r3685374 r3748403 2 2 * Classic FAQ dashboard widgets (wp-admin dashboard pattern). 3 3 */ 4 5 /* Square postboxes — native wp-admin, not the rounded dashboard CSS. */6 body.forwp-faq-dashboard-page #dashboard-widgets .postbox,7 body.forwp-faq-dashboard-page #dashboard-widgets .postbox-container .empty-container,8 body.forwp-faq-dashboard-page.is-dragging-metaboxes #dashboard-widgets .meta-box-sortables {9 border-radius: 0;10 }11 4 12 5 /* Keep 3-col and 33/66 radios visible below 1500px (core dashboard.css hides them). */ … … 17 10 18 11 @media screen and (min-width: 800px) { 19 /* 2 columns: 50 / 50 */ 20 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 .postbox-container, 21 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-1, 22 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-2, 23 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-3, 24 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-4 { 25 width: 50%; 12 /* 2 columns: same split as the WordPress dashboard, so the third column stacks on the right. */ 13 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-1 { 14 float: left; 15 width: 49.5%; 26 16 } 27 17 … … 30 20 body.forwp-faq-dashboard-page #wpbody-content #dashboard-widgets.columns-2 #postbox-container-4 { 31 21 float: right; 22 clear: right; 23 width: 50.5%; 32 24 } 33 25 … … 173 165 } 174 166 175 #dashboard-widgets #forwp_faq_status .inside { 176 margin: 0; 177 padding: 0; 167 #dashboard-widgets #forwp_faq_status .inside, 168 #dashboard-widgets #forwp_faq_home .inside { 169 margin: 0; 170 padding: 0; 171 } 172 173 #dashboard-widgets .forwp-faq-stats { 174 display: grid; 175 grid-template-columns: 1fr 1fr; 176 } 177 178 #dashboard-widgets .forwp-faq-stat-cell { 179 display: block; 180 padding: 16px 8px; 181 border-top: 1px solid #f0f0f1; 182 text-align: center; 183 text-decoration: none; 184 } 185 186 #dashboard-widgets .forwp-faq-stat-cell:nth-child(-n + 2) { 187 border-top: 0; 188 } 189 190 #dashboard-widgets .forwp-faq-stat-cell:nth-child(odd) { 191 border-right: 1px solid #f0f0f1; 192 } 193 194 #dashboard-widgets .forwp-faq-stat-cell:hover, 195 #dashboard-widgets .forwp-faq-stat-cell:focus { 196 background: #f6f7f7; 197 } 198 199 #dashboard-widgets .forwp-faq-stat-cell__value { 200 display: block; 201 color: #1d2327; 202 font-size: 28px; 203 font-weight: 600; 204 line-height: 1; 205 } 206 207 #dashboard-widgets .forwp-faq-stat-cell__label { 208 display: block; 209 margin-top: 4px; 210 color: #646970; 211 font-size: 13px; 212 line-height: 1.3; 178 213 } 179 214 … … 371 406 border-top: 1px solid #f0f0f1; 372 407 } 408 409 #dashboard-widgets .forwp-faq-dash-lang { 410 margin: 0; 411 padding: 8px 12px; 412 border-bottom: 1px solid #f0f0f1; 413 color: #50575e; 414 font-size: 12px; 415 } 416 417 #dashboard-widgets .forwp-faq-dash-langs { 418 margin: 0; 419 border-width: 0 0 1px; 420 } 421 422 #dashboard-widgets .forwp-faq-dash-langs th:first-child, 423 #dashboard-widgets .forwp-faq-dash-langs td:first-child { 424 padding-left: 12px; 425 } 426 427 #dashboard-widgets .forwp-faq-dash-langs th, 428 #dashboard-widgets .forwp-faq-dash-langs td { 429 padding: 4px 8px; 430 font-size: 12px; 431 } -
4wp-faq/trunk/assets/faq-view.js
r3691205 r3748403 30 30 }; 31 31 32 const normalizePath = ( path ) => 33 ( path || '' ).replace( /\/+$/, '' ) || '/'; 34 35 /** 36 * Category from ?faq_cat= or a pretty /hub/term-slug/ URL. 37 * Match the full nav href path — never the host page slug alone 38 * (e.g. /4wp-faq/ must not activate category "4wp-faq"). 39 */ 32 40 const categoryFromLocation = () => { 33 41 const params = new URLSearchParams( window.location.search || '' ); … … 37 45 } 38 46 39 const currentPath = ( window.location.pathname || '' ).replace( /\/+$/, '' ); 40 const last = currentPath.split( '/' ).filter( Boolean ).pop() || ''; 41 if ( ! last ) { 42 return ''; 43 } 44 47 const currentPath = normalizePath( window.location.pathname || '' ); 45 48 const links = document.querySelectorAll( 46 49 '.forwp-faq-categories__link[data-faq-cat]' … … 48 51 let match = ''; 49 52 links.forEach( ( link ) => { 50 const slug = link.getAttribute( 'data-faq-cat' ) || ''; 51 if ( slug && slug === last ) { 52 match = slug; 53 const slug = ( link.getAttribute( 'data-faq-cat' ) || '' ).trim(); 54 if ( ! slug || match ) { 55 return; 56 } 57 const href = link.getAttribute( 'href' ) || ''; 58 if ( ! href || href === '#' ) { 59 return; 60 } 61 try { 62 const linkPath = normalizePath( 63 new URL( href, window.location.origin ).pathname || '' 64 ); 65 if ( linkPath === currentPath ) { 66 match = slug; 67 } 68 } catch ( e ) { 69 // Ignore malformed hrefs. 53 70 } 54 71 } ); … … 67 84 }; 68 85 86 // Without a search the badge shows the category nav totals, not the cards on screen (preview limit). 87 const currentCount = () => { 88 if ( ! String( state.search || '' ).trim() ) { 89 const total = state.totals?.[ state.category || '' ]; 90 if ( typeof total === 'number' ) { 91 return total; 92 } 93 } 94 return countVisibleCards(); 95 }; 96 69 97 const { state } = store( 'forwp/faq', { 70 98 state: { … … 94 122 return ! state.isBranchOpen; 95 123 }, 124 get isMenuOpen() { 125 return !! state.menuOpen; 126 }, 127 get hasNoResults() { 128 return ( 129 !! String( state.search || '' ).trim() && state.visibleCount === 0 130 ); 131 }, 96 132 get isGroupVisible() { 97 133 const ctx = getContext() || {}; 98 if ( ! state.category ) { 99 return true; 100 } 101 if ( ( ctx.slug || '' ) === state.category ) { 102 return true; 103 } 104 const ancestors = ( ctx.ancestors || '' ).split( /\s+/ ).filter( Boolean ); 105 return ancestors.indexOf( state.category ) !== -1; 134 if ( state.category ) { 135 const slug = ctx.slug || ''; 136 const ancestors = ( ctx.ancestors || '' ) 137 .split( /\s+/ ) 138 .filter( Boolean ); 139 const isSelf = slug === state.category; 140 const isDescendant = 141 ancestors.indexOf( state.category ) !== -1; 142 // Keep parents of the active category visible (nested list HTML). 143 const isAncestor = 144 ( state.categoryAncestors || [] ).indexOf( slug ) !== -1; 145 if ( ! isSelf && ! isDescendant && ! isAncestor ) { 146 return false; 147 } 148 } 149 const query = ( state.search || '' ).trim().toLowerCase(); 150 if ( query && ( ctx.searchText || '' ).indexOf( query ) === -1 ) { 151 return false; 152 } 153 return true; 106 154 }, 107 155 get isItemVisible() { … … 119 167 }, 120 168 actions: { 169 toggleMenu( event ) { 170 if ( event && typeof event.preventDefault === 'function' ) { 171 event.preventDefault(); 172 } 173 state.menuOpen = ! state.menuOpen; 174 }, 121 175 toggleBranch: withSyncEvent( ( event ) => { 122 176 if ( event && typeof event.preventDefault === 'function' ) { … … 149 203 event.preventDefault(); 150 204 } 151 state.category = ctx.slug || '';205 applyCategory( ctx.slug || '', ctx.ancestors || '' ); 152 206 window.requestAnimationFrame( () => { 153 state.visibleCount = c ountVisibleCards();207 state.visibleCount = currentCount(); 154 208 } ); 155 209 }, … … 159 213 target && typeof target.value === 'string' ? target.value : ''; 160 214 window.requestAnimationFrame( () => { 161 state.visibleCount = c ountVisibleCards();215 state.visibleCount = currentCount(); 162 216 } ); 163 217 }, … … 169 223 }, 170 224 } ); 225 226 const ancestorsForSlug = ( slug ) => { 227 if ( ! slug ) { 228 return []; 229 } 230 const groups = document.querySelectorAll( '.forwp-faq-list__group' ); 231 for ( let i = 0; i < groups.length; i++ ) { 232 const raw = groups[ i ].getAttribute( 'data-wp-context' ); 233 if ( ! raw ) { 234 continue; 235 } 236 try { 237 const ctx = JSON.parse( raw ); 238 if ( ( ctx.slug || '' ) === slug ) { 239 return String( ctx.ancestors || '' ) 240 .split( /\s+/ ) 241 .filter( Boolean ); 242 } 243 } catch ( e ) { 244 // Ignore malformed context. 245 } 246 } 247 return []; 248 }; 249 250 const applyCategory = ( slug, ancestorsRaw ) => { 251 state.category = slug || ''; 252 if ( ! slug ) { 253 state.categoryAncestors = []; 254 return; 255 } 256 if ( typeof ancestorsRaw === 'string' && ancestorsRaw.trim() ) { 257 state.categoryAncestors = ancestorsRaw.split( /\s+/ ).filter( Boolean ); 258 return; 259 } 260 state.categoryAncestors = ancestorsForSlug( slug ); 261 }; 171 262 172 263 if ( ! state.category ) { 173 264 const fromUrl = categoryFromLocation(); 174 265 if ( fromUrl ) { 175 state.category = fromUrl; 176 } 266 applyCategory( fromUrl ); 267 } 268 } else if ( ! Array.isArray( state.categoryAncestors ) ) { 269 state.categoryAncestors = ancestorsForSlug( state.category ); 177 270 } 178 271 … … 182 275 183 276 if ( typeof state.visibleCount !== 'number' ) { 184 state.visibleCount = c ountVisibleCards();277 state.visibleCount = currentCount(); 185 278 } 186 279 187 280 window.addEventListener( 'popstate', () => { 188 state.category = categoryFromLocation();189 state.visibleCount = c ountVisibleCards();281 applyCategory( categoryFromLocation() ); 282 state.visibleCount = currentCount(); 190 283 } ); -
4wp-faq/trunk/blocks/faq-card/block.json
r3698640 r3748403 30 30 "default": "Used in" 31 31 }, 32 "sourcesSeparator": { 33 "type": "string", 34 "default": ", " 35 }, 32 36 "showPostType": { 33 37 "type": "boolean", -
4wp-faq/trunk/blocks/faq-categories/block.json
r3698640 r3748403 57 57 "type": "number" 58 58 } 59 }, 60 "allItemFontSize": { 61 "type": "string", 62 "default": "" 63 }, 64 "itemFontSize": { 65 "type": "string", 66 "default": "" 67 }, 68 "itemGap": { 69 "type": "string", 70 "default": "" 59 71 } 60 72 }, -
4wp-faq/trunk/blocks/faq-list/block.json
r3698640 r3748403 46 46 "default": "Used in" 47 47 }, 48 "cardSourcesSeparator": { 49 "type": "string", 50 "default": ", " 51 }, 48 52 "cardShowPostType": { 49 53 "type": "boolean", … … 55 59 }, 56 60 "cardAnswerStyle": { 61 "type": "object", 62 "default": {} 63 }, 64 "groupTitleStyle": { 57 65 "type": "object", 58 66 "default": {} -
4wp-faq/trunk/build/admin/index.asset.php
r3702258 r3748403 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => ' 73eae73b8f871db33b20');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'b6827ecaf8c95084b4cb'); -
4wp-faq/trunk/build/admin/index.js
r3702258 r3748403 1 (()=>{"use strict";var e,t={476(e,t,a){const n=window.React,l=window.wp.element,r=window.wp.i18n,o=window.wp.apiFetch;var s=a.n(o);const i=window.wp.components,c="/forwp-faq/v1/settings";function p({label:e,value:t,hint:a}){return(0,n.createElement)("div",{className:"forwp-faq-stat"},(0,n.createElement)("span",{className:"forwp-faq-stat__value"},t),(0,n.createElement)("span",{className:"forwp-faq-stat__label"},e),a?(0,n.createElement)("span",{className:"forwp-faq-stat__hint"},a):null)}function u({stats:e,setupComplete:t,lastScan:a}){return e?(0,n.createElement)(i.Card,{className:"forwp-faq-stats-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Overview","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("div",{className:"forwp-faq-stats-grid"},(0,n.createElement)(p,{label:(0,r.__)("Questions","4wp-faq"),value:t?e.total_questions:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Categories","4wp-faq"),value:t?e.faq_categories:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Reused","4wp-faq"),value:t?e.reused_questions:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Items in content","4wp-faq"),value:e.faq_items_in_content}),(0,n.createElement)(p,{label:(0,r.__)("Pages with FAQ","4wp-faq"),value:e.pages_with_faq})),a?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,r.sprintf)(/* translators: %s: date/time */ /* translators: %s: date/time */ 2 (0,r.__)("Last scan: %s","4wp-faq"),a)):null)):null}function d(){const[e,t]=(0,l.useState)(!0),[a,o]=(0,l.useState)(!1),[p,d]=(0,l.useState)(!1),[f,m]=(0,l.useState)(!1),[_,w]=(0,l.useState)(!1),[g,h]=(0,l.useState)(null),[q,E]=(0,l.useState)(null),[y,b]=(0,l.useState)(""),[v,A]=(0,l.useState)(""),[C,k]=(0,l.useState)(!1),N=(0,l.useCallback)(()=>(t(!0),b(""),Promise.all([s()({path:c}),s()({path:"/forwp-faq/v1/registry"})]).then(([e,t])=>{E(e),h(t)}).catch(e=>{b(e?.message||(0,r.__)("Could not load settings.","4wp-faq"))}).finally(()=>t(!1))),[]);if((0,l.useEffect)(()=>{!function(){if("undefined"==typeof window||!window.forwpFaqAdmin||window.forwpFaqAdmin.__middlewareApplied)return;const{restRoot:e,nonce:t}=window.forwpFaqAdmin,a=e.endsWith("/")?e:`${e}/`;s().use(s().createRootURLMiddleware(a)),s().use(s().createNonceMiddleware(t)),window.forwpFaqAdmin.__middlewareApplied=!0}(),N()},[N]),e)return(0,n.createElement)("div",{className:"forwp-faq-tab-loading"},(0,n.createElement)(i.Spinner,null));const O=g?.setup_complete,S=!0===q?.output_json_ld,F=q?.preview_per_category||5,P=!0===q?.seo_urls,Q=!0===q?.ai_available,L=!0===q?.ai_field_markup;return(0,n.createElement)("div",{className:"forwp-faq-settings-layout"},v?(0,n.createElement)(i.Notice,{status:"success",isDismissible:!0,onRemove:()=>A("")},v):null,y?(0,n.createElement)(i.Notice,{status:"error",isDismissible:!1},y):null,(0,n.createElement)(u,{stats:g?.stats,setupComplete:O,lastScan:g?.last_scan_label}),(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Settings","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("div",{className:"forwp-faq-actions-row"},(0,n.createElement)(i.Button,{variant:"primary",onClick:()=>{o(!0),A(""),b(""),s()({path:"/forwp-faq/v1/registry/scan",method:"POST"}).then(e=>{h(e),A((0,r.__)("Registry scan completed.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Scan failed. Please try again.","4wp-faq"))}).finally(()=>o(!1))},isBusy:a,disabled:a||!O},a?(0,r.__)("Scanning…","4wp-faq"):(0,r.__)("Rescan registry","4wp-faq")),!O&&g?.setup_url?(0,n.createElement)(i.ExternalLink,{href:g.setup_url},(0,r.__)("Complete setup to enable scan","4wp-faq")):null),O&&g?.last_scan_label?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,r.sprintf)(/* translators: %s: date/time */ /* translators: %s: date/time */ 3 (0,r.__)("Last scan: %s","4wp-faq"),g.last_scan_label)):null,(0,n.createElement)("hr",{className:"forwp-faq-actions-divider"}),(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("FAQPage JSON-LD","4wp-faq"),help:(0,r.__)("On: schema for questions actually shown. Per-block override still applies.","4wp-faq"),checked:S,disabled:p,onChange:e=>{d(!0),b(""),s()({path:c,method:"POST",data:{output_json_ld:e}}).then(t=>{E(t),A(e?(0,r.__)("JSON-LD enabled site-wide.","4wp-faq"):(0,r.__)("JSON-LD disabled site-wide.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save SEO setting.","4wp-faq"))}).finally(()=>d(!1))}}),(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("Pretty category URLs","4wp-faq"),help:(0,r.__)("Allows /page/term-slug/. Also enable it on the Categories block. Off: in-place filter, URL unchanged.","4wp-faq"),checked:P,disabled:p,onChange:e=>{d(!0),b(""),s()({path:c,method:"POST",data:{seo_urls:e}}).then(t=>{E(t),A(e?(0,r.__)("Pretty category URLs enabled. Turn on SEO-friendly category URLs in the 4WP FAQ Categories block on each hub page.","4wp-faq"):(0,r.__)("Pretty category URLs disabled. Category clicks filter in place and the page URL stays unchanged.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save SEO setting.","4wp-faq"))}).finally(()=>d(!1))}}),(0,n.createElement)(i.RangeControl,{label:(0,r.__)("Questions per group (All view)","4wp-faq"),help:(0,r.__)("Preview count on All categories. Category URLs still list every question.","4wp-faq"),value:F,onChange:e=>{const t="number"==typeof e?e:5;d(!0),b(""),s()({path:c,method:"POST",data:{preview_per_category:t}}).then(e=>{E(e),A((0,r.__)("Preview count saved.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save setting.","4wp-faq"))}).finally(()=>d(!1))},min:1,max:20,disabled:p}),O?(0,n.createElement)(n.Fragment,null,(0,n.createElement)("hr",{className:"forwp-faq-actions-divider"}),(0,n.createElement)("p",{className:"forwp-faq-reset-intro"},(0,r.__)("Reset setup to change CPT/taxonomy slugs. Categories are removed.","4wp-faq")),(0,n.createElement)(i.Button,{variant:"secondary",isDestructive:!0,onClick:()=>k(!0)},(0,r.__)("Reset setup","4wp-faq"))):null)),(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("AI","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("p",null,(0,r.__)("Uses WordPress Connectors. One prompt fills mapped fields on FAQ category edit. Apply writes into the form; Update still saves.","4wp-faq")),Q?null:(0,n.createElement)(i.Notice,{status:"warning",isDismissible:!1},(0,r.__)("WordPress Connectors are not available yet. Configure a text provider, then enable the option below.","4wp-faq"),q?.ai_connectors_url?(0,n.createElement)(n.Fragment,null," ",(0,n.createElement)(i.ExternalLink,{href:q.ai_connectors_url},(0,r.__)("Open Connectors","4wp-faq"))):null),(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("Allow predefined field markup","4wp-faq"),help:Q?(0,r.__)("On: show Generate with AI on category screens. Off: keep the panel hidden.","4wp-faq"):(0,r.__)("Turn on after WordPress Connectors support text generation.","4wp-faq"),checked:Q&&L,disabled:f||!Q,onChange:e=>{m(!0),b(""),s()({path:c,method:"POST",data:{ai_field_markup:e}}).then(t=>{E(t),A(e?(0,r.__)("Predefined field markup enabled. Generate with AI can fill mapped category fields.","4wp-faq"):(0,r.__)("Predefined field markup disabled. The AI panel stays hidden on category screens.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save AI setting.","4wp-faq"))}).finally(()=>m(!1))}}),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Description","4wp-faq"))," — ",(0,r.__)("Core category Description.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Display title","4wp-faq"))," — ",(0,r.__)("On-page title on pretty category URLs.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO title","4wp-faq"))," — ",(0,r.__)("Document title. No site name suffix.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO description","4wp-faq"))," — ",(0,r.__)("Meta description on category URLs.","4wp-faq"))),q?.ai_connectors_url?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,n.createElement)(i.ExternalLink,{href:q.ai_connectors_url},(0,r.__)("WordPress Connectors","4wp-faq"))):null)),(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Category titles","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("p",null,(0,r.__)("On pretty category URLs (/page/term-slug/). Edit fields on each FAQ category.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("On-page title","4wp-faq"))," — ",(0,r.__)("Display title (empty: category name). Put a core Title (post-title), Query Title / Archive title (query-title), or Term Name (term-name). Heading level is the template’s choice. Heading blocks are not swapped.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("On-page description","4wp-faq"))," — ",(0,r.__)("Category Description field. Put a core Excerpt (post-excerpt) or Term Description (term-description). Empty description: WordPress output is left as-is.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Document title","4wp-faq"))," — ",(0,r.__)("SEO title as-is if filled (no site-name suffix). Empty: on-page title + “ – {site name}”.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Meta description","4wp-faq"))," — ",(0,r.__)("SEO description. Empty: hub page default.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Canonical","4wp-faq"))," — ",(0,r.__)("The category URL (/page/term-slug/), not the hub.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO image","4wp-faq"))," — ",(0,r.__)("Open Graph / Twitter image on the category. Empty: hub page image.","4wp-faq"))))),C?(0,n.createElement)(i.Modal,{title:(0,r.__)("Reset FAQ setup?","4wp-faq"),onRequestClose:()=>!_&&k(!1),shouldCloseOnClickOutside:!_,shouldCloseOnEsc:!_},(0,n.createElement)("p",null,(0,r.__)("You can choose new registry slugs in the setup wizard, but all FAQ categories will be removed. Registry entries stay on the previous post type until you complete setup and run a new scan.","4wp-faq")),(0,n.createElement)("div",{className:"forwp-faq-modal-actions"},(0,n.createElement)(i.Button,{variant:"secondary",onClick:()=>k(!1),disabled:_},(0,r.__)("Cancel","4wp-faq")),(0,n.createElement)(i.Button,{variant:"primary",isDestructive:!0,isBusy:_,disabled:_,onClick:()=>{w(!0),b(""),s()({path:"/forwp-faq/v1/setup/reset",method:"POST"}).then(e=>{k(!1),e?.redirect&&(window.location.href=e.redirect)}).catch(e=>{b(e?.message||(0,r.__)("Reset failed. Please try again.","4wp-faq")),k(!1)}).finally(()=>w(!1))}},(0,r.__)("Reset setup","4wp-faq")))):null)}function f({title:e,children:t}){return(0,n.createElement)(i.Card,{className:"forwp-faq-doc-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,e)),(0,n.createElement)(i.CardBody,{className:"forwp-faq-doc-card__body"},t))}function m(){return(0,n.createElement)("div",{className:"forwp-faq-docs-layout"},(0,n.createElement)(f,{title:(0,r.__)("Overview","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("4WP FAQ is a thin wrapper around WordPress core Accordion. It does not replace your blocks or theme styles. It adds an intelligence layer: FAQPage JSON-LD on the front end, optional aggregation into a FAQ registry post type, and usage statistics in the admin.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Your questions and answers live in page content (Accordion items). That is the source of truth. The registry is a scan of unique questions. Edit a registry record and Update: the plugin writes the new Q/A onto every Used In page. Add FAQ to place a new item. Delete the registry or reinstall: a scan rebuilds it from the site.","4wp-faq"))),(0,n.createElement)(f,{title:(0,r.__)("Convert to FAQ","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("You can convert an existing Accordion, Accordion Item, Accordion Group, Details, List, or heading + paragraph pairs into a 4WP FAQ block without rebuilding the layout.","4wp-faq")),(0,n.createElement)("ol",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Select a core Accordion, Accordion Item, Accordion Group, Details, or List in the editor. You can select several Details or Accordion Items at once.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("In the block toolbar, click Convert to 4WP FAQ, or use Transform to → 4WP FAQ.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("The plugin wraps your markup in forwp/faq. Inner Accordion or Details blocks and styling stay the same on the front end.","4wp-faq"))),(0,n.createElement)("p",null,(0,r.__)("Each Accordion Item (or legacy Details block) inside the wrapper counts as one FAQ question for JSON-LD and for the registry scan.","4wp-faq"))),(0,n.createElement)(f,{title:(0,r.__)("Block structure","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Recommended pattern (WordPress 6.x core Accordion):","4wp-faq")),(0,n.createElement)("pre",{className:"forwp-faq-doc-pre"},(0,n.createElement)("code",null,"forwp/faq ← 4WP FAQ wrapper\n└── core/accordion ← container\n └── core/accordion-item ← one Q&A\n ├── accordion heading\n └── accordion panel")),(0,n.createElement)("p",null,(0,r.__)("Legacy core/details blocks inside forwp/faq are still supported. Prefer Accordion + Accordion Item for new pages.","4wp-faq"))),(0,n.createElement)(f,{title:(0,r.__)("Blocks for pages","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Use these blocks when building a FAQ hub or in-page FAQs:","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq")," — ",(0,r.__)("Wrapper around core Accordion or Details for JSON-LD and registry scan. Convert / Transform to 4WP FAQ in the editor.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-list")," — ",(0,r.__)("Registry glossary (grouped or flat). Place on a page or template after setup + scan.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-card")," — ",(0,r.__)("Inner template of the List (not in the inserter). Accordion or heading + answer; optional sources.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-categories")," — ",(0,r.__)("Category nav. Include/exclude stay in sync with the List on the same page.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-count")," — ",(0,r.__)("Live number for All / current category / current search. Same as [forwp_faq_count].","4wp-faq"))),(0,n.createElement)("pre",{className:"forwp-faq-doc-pre"},(0,n.createElement)("code",null,"forwp/faq-categories ← nav (optional)\nforwp/faq-list ← registry questions\n└── forwp/faq-card\ncore/search ← optional filter\nforwp/faq-count ← optional count"))),(0,n.createElement)(f,{title:(0,r.__)("Core Search block","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Add a core Search block on the same page as 4WP FAQ List. In the block sidebar open 4WP FAQ and turn on Filter 4WP FAQ List.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Typing filters visible FAQ cards through the Interactivity store. The form does not submit a WordPress search.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("FAQ Count follows the same search query when the filter is on.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Leave the toggle off if the Search should behave as a normal site search.","4wp-faq")))),(0,n.createElement)(f,{title:(0,r.__)("JSON-LD (SEO)","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("On singular posts and pages, the plugin can output FAQPage structured data (JSON-LD) in the document head when FAQ blocks are present.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Site-wide default: Settings → FAQPage JSON-LD (off by default).","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("When enabled site-wide: every forwp/faq block outputs schema unless you set JSON-LD on front end → Off for this block in the block sidebar.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("When disabled site-wide: no schema by default; enable per block with On for this block in the sidebar.","4wp-faq"))),(0,n.createElement)("p",{className:"forwp-faq-doc-muted"},(0,r.__)("JSON-LD does not require the FAQ registry. Blocks and schema work even if you never complete registry setup.","4wp-faq"))),(0,n.createElement)(f,{title:(0,r.__)("FAQ registry (optional)","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("After you complete setup (Settings → 4WP FAQ Setup), the plugin registers a custom post type and taxonomy (default slugs: faq and faq-category).","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("A scan walks content, finds forwp/faq blocks, and creates or updates registry posts—one per unique question—with usage, categories, and answer snapshots.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Where the question is used (pages, posts, other types)","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("How many times it appears (reuse count)","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Collected answer text and HTML snapshots","4wp-faq"))),(0,n.createElement)("p",null,(0,r.__)("Edit a registry FAQ (title + answer) and Update. The plugin finds that accordion item on every Used In page. If you change the question, it matches the previous title.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Add FAQ: write the question and answer. FAQ categories in the sidebar append the item to every forwp/faq block with those terms. One page (optional) writes only to that post/page. Neither: the row stays in the list until a scan, then it is dropped because it is not on the site.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("A new answer reuses the wrapper of a sibling accordion item on that page (same heading/panel markup) and fills in your text. After save, that wrapped HTML is stored on the registry record.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Run Rescan after you change FAQ content on pages. Registry Update also writes back to those pages, then a scan is scheduled. Scans also run when relevant posts are saved.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Reset setup (Settings tab) lets you change registry slugs in the wizard again but removes all FAQ categories; existing registry entries stay on the previous post type until you complete setup and scan again.","4wp-faq"))),(0,n.createElement)(f,{title:(0,r.__)("Typical workflow","4wp-faq")},(0,n.createElement)("ol",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Add or convert Accordion blocks to forwp/faq on your pages.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Enable JSON-LD on the Settings tab if you want structured data site-wide.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Optional: complete FAQ registry setup and run a scan. Then you can edit a registry FAQ (pushes to Used In pages) or Add FAQ onto category pages / one page.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Review Dashboard stats and open All FAQs under the FAQ admin menu.","4wp-faq")))))}const _=document.getElementById("forwp-faq-admin-root");_&&(0,l.createRoot)(_).render((0,n.createElement)(function(){const[e,t]=(0,l.useState)("settings");return(0,n.createElement)("div",{className:"forwp-faq-admin-app"},(0,n.createElement)("div",{className:"forwp-faq-tab-panel components-tab-panel"},(0,n.createElement)("div",{className:"components-tab-panel__tabs",role:"tablist","aria-label":(0,r.__)("4WP FAQ","4wp-faq")},(0,n.createElement)("button",{type:"button",role:"tab",id:"forwp-faq-tab-settings",className:"components-button components-tab-panel__tabs-item forwp-faq-tab-settings"+("settings"===e?" is-active":""),"aria-selected":"settings"===e,"aria-controls":"forwp-faq-panel-settings",tabIndex:"settings"===e?0:-1,onClick:()=>t("settings")},(0,r.__)("Settings","4wp-faq")),(0,n.createElement)("button",{type:"button",role:"tab",id:"forwp-faq-tab-documentation",className:"components-button components-tab-panel__tabs-item forwp-faq-tab-docs"+("documentation"===e?" is-active":""),"aria-selected":"documentation"===e,"aria-controls":"forwp-faq-panel-documentation",tabIndex:"documentation"===e?0:-1,onClick:()=>t("documentation")},(0,r.__)("Documentation","4wp-faq"))),(0,n.createElement)("div",{id:"forwp-faq-panel-settings",role:"tabpanel","aria-labelledby":"forwp-faq-tab-settings",className:"components-tab-panel__tab-content",hidden:"settings"!==e},(0,n.createElement)(d,null)),(0,n.createElement)("div",{id:"forwp-faq-panel-documentation",role:"tabpanel","aria-labelledby":"forwp-faq-tab-documentation",className:"components-tab-panel__tab-content",hidden:"documentation"!==e},(0,n.createElement)(m,null))))},null))}},a={};function n(e){var l=a[e];if(void 0!==l)return l.exports;var r=a[e]={exports:{}};return t[e](r,r.exports,n),r.exports}n.m=t,e=[],n.O=(t,a,l,r)=>{if(!a){var o=1/0;for(p=0;p<e.length;p++){for(var[a,l,r]=e[p],s=!0,i=0;i<a.length;i++)(!1&r||o>=r)&&Object.keys(n.O).every(e=>n.O[e](a[i]))?a.splice(i--,1):(s=!1,r<o&&(o=r));if(s){e.splice(p--,1);var c=l();void 0!==c&&(t=c)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[a,l,r]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={773:0,641:0};n.O.j=t=>0===e[t];var t=(t,a)=>{var l,r,[o,s,i]=a,c=0;if(o.some(t=>0!==e[t])){for(l in s)n.o(s,l)&&(n.m[l]=s[l]);if(i)var p=i(n)}for(t&&t(a);c<o.length;c++)r=o[c],n.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return n.O(p)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var l=n.O(void 0,[641],()=>n(476));l=n.O(l)})(); 1 (()=>{"use strict";var e,t={476(e,t,a){const n=window.React,l=window.wp.element,r=window.wp.i18n,s=window.wp.apiFetch;var o=a.n(s);const i=window.wp.components,c="/forwp-faq/v1/settings";function p({label:e,value:t,hint:a}){return(0,n.createElement)("div",{className:"forwp-faq-stat"},(0,n.createElement)("span",{className:"forwp-faq-stat__value"},t),(0,n.createElement)("span",{className:"forwp-faq-stat__label"},e),a?(0,n.createElement)("span",{className:"forwp-faq-stat__hint"},a):null)}function f({stats:e,setupComplete:t,lastScan:a}){return e?(0,n.createElement)(i.Card,{className:"forwp-faq-stats-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Overview","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("div",{className:"forwp-faq-stats-grid"},(0,n.createElement)(p,{label:(0,r.__)("Questions","4wp-faq"),value:t?e.total_questions:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Categories","4wp-faq"),value:t?e.faq_categories:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Reused","4wp-faq"),value:t?e.reused_questions:"—"}),(0,n.createElement)(p,{label:(0,r.__)("Items in content","4wp-faq"),value:e.faq_items_in_content}),(0,n.createElement)(p,{label:(0,r.__)("Pages with FAQ","4wp-faq"),value:e.pages_with_faq})),a?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,r.sprintf)(/* translators: %s: date/time */ /* translators: %s: date/time */ 2 (0,r.__)("Last scan: %s","4wp-faq"),a)):null)):null}function u(){const[e,t]=(0,l.useState)(!0),[a,s]=(0,l.useState)(!1),[p,u]=(0,l.useState)(!1),[d,m]=(0,l.useState)(!1),[_,w]=(0,l.useState)(!1),[q,g]=(0,l.useState)(null),[h,E]=(0,l.useState)(null),[y,b]=(0,l.useState)(""),[v,A]=(0,l.useState)(""),[C,N]=(0,l.useState)(!1),[O,k]=(0,l.useState)(null),S=(0,l.useCallback)(()=>(t(!0),b(""),Promise.all([o()({path:c}),o()({path:"/forwp-faq/v1/registry"})]).then(([e,t])=>{E(e),g(t)}).catch(e=>{b(e?.message||(0,r.__)("Could not load settings.","4wp-faq"))}).finally(()=>t(!1))),[]);if((0,l.useEffect)(()=>{!function(){if("undefined"==typeof window||!window.forwpFaqAdmin||window.forwpFaqAdmin.__middlewareApplied)return;const{restRoot:e,nonce:t}=window.forwpFaqAdmin,a=e.endsWith("/")?e:`${e}/`;o().use(o().createRootURLMiddleware(a)),o().use(o().createNonceMiddleware(t)),window.forwpFaqAdmin.__middlewareApplied=!0}(),S()},[S]),e)return(0,n.createElement)("div",{className:"forwp-faq-tab-loading"},(0,n.createElement)(i.Spinner,null));const F=q?.setup_complete,P=!0===h?.output_json_ld,Q=h?.preview_per_category||5,L=!0===h?.seo_urls,R=!0===h?.ai_available,D=!0===h?.ai_field_markup;return(0,n.createElement)("div",{className:"forwp-faq-settings-layout"},v?(0,n.createElement)(i.Notice,{status:"success",isDismissible:!0,onRemove:()=>A("")},v):null,y?(0,n.createElement)(i.Notice,{status:"error",isDismissible:!1},y):null,O?(0,n.createElement)(i.Button,{className:"forwp-faq-section-back",variant:"tertiary",onClick:()=>k(null)},(0,r.__)("Overview","4wp-faq")):(0,n.createElement)(n.Fragment,null,(0,n.createElement)(f,{stats:q?.stats,setupComplete:F,lastScan:q?.last_scan_label}),(0,n.createElement)("div",{className:"forwp-faq-overview-grid"},(0,n.createElement)("button",{type:"button",className:"forwp-faq-overview-card",onClick:()=>k("registry")},(0,n.createElement)("span",{className:"forwp-faq-overview-card__title"},(0,r.__)("Registry","4wp-faq")),(0,n.createElement)("span",{className:"forwp-faq-overview-card__summary"},F?q?.last_scan_label?(0,r.sprintf)(/* translators: %s: date/time */ /* translators: %s: date/time */ 3 (0,r.__)("Last scan: %s","4wp-faq"),q.last_scan_label):(0,r.__)("Not scanned yet.","4wp-faq"):(0,r.__)("Setup is not complete.","4wp-faq"))),(0,n.createElement)("button",{type:"button",className:"forwp-faq-overview-card",onClick:()=>k("seo")},(0,n.createElement)("span",{className:"forwp-faq-overview-card__title"},(0,r.__)("SEO","4wp-faq")),(0,n.createElement)("span",{className:"forwp-faq-overview-card__summary"},(0,r.sprintf)(/* translators: 1: on/off, 2: on/off, 3: count */ /* translators: 1: on/off, 2: on/off, 3: count */ 4 (0,r.__)("JSON-LD %1$s · Pretty URLs %2$s · %3$d per group","4wp-faq"),P?(0,r.__)("On","4wp-faq"):(0,r.__)("Off","4wp-faq"),L?(0,r.__)("On","4wp-faq"):(0,r.__)("Off","4wp-faq"),Q))),(0,n.createElement)("button",{type:"button",className:"forwp-faq-overview-card",onClick:()=>k("ai")},(0,n.createElement)("span",{className:"forwp-faq-overview-card__title"},(0,r.__)("AI","4wp-faq")),(0,n.createElement)("span",{className:"forwp-faq-overview-card__summary"},R?D?(0,r.__)("Field markup is on.","4wp-faq"):(0,r.__)("Field markup is off.","4wp-faq"):(0,r.__)("WordPress Connectors are not available.","4wp-faq"))),(0,n.createElement)("button",{type:"button",className:"forwp-faq-overview-card",onClick:()=>k("titles")},(0,n.createElement)("span",{className:"forwp-faq-overview-card__title"},(0,r.__)("Category titles","4wp-faq")),(0,n.createElement)("span",{className:"forwp-faq-overview-card__summary"},(0,r.__)("On-page title, document title, meta description, and image.","4wp-faq"))))),"registry"===O?(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Registry","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("div",{className:"forwp-faq-actions-row"},(0,n.createElement)(i.Button,{variant:"primary",onClick:()=>{s(!0),A(""),b(""),o()({path:"/forwp-faq/v1/registry/scan",method:"POST"}).then(e=>{g(e),A((0,r.__)("Registry scan completed.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Scan failed. Please try again.","4wp-faq"))}).finally(()=>s(!1))},isBusy:a,disabled:a||!F},a?(0,r.__)("Scanning…","4wp-faq"):(0,r.__)("Rescan registry","4wp-faq")),!F&&q?.setup_url?(0,n.createElement)(i.ExternalLink,{href:q.setup_url},(0,r.__)("Complete setup to enable scan","4wp-faq")):null),F&&q?.last_scan_label?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,r.sprintf)(/* translators: %s: date/time */ /* translators: %s: date/time */ 5 (0,r.__)("Last scan: %s","4wp-faq"),q.last_scan_label)):null,F?(0,n.createElement)(n.Fragment,null,(0,n.createElement)("hr",{className:"forwp-faq-actions-divider"}),(0,n.createElement)("p",{className:"forwp-faq-reset-intro"},(0,r.__)("Reset setup to change CPT/taxonomy slugs. Categories are removed.","4wp-faq")),(0,n.createElement)(i.Button,{variant:"secondary",isDestructive:!0,onClick:()=>N(!0)},(0,r.__)("Reset setup","4wp-faq"))):null)):null,"seo"===O?(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("SEO","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("FAQPage JSON-LD","4wp-faq"),help:(0,r.__)("On: schema for questions actually shown. Per-block override still applies.","4wp-faq"),checked:P,disabled:p,onChange:e=>{u(!0),b(""),o()({path:c,method:"POST",data:{output_json_ld:e}}).then(t=>{E(t),A(e?(0,r.__)("JSON-LD enabled site-wide.","4wp-faq"):(0,r.__)("JSON-LD disabled site-wide.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save SEO setting.","4wp-faq"))}).finally(()=>u(!1))}}),(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("Pretty category URLs","4wp-faq"),help:(0,r.__)("Allows /page/term-slug/. Also enable it on the Categories block. Off: in-place filter, URL unchanged.","4wp-faq"),checked:L,disabled:p,onChange:e=>{u(!0),b(""),o()({path:c,method:"POST",data:{seo_urls:e}}).then(t=>{E(t),A(e?(0,r.__)("Pretty category URLs enabled. Turn on SEO-friendly category URLs in the 4WP FAQ Categories block on each hub page.","4wp-faq"):(0,r.__)("Pretty category URLs disabled. Category clicks filter in place and the page URL stays unchanged.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save SEO setting.","4wp-faq"))}).finally(()=>u(!1))}}),(0,n.createElement)(i.RangeControl,{label:(0,r.__)("Questions per group (All view)","4wp-faq"),help:(0,r.__)("Preview count on All categories. Category URLs still list every question.","4wp-faq"),value:Q,onChange:e=>{const t="number"==typeof e?e:5;u(!0),b(""),o()({path:c,method:"POST",data:{preview_per_category:t}}).then(e=>{E(e),A((0,r.__)("Preview count saved.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save setting.","4wp-faq"))}).finally(()=>u(!1))},min:1,max:20,disabled:p}))):null,"ai"===O?(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("AI","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("p",null,(0,r.__)("Uses WordPress Connectors. One prompt fills mapped fields on FAQ category edit. Apply writes into the form; Update still saves.","4wp-faq")),R?null:(0,n.createElement)(i.Notice,{status:"warning",isDismissible:!1},(0,r.__)("WordPress Connectors are not available yet. Configure a text provider, then enable the option below.","4wp-faq"),h?.ai_connectors_url?(0,n.createElement)(n.Fragment,null," ",(0,n.createElement)(i.ExternalLink,{href:h.ai_connectors_url},(0,r.__)("Open Connectors","4wp-faq"))):null),(0,n.createElement)(i.ToggleControl,{label:(0,r.__)("Allow predefined field markup","4wp-faq"),help:R?(0,r.__)("On: show Generate with AI on category screens. Off: keep the panel hidden.","4wp-faq"):(0,r.__)("Turn on after WordPress Connectors support text generation.","4wp-faq"),checked:R&&D,disabled:d||!R,onChange:e=>{m(!0),b(""),o()({path:c,method:"POST",data:{ai_field_markup:e}}).then(t=>{E(t),A(e?(0,r.__)("Predefined field markup enabled. Generate with AI can fill mapped category fields.","4wp-faq"):(0,r.__)("Predefined field markup disabled. The AI panel stays hidden on category screens.","4wp-faq"))}).catch(e=>{b(e?.message||(0,r.__)("Could not save AI setting.","4wp-faq"))}).finally(()=>m(!1))}}),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Description","4wp-faq"))," — ",(0,r.__)("Core category Description.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Display title","4wp-faq"))," — ",(0,r.__)("On-page title on pretty category URLs.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO title","4wp-faq"))," — ",(0,r.__)("Document title. No site name suffix.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO description","4wp-faq"))," — ",(0,r.__)("Meta description on category URLs.","4wp-faq"))),h?.ai_connectors_url?(0,n.createElement)("p",{className:"forwp-faq-actions-card__meta"},(0,n.createElement)(i.ExternalLink,{href:h.ai_connectors_url},(0,r.__)("WordPress Connectors","4wp-faq"))):null)):null,"titles"===O?(0,n.createElement)(i.Card,{className:"forwp-faq-actions-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,(0,r.__)("Category titles","4wp-faq"))),(0,n.createElement)(i.CardBody,null,(0,n.createElement)("p",null,(0,r.__)("On pretty category URLs (/page/term-slug/). Edit fields on each FAQ category.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("On-page title","4wp-faq"))," — ",(0,r.__)("Display title (empty: category name). Put a core Title (post-title), Query Title / Archive title (query-title), or Term Name (term-name). Heading level is the template’s choice. Heading blocks are not swapped.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("On-page description","4wp-faq"))," — ",(0,r.__)("Category Description field. Put a core Excerpt (post-excerpt) or Term Description (term-description). Empty description: WordPress output is left as-is.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Document title","4wp-faq"))," — ",(0,r.__)("SEO title as-is if filled (no site-name suffix). Empty: on-page title + “ – {site name}”.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Meta description","4wp-faq"))," — ",(0,r.__)("SEO description. Empty: hub page default.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("Canonical","4wp-faq"))," — ",(0,r.__)("The category URL (/page/term-slug/), not the hub.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,(0,r.__)("SEO image","4wp-faq"))," — ",(0,r.__)("Open Graph / Twitter image on the category. Empty: hub page image.","4wp-faq"))))):null,C?(0,n.createElement)(i.Modal,{title:(0,r.__)("Reset FAQ setup?","4wp-faq"),onRequestClose:()=>!_&&N(!1),shouldCloseOnClickOutside:!_,shouldCloseOnEsc:!_},(0,n.createElement)("p",null,(0,r.__)("You can choose new registry slugs in the setup wizard, but all FAQ categories will be removed. Registry entries stay on the previous post type until you complete setup and run a new scan.","4wp-faq")),(0,n.createElement)("div",{className:"forwp-faq-modal-actions"},(0,n.createElement)(i.Button,{variant:"secondary",onClick:()=>N(!1),disabled:_},(0,r.__)("Cancel","4wp-faq")),(0,n.createElement)(i.Button,{variant:"primary",isDestructive:!0,isBusy:_,disabled:_,onClick:()=>{w(!0),b(""),o()({path:"/forwp-faq/v1/setup/reset",method:"POST"}).then(e=>{N(!1),e?.redirect&&(window.location.href=e.redirect)}).catch(e=>{b(e?.message||(0,r.__)("Reset failed. Please try again.","4wp-faq")),N(!1)}).finally(()=>w(!1))}},(0,r.__)("Reset setup","4wp-faq")))):null)}function d({title:e,children:t}){return(0,n.createElement)(i.Card,{className:"forwp-faq-doc-card"},(0,n.createElement)(i.CardHeader,null,(0,n.createElement)("h2",null,e)),(0,n.createElement)(i.CardBody,{className:"forwp-faq-doc-card__body"},t))}function m(){return(0,n.createElement)("div",{className:"forwp-faq-docs-layout"},(0,n.createElement)(d,{title:(0,r.__)("Overview","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("4WP FAQ is a thin wrapper around WordPress core Accordion. It does not replace your blocks or theme styles. It adds an intelligence layer: FAQPage JSON-LD on the front end, optional aggregation into a FAQ registry post type, and usage statistics in the admin.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Your questions and answers live in page content (Accordion items). That is the source of truth. The registry is a scan of unique questions. Edit a registry record and Update: the plugin writes the new Q/A onto every Used In page. Add FAQ to place a new item. Delete the registry or reinstall: a scan rebuilds it from the site.","4wp-faq"))),(0,n.createElement)(d,{title:(0,r.__)("Convert to FAQ","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("You can convert an existing Accordion, Accordion Item, Accordion Group, Details, List, or heading + paragraph pairs into a 4WP FAQ block without rebuilding the layout.","4wp-faq")),(0,n.createElement)("ol",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Select a core Accordion, Accordion Item, Accordion Group, Details, or List in the editor. You can select several Details or Accordion Items at once.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("In the block toolbar, click Convert to 4WP FAQ, or use Transform to → 4WP FAQ.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("The plugin wraps your markup in forwp/faq. Inner Accordion or Details blocks and styling stay the same on the front end.","4wp-faq"))),(0,n.createElement)("p",null,(0,r.__)("Each Accordion Item (or legacy Details block) inside the wrapper counts as one FAQ question for JSON-LD and for the registry scan.","4wp-faq"))),(0,n.createElement)(d,{title:(0,r.__)("Block structure","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Recommended pattern (WordPress 6.x core Accordion):","4wp-faq")),(0,n.createElement)("pre",{className:"forwp-faq-doc-pre"},(0,n.createElement)("code",null,"forwp/faq ← 4WP FAQ wrapper\n└── core/accordion ← container\n └── core/accordion-item ← one Q&A\n ├── accordion heading\n └── accordion panel")),(0,n.createElement)("p",null,(0,r.__)("Legacy core/details blocks inside forwp/faq are still supported. Prefer Accordion + Accordion Item for new pages.","4wp-faq"))),(0,n.createElement)(d,{title:(0,r.__)("Blocks for pages","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Use these blocks when building a FAQ hub or in-page FAQs:","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq")," — ",(0,r.__)("Wrapper around core Accordion or Details for JSON-LD and registry scan. Convert / Transform to 4WP FAQ in the editor.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-list")," — ",(0,r.__)("Registry glossary (grouped or flat). Place on a page or template after setup + scan.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-card")," — ",(0,r.__)("Inner template of the List (not in the inserter). Accordion or heading + answer; optional sources.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-categories")," — ",(0,r.__)("Category nav. Include/exclude stay in sync with the List on the same page.","4wp-faq")),(0,n.createElement)("li",null,(0,n.createElement)("strong",null,"forwp/faq-count")," — ",(0,r.__)("Live number for All / current category / current search. Same as [forwp_faq_count].","4wp-faq"))),(0,n.createElement)("pre",{className:"forwp-faq-doc-pre"},(0,n.createElement)("code",null,"forwp/faq-categories ← nav (optional)\nforwp/faq-list ← registry questions\n└── forwp/faq-card\ncore/search ← optional filter\nforwp/faq-count ← optional count"))),(0,n.createElement)(d,{title:(0,r.__)("Core Search block","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("Add a core Search block on the same page as 4WP FAQ List. In the block sidebar open 4WP FAQ and turn on Filter 4WP FAQ List.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Typing filters visible FAQ cards through the Interactivity store. The form does not submit a WordPress search.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("FAQ Count follows the same search query when the filter is on.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Leave the toggle off if the Search should behave as a normal site search.","4wp-faq")))),(0,n.createElement)(d,{title:(0,r.__)("JSON-LD (SEO)","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("On singular posts and pages, the plugin can output FAQPage structured data (JSON-LD) in the document head when FAQ blocks are present.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Site-wide default: Settings → FAQPage JSON-LD (off by default).","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("When enabled site-wide: every forwp/faq block outputs schema unless you set JSON-LD on front end → Off for this block in the block sidebar.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("When disabled site-wide: no schema by default; enable per block with On for this block in the sidebar.","4wp-faq"))),(0,n.createElement)("p",{className:"forwp-faq-doc-muted"},(0,r.__)("JSON-LD does not require the FAQ registry. Blocks and schema work even if you never complete registry setup.","4wp-faq"))),(0,n.createElement)(d,{title:(0,r.__)("FAQ registry (optional)","4wp-faq")},(0,n.createElement)("p",null,(0,r.__)("After you complete setup (Settings → 4WP FAQ Setup), the plugin registers a custom post type and taxonomy (default slugs: faq and faq-category).","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("A scan walks content, finds forwp/faq blocks, and creates or updates registry posts—one per unique question—with usage, categories, and answer snapshots.","4wp-faq")),(0,n.createElement)("ul",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Where the question is used (pages, posts, other types)","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("How many times it appears (reuse count)","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Collected answer text and HTML snapshots","4wp-faq"))),(0,n.createElement)("p",null,(0,r.__)("Edit a registry FAQ (title + answer) and Update. The plugin finds that accordion item on every Used In page. If you change the question, it matches the previous title.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Add FAQ: write the question and answer. FAQ categories in the sidebar append the item to every forwp/faq block with those terms. One page (optional) writes only to that post/page. Neither: the row stays in the list until a scan, then it is dropped because it is not on the site.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("A new answer reuses the wrapper of a sibling accordion item on that page (same heading/panel markup) and fills in your text. After save, that wrapped HTML is stored on the registry record.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Run Rescan after you change FAQ content on pages. Registry Update also writes back to those pages, then a scan is scheduled. Scans also run when relevant posts are saved.","4wp-faq")),(0,n.createElement)("p",null,(0,r.__)("Reset setup (Settings tab) lets you change registry slugs in the wizard again but removes all FAQ categories; existing registry entries stay on the previous post type until you complete setup and scan again.","4wp-faq"))),(0,n.createElement)(d,{title:(0,r.__)("Typical workflow","4wp-faq")},(0,n.createElement)("ol",{className:"forwp-faq-doc-list"},(0,n.createElement)("li",null,(0,r.__)("Add or convert Accordion blocks to forwp/faq on your pages.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Enable JSON-LD on the Settings tab if you want structured data site-wide.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Optional: complete FAQ registry setup and run a scan. Then you can edit a registry FAQ (pushes to Used In pages) or Add FAQ onto category pages / one page.","4wp-faq")),(0,n.createElement)("li",null,(0,r.__)("Review Dashboard stats and open All FAQs under the FAQ admin menu.","4wp-faq")))))}const _=document.getElementById("forwp-faq-admin-root");_&&(0,l.createRoot)(_).render((0,n.createElement)(function(){const[e,t]=(0,l.useState)("settings");return(0,n.createElement)("div",{className:"forwp-faq-admin-app"},(0,n.createElement)("div",{className:"forwp-faq-tab-panel components-tab-panel"},(0,n.createElement)("div",{className:"components-tab-panel__tabs",role:"tablist","aria-label":(0,r.__)("4WP FAQ","4wp-faq")},(0,n.createElement)("button",{type:"button",role:"tab",id:"forwp-faq-tab-settings",className:"components-button components-tab-panel__tabs-item forwp-faq-tab-settings"+("settings"===e?" is-active":""),"aria-selected":"settings"===e,"aria-controls":"forwp-faq-panel-settings",tabIndex:"settings"===e?0:-1,onClick:()=>t("settings")},(0,r.__)("Settings","4wp-faq")),(0,n.createElement)("button",{type:"button",role:"tab",id:"forwp-faq-tab-documentation",className:"components-button components-tab-panel__tabs-item forwp-faq-tab-docs"+("documentation"===e?" is-active":""),"aria-selected":"documentation"===e,"aria-controls":"forwp-faq-panel-documentation",tabIndex:"documentation"===e?0:-1,onClick:()=>t("documentation")},(0,r.__)("Documentation","4wp-faq"))),(0,n.createElement)("div",{id:"forwp-faq-panel-settings",role:"tabpanel","aria-labelledby":"forwp-faq-tab-settings",className:"components-tab-panel__tab-content",hidden:"settings"!==e},(0,n.createElement)(u,null)),(0,n.createElement)("div",{id:"forwp-faq-panel-documentation",role:"tabpanel","aria-labelledby":"forwp-faq-tab-documentation",className:"components-tab-panel__tab-content",hidden:"documentation"!==e},(0,n.createElement)(m,null))))},null))}},a={};function n(e){var l=a[e];if(void 0!==l)return l.exports;var r=a[e]={exports:{}};return t[e](r,r.exports,n),r.exports}n.m=t,e=[],n.O=(t,a,l,r)=>{if(!a){var s=1/0;for(p=0;p<e.length;p++){for(var[a,l,r]=e[p],o=!0,i=0;i<a.length;i++)(!1&r||s>=r)&&Object.keys(n.O).every(e=>n.O[e](a[i]))?a.splice(i--,1):(o=!1,r<s&&(s=r));if(o){e.splice(p--,1);var c=l();void 0!==c&&(t=c)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[a,l,r]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={773:0,641:0};n.O.j=t=>0===e[t];var t=(t,a)=>{var l,r,[s,o,i]=a,c=0;if(s.some(t=>0!==e[t])){for(l in o)n.o(o,l)&&(n.m[l]=o[l]);if(i)var p=i(n)}for(t&&t(a);c<s.length;c++)r=s[c],n.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return n.O(p)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var l=n.O(void 0,[641],()=>n(476));l=n.O(l)})(); -
4wp-faq/trunk/build/admin/style-index-rtl.css
r3698640 r3748403 1 .forwp-faq-admin-shell{max-width:1100px}.forwp-faq-admin-shell h1.forwp-faq-admin-heading{align-items:center;display:flex;font-size:1.6rem;font-weight:600;gap:10px;margin-bottom:.25rem}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon{align-items:center;color:var(--wp-admin-theme-color,#3858e9);display:inline-flex;flex-shrink:0;justify-content:center;line-height:0}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon svg{display:block}.forwp-faq-admin-shell .forwp-faq-admin-heading__text{line-height:1.25}.forwp-faq-admin-root{margin-top:1rem;padding-bottom:2rem}.forwp-faq-admin-app{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);overflow:hidden}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs{align-items:stretch;background:#fafafa;border-bottom:1px solid #e0e0e0;display:flex;flex-wrap:wrap;gap:0;margin:0;padding:0}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item{border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;font-weight:500;height:auto;margin:0!important;min-height:0;padding:10px 14px}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item.is-active{background:#fff;border-color:#e0e0e0 #e0e0e0 #fff;margin-bottom:-1px!important;position:relative;z-index:1}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tab-content{padding:1.25rem 1.5rem 1.5rem}.forwp-faq-tab-loading{display:flex;justify-content:center;padding:2rem}.forwp-faq-intro-card{border:1px solid #e8e8e8;margin-bottom:1rem}.forwp-faq-intro-card__title{font-size:1.05rem;margin:0 0 .5rem}.forwp-faq-intro-card__text{color:#50575e;line-height:1.55;margin:0 0 .75rem}.forwp-faq-intro-card__text:last-child{margin-bottom:0}.forwp-faq-settings-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq- stats-card .forwp-faq-actions-card__meta{margin-top:1rem}.forwp-faq-stats-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.forwp-faq-stat{background:#f6f7f7;border:1px solid #e8e8e8;border-radius:6px;display:flex;flex-direction:column;gap:.2rem;padding:.75rem}.forwp-faq-stat__value{color:#1d2327;font-size:1.5rem;font-weight:600;line-height:1.2}.forwp-faq-stat__label{color:#50575e;font-size:.8rem;line-height:1.35}.forwp-faq-stat__hint{color:#646970;font-size:.72rem}.forwp-faq-actions-card__meta{color:#646970;font-size:.9rem;margin:.35rem 0 0}.forwp-faq-doc-list+.forwp-faq-actions-card__meta{margin-top:.15rem}.forwp-faq-actions-row{align-items:center;display:flex;flex-wrap:wrap;gap:.75rem}.forwp-faq-actions-divider{border:none;border-top:1px solid #e8e8e8;margin:1.25rem 0}.forwp-faq-reset-intro{color:#50575e;margin:0 0 .75rem}.forwp-faq-modal-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1rem}.forwp-faq-registry-layout{max-width:720px}.forwp-faq-registry-card__meta{margin:0 0 .5rem}.forwp-faq-registry-card__meta--muted{color:#646970}.forwp-faq-registry-card__actions{margin-top:1rem}.forwp-faq-docs-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-doc-card__body p{color:#1d2327;line-height:1.55;margin:0 0 .85rem}.forwp-faq-doc-card__body p:last-child{margin-bottom:0}.forwp-faq-doc-card__body strong{font-weight:600}.forwp-faq-doc-list{line-height:1.55;margin:0 1.25rem .85rem 0;padding:0}.forwp-faq-doc-list li{margin-bottom:.35rem}.forwp-faq-doc-pre{background:#f6f7f7;border:1px solid #e0e0e0;border-radius:4px;font-size:12px;line-height:1.45;margin:0 0 .85rem;overflow-x:auto;padding:12px 14px}.forwp-faq-doc-pre code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre}.forwp-faq-doc-muted{color:#646970!important;font-size:.92em}.forwp-faq-guide{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);margin-top:1.25rem;max-width:640px;padding:1.25rem 1.5rem}.forwp-faq-guide__lead{color:#1d2327;font-size:1rem;line-height:1.5;margin:0 0 1rem}.forwp-faq-guide__steps{line-height:1.6;margin:0 1.25rem 1.25rem 0;padding:0}.forwp-faq-guide__steps li{margin-bottom:.5rem}.forwp-faq-guide__steps a{color:var(--wp-admin-theme-color,#3858e9)}.forwp-faq-guide__hub,.forwp-faq-guide__video{color:#50575e;line-height:1.5;margin:0 0 .75rem}.forwp-faq-guide__video{border-top:1px solid #e8e8e8;font-style:italic;margin-bottom:0;padding-top:.75rem}1 .forwp-faq-admin-shell{max-width:1100px}.forwp-faq-admin-shell h1.forwp-faq-admin-heading{align-items:center;display:flex;font-size:1.6rem;font-weight:600;gap:10px;margin-bottom:.25rem}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon{align-items:center;color:var(--wp-admin-theme-color,#3858e9);display:inline-flex;flex-shrink:0;justify-content:center;line-height:0}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon svg{display:block}.forwp-faq-admin-shell .forwp-faq-admin-heading__text{line-height:1.25}.forwp-faq-admin-root{margin-top:1rem;padding-bottom:2rem}.forwp-faq-admin-app{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);overflow:hidden}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs{align-items:stretch;background:#fafafa;border-bottom:1px solid #e0e0e0;display:flex;flex-wrap:wrap;gap:0;margin:0;padding:0}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item{border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;font-weight:500;height:auto;margin:0!important;min-height:0;padding:10px 14px}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item.is-active{background:#fff;border-color:#e0e0e0 #e0e0e0 #fff;margin-bottom:-1px!important;position:relative;z-index:1}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tab-content{padding:1.25rem 1.5rem 1.5rem}.forwp-faq-tab-loading{display:flex;justify-content:center;padding:2rem}.forwp-faq-intro-card{border:1px solid #e8e8e8;margin-bottom:1rem}.forwp-faq-intro-card__title{font-size:1.05rem;margin:0 0 .5rem}.forwp-faq-intro-card__text{color:#50575e;line-height:1.55;margin:0 0 .75rem}.forwp-faq-intro-card__text:last-child{margin-bottom:0}.forwp-faq-settings-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-overview-grid{display:grid;gap:1rem;grid-template-columns:repeat(2,minmax(0,1fr))}.forwp-faq-overview-card{align-items:flex-start;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 2px rgba(0,0,0,.04);color:inherit;cursor:pointer;display:flex;flex-direction:column;font:inherit;gap:.35rem;margin:0;padding:1rem 1.1rem;text-align:right;width:100%}.forwp-faq-overview-card:focus,.forwp-faq-overview-card:hover{border-color:var(--wp-admin-theme-color,#3858e9);box-shadow:0 0 0 1px var(--wp-admin-theme-color,#3858e9);outline:none}.forwp-faq-overview-card__title{color:#1d2327;font-size:1rem;font-weight:600}.forwp-faq-overview-card__summary{color:#50575e;font-size:.85rem;line-height:1.45}.forwp-faq-section-back{align-self:flex-start}@media(max-width:600px){.forwp-faq-overview-grid{grid-template-columns:1fr}}.forwp-faq-stats-card .forwp-faq-actions-card__meta{margin-top:1rem}.forwp-faq-stats-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.forwp-faq-stat{background:#f6f7f7;border:1px solid #e8e8e8;border-radius:6px;display:flex;flex-direction:column;gap:.2rem;padding:.75rem}.forwp-faq-stat__value{color:#1d2327;font-size:1.5rem;font-weight:600;line-height:1.2}.forwp-faq-stat__label{color:#50575e;font-size:.8rem;line-height:1.35}.forwp-faq-stat__hint{color:#646970;font-size:.72rem}.forwp-faq-settings-layout .components-card__body{padding:12px 14px}.forwp-faq-settings-layout .components-card__body>p{margin:0 0 10px}.forwp-faq-settings-layout .components-notice{margin:0 0 14px}.forwp-faq-actions-card__meta{color:#646970;font-size:.9rem;margin:.35rem 0 0}.forwp-faq-doc-list+.forwp-faq-actions-card__meta{margin-top:.15rem}.forwp-faq-actions-row{align-items:center;display:flex;flex-wrap:wrap;gap:.75rem}.forwp-faq-actions-divider{border:none;border-top:1px solid #e8e8e8;margin:1.25rem 0}.forwp-faq-reset-intro{color:#50575e;margin:0 0 .75rem}.forwp-faq-modal-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1rem}.forwp-faq-registry-layout{max-width:720px}.forwp-faq-registry-card__meta{margin:0 0 .5rem}.forwp-faq-registry-card__meta--muted{color:#646970}.forwp-faq-registry-card__actions{margin-top:1rem}.forwp-faq-docs-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-doc-card__body p{color:#1d2327;line-height:1.55;margin:0 0 .85rem}.forwp-faq-doc-card__body p:last-child{margin-bottom:0}.forwp-faq-doc-card__body strong{font-weight:600}.forwp-faq-doc-list{line-height:1.55;margin:0 1.25rem .85rem 0;padding:0}.forwp-faq-doc-list li{margin-bottom:.35rem}.forwp-faq-doc-pre{background:#f6f7f7;border:1px solid #e0e0e0;border-radius:4px;font-size:12px;line-height:1.45;margin:0 0 .85rem;overflow-x:auto;padding:12px 14px}.forwp-faq-doc-pre code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre}.forwp-faq-doc-muted{color:#646970!important;font-size:.92em}.forwp-faq-guide{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);margin-top:1.25rem;max-width:640px;padding:1.25rem 1.5rem}.forwp-faq-guide__lead{color:#1d2327;font-size:1rem;line-height:1.5;margin:0 0 1rem}.forwp-faq-guide__steps{line-height:1.6;margin:0 1.25rem 1.25rem 0;padding:0}.forwp-faq-guide__steps li{margin-bottom:.5rem}.forwp-faq-guide__steps a{color:var(--wp-admin-theme-color,#3858e9)}.forwp-faq-guide__hub,.forwp-faq-guide__video{color:#50575e;line-height:1.5;margin:0 0 .75rem}.forwp-faq-guide__video{border-top:1px solid #e8e8e8;font-style:italic;margin-bottom:0;padding-top:.75rem} -
4wp-faq/trunk/build/admin/style-index.css
r3698640 r3748403 1 .forwp-faq-admin-shell{max-width:1100px}.forwp-faq-admin-shell h1.forwp-faq-admin-heading{align-items:center;display:flex;font-size:1.6rem;font-weight:600;gap:10px;margin-bottom:.25rem}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon{align-items:center;color:var(--wp-admin-theme-color,#3858e9);display:inline-flex;flex-shrink:0;justify-content:center;line-height:0}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon svg{display:block}.forwp-faq-admin-shell .forwp-faq-admin-heading__text{line-height:1.25}.forwp-faq-admin-root{margin-top:1rem;padding-bottom:2rem}.forwp-faq-admin-app{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);overflow:hidden}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs{align-items:stretch;background:#fafafa;border-bottom:1px solid #e0e0e0;display:flex;flex-wrap:wrap;gap:0;margin:0;padding:0}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item{border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;font-weight:500;height:auto;margin:0!important;min-height:0;padding:10px 14px}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item.is-active{background:#fff;border-color:#e0e0e0 #e0e0e0 #fff;margin-bottom:-1px!important;position:relative;z-index:1}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tab-content{padding:1.25rem 1.5rem 1.5rem}.forwp-faq-tab-loading{display:flex;justify-content:center;padding:2rem}.forwp-faq-intro-card{border:1px solid #e8e8e8;margin-bottom:1rem}.forwp-faq-intro-card__title{font-size:1.05rem;margin:0 0 .5rem}.forwp-faq-intro-card__text{color:#50575e;line-height:1.55;margin:0 0 .75rem}.forwp-faq-intro-card__text:last-child{margin-bottom:0}.forwp-faq-settings-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq- stats-card .forwp-faq-actions-card__meta{margin-top:1rem}.forwp-faq-stats-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.forwp-faq-stat{background:#f6f7f7;border:1px solid #e8e8e8;border-radius:6px;display:flex;flex-direction:column;gap:.2rem;padding:.75rem}.forwp-faq-stat__value{color:#1d2327;font-size:1.5rem;font-weight:600;line-height:1.2}.forwp-faq-stat__label{color:#50575e;font-size:.8rem;line-height:1.35}.forwp-faq-stat__hint{color:#646970;font-size:.72rem}.forwp-faq-actions-card__meta{color:#646970;font-size:.9rem;margin:.35rem 0 0}.forwp-faq-doc-list+.forwp-faq-actions-card__meta{margin-top:.15rem}.forwp-faq-actions-row{align-items:center;display:flex;flex-wrap:wrap;gap:.75rem}.forwp-faq-actions-divider{border:none;border-top:1px solid #e8e8e8;margin:1.25rem 0}.forwp-faq-reset-intro{color:#50575e;margin:0 0 .75rem}.forwp-faq-modal-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1rem}.forwp-faq-registry-layout{max-width:720px}.forwp-faq-registry-card__meta{margin:0 0 .5rem}.forwp-faq-registry-card__meta--muted{color:#646970}.forwp-faq-registry-card__actions{margin-top:1rem}.forwp-faq-docs-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-doc-card__body p{color:#1d2327;line-height:1.55;margin:0 0 .85rem}.forwp-faq-doc-card__body p:last-child{margin-bottom:0}.forwp-faq-doc-card__body strong{font-weight:600}.forwp-faq-doc-list{line-height:1.55;margin:0 0 .85rem 1.25rem;padding:0}.forwp-faq-doc-list li{margin-bottom:.35rem}.forwp-faq-doc-pre{background:#f6f7f7;border:1px solid #e0e0e0;border-radius:4px;font-size:12px;line-height:1.45;margin:0 0 .85rem;overflow-x:auto;padding:12px 14px}.forwp-faq-doc-pre code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre}.forwp-faq-doc-muted{color:#646970!important;font-size:.92em}.forwp-faq-guide{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);margin-top:1.25rem;max-width:640px;padding:1.25rem 1.5rem}.forwp-faq-guide__lead{color:#1d2327;font-size:1rem;line-height:1.5;margin:0 0 1rem}.forwp-faq-guide__steps{line-height:1.6;margin:0 0 1.25rem 1.25rem;padding:0}.forwp-faq-guide__steps li{margin-bottom:.5rem}.forwp-faq-guide__steps a{color:var(--wp-admin-theme-color,#3858e9)}.forwp-faq-guide__hub,.forwp-faq-guide__video{color:#50575e;line-height:1.5;margin:0 0 .75rem}.forwp-faq-guide__video{border-top:1px solid #e8e8e8;font-style:italic;margin-bottom:0;padding-top:.75rem}1 .forwp-faq-admin-shell{max-width:1100px}.forwp-faq-admin-shell h1.forwp-faq-admin-heading{align-items:center;display:flex;font-size:1.6rem;font-weight:600;gap:10px;margin-bottom:.25rem}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon{align-items:center;color:var(--wp-admin-theme-color,#3858e9);display:inline-flex;flex-shrink:0;justify-content:center;line-height:0}.forwp-faq-admin-shell .forwp-faq-admin-heading__icon svg{display:block}.forwp-faq-admin-shell .forwp-faq-admin-heading__text{line-height:1.25}.forwp-faq-admin-root{margin-top:1rem;padding-bottom:2rem}.forwp-faq-admin-app{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);overflow:hidden}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs{align-items:stretch;background:#fafafa;border-bottom:1px solid #e0e0e0;display:flex;flex-wrap:wrap;gap:0;margin:0;padding:0}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item{border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;font-weight:500;height:auto;margin:0!important;min-height:0;padding:10px 14px}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tabs button.components-tab-panel__tabs-item.is-active{background:#fff;border-color:#e0e0e0 #e0e0e0 #fff;margin-bottom:-1px!important;position:relative;z-index:1}.forwp-faq-admin-app .forwp-faq-tab-panel .components-tab-panel__tab-content{padding:1.25rem 1.5rem 1.5rem}.forwp-faq-tab-loading{display:flex;justify-content:center;padding:2rem}.forwp-faq-intro-card{border:1px solid #e8e8e8;margin-bottom:1rem}.forwp-faq-intro-card__title{font-size:1.05rem;margin:0 0 .5rem}.forwp-faq-intro-card__text{color:#50575e;line-height:1.55;margin:0 0 .75rem}.forwp-faq-intro-card__text:last-child{margin-bottom:0}.forwp-faq-settings-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-overview-grid{display:grid;gap:1rem;grid-template-columns:repeat(2,minmax(0,1fr))}.forwp-faq-overview-card{align-items:flex-start;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 2px rgba(0,0,0,.04);color:inherit;cursor:pointer;display:flex;flex-direction:column;font:inherit;gap:.35rem;margin:0;padding:1rem 1.1rem;text-align:left;width:100%}.forwp-faq-overview-card:focus,.forwp-faq-overview-card:hover{border-color:var(--wp-admin-theme-color,#3858e9);box-shadow:0 0 0 1px var(--wp-admin-theme-color,#3858e9);outline:none}.forwp-faq-overview-card__title{color:#1d2327;font-size:1rem;font-weight:600}.forwp-faq-overview-card__summary{color:#50575e;font-size:.85rem;line-height:1.45}.forwp-faq-section-back{align-self:flex-start}@media(max-width:600px){.forwp-faq-overview-grid{grid-template-columns:1fr}}.forwp-faq-stats-card .forwp-faq-actions-card__meta{margin-top:1rem}.forwp-faq-stats-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.forwp-faq-stat{background:#f6f7f7;border:1px solid #e8e8e8;border-radius:6px;display:flex;flex-direction:column;gap:.2rem;padding:.75rem}.forwp-faq-stat__value{color:#1d2327;font-size:1.5rem;font-weight:600;line-height:1.2}.forwp-faq-stat__label{color:#50575e;font-size:.8rem;line-height:1.35}.forwp-faq-stat__hint{color:#646970;font-size:.72rem}.forwp-faq-settings-layout .components-card__body{padding:12px 14px}.forwp-faq-settings-layout .components-card__body>p{margin:0 0 10px}.forwp-faq-settings-layout .components-notice{margin:0 0 14px}.forwp-faq-actions-card__meta{color:#646970;font-size:.9rem;margin:.35rem 0 0}.forwp-faq-doc-list+.forwp-faq-actions-card__meta{margin-top:.15rem}.forwp-faq-actions-row{align-items:center;display:flex;flex-wrap:wrap;gap:.75rem}.forwp-faq-actions-divider{border:none;border-top:1px solid #e8e8e8;margin:1.25rem 0}.forwp-faq-reset-intro{color:#50575e;margin:0 0 .75rem}.forwp-faq-modal-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:1rem}.forwp-faq-registry-layout{max-width:720px}.forwp-faq-registry-card__meta{margin:0 0 .5rem}.forwp-faq-registry-card__meta--muted{color:#646970}.forwp-faq-registry-card__actions{margin-top:1rem}.forwp-faq-docs-layout{display:flex;flex-direction:column;gap:1rem;max-width:820px}.forwp-faq-doc-card__body p{color:#1d2327;line-height:1.55;margin:0 0 .85rem}.forwp-faq-doc-card__body p:last-child{margin-bottom:0}.forwp-faq-doc-card__body strong{font-weight:600}.forwp-faq-doc-list{line-height:1.55;margin:0 0 .85rem 1.25rem;padding:0}.forwp-faq-doc-list li{margin-bottom:.35rem}.forwp-faq-doc-pre{background:#f6f7f7;border:1px solid #e0e0e0;border-radius:4px;font-size:12px;line-height:1.45;margin:0 0 .85rem;overflow-x:auto;padding:12px 14px}.forwp-faq-doc-pre code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre}.forwp-faq-doc-muted{color:#646970!important;font-size:.92em}.forwp-faq-guide{background:#fff;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,.06);margin-top:1.25rem;max-width:640px;padding:1.25rem 1.5rem}.forwp-faq-guide__lead{color:#1d2327;font-size:1rem;line-height:1.5;margin:0 0 1rem}.forwp-faq-guide__steps{line-height:1.6;margin:0 0 1.25rem 1.25rem;padding:0}.forwp-faq-guide__steps li{margin-bottom:.5rem}.forwp-faq-guide__steps a{color:var(--wp-admin-theme-color,#3858e9)}.forwp-faq-guide__hub,.forwp-faq-guide__video{color:#50575e;line-height:1.5;margin:0 0 .75rem}.forwp-faq-guide__video{border-top:1px solid #e8e8e8;font-style:italic;margin-bottom:0;padding-top:.75rem} -
4wp-faq/trunk/build/faq-card.asset.php
r3685374 r3748403 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp- data', 'wp-i18n'), 'version' => '070b7332a0d905de6e45');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'eb35a819a118ff7797e1'); -
4wp-faq/trunk/build/faq-card.js
r3685374 r3748403 1 (()=>{"use strict";var e, a={49(){const e=window.React,a=window.wp.blocks,t=window.wp.blockEditor,o=window.wp.components,l=window.wp.i18n,n=window.wp.data,r=e=>{const a=[],t=new Set,o=e=>{if(!e||"object"!=typeof e)return;const o="string"==typeof e.fontFamily?e.fontFamily:"",l="string"==typeof e.slug?e.slug:"",n=o||l;n&&!t.has(n)&&(t.add(n),a.push({name:"string"==typeof e.name&&e.name||l||o,slug:l||n.replace(/[^a-z0-9\-]+/gi,"-").toLowerCase(),fontFamily:o||(l?`var(--wp--preset--font-family--${l})`:"")}))};return Array.isArray(e)?(e.forEach(o),a):(e&&"object"==typeof e&&Object.values(e).forEach(e=>{Array.isArray(e)&&e.forEach(o)}),a)},i=e=>null==e||""===e?"":"number"==typeof e&&Number.isFinite(e)?`${e}px`:String(e),s=e=>{if(null==e||""===e)return"";const a=String(e).trim(),t=a.match(/^var:preset\|color\|([a-z0-9\-]+)$/i);return t?`var(--wp--preset--color--${t[1].toLowerCase()})`:a},p={fontSize:"",fontFamily:"",fontWeight:"",color:""},f={colors:[],gradients:[],disableCustomColors:!1,disableCustomGradients:!0,hasColorsOrGradients:!1};function c({value:a={},onChange:c,title:_,panelId:m,help:u=""}){const{fontSizes:w,fontFamilies:d}=(0,n.useSelect)(e=>{var a,t;const o=e("core/block-editor")?.getSettings?.()||{},l=o.__experimentalFeatures||{},n=null!==(a=null!==(t=l?.typography?.fontFamilies)&&void 0!==t?t:o.fontFamilies)&&void 0!==a?a:null;return{fontSizes:Array.isArray(o.fontSizes)?o.fontSizes:Array.isArray(l?.typography?.fontSizes)?l.typography.fontSizes:void 0,fontFamilies:r(n)}},[]),h=("function"==typeof t.__experimentalUseMultipleOriginColorsAndGradients?(0,t.__experimentalUseMultipleOriginColorsAndGradients)():null)||f,g=a&&"object"==typeof a?a:{},y=g.fontSize||"",q=g.fontFamily||"",b=g.fontWeight||"",v=g.color||"",S=e=>c({...g,...e}),C=()=>!!q,E=()=>!!b;return(0,e.createElement)(e.Fragment,null,u?(0,e.createElement)("p",{className:"forwp-faq-typography-help"},u):null,(0,e.createElement)(o.__experimentalToolsPanel,{label:_,resetAll:()=>c({...p}),panelId:m,hasInnerWrapper:!0},t.__experimentalColorGradientSettingsDropdown?(0,e.createElement)(t.__experimentalColorGradientSettingsDropdown,{__experimentalIsRenderedInSidebar:!0,settings:[{colorValue:v||void 0,label:(0,l.__)("Color","4wp-faq"),onColorChange:e=>S({color:s(e)}),isShownByDefault:!0,resetAllFilter:()=>S({color:""}),hasValue:()=>!!v,onDeselect:()=>S({color:""})}],panelId:m,...h}):null,d.length>0&&t.__experimentalFontFamilyControl?(0,e.createElement)(o.__experimentalToolsPanelItem,{hasValue:C,label:(0,l.__)("Font","4wp-faq"),onDeselect:()=>S({fontFamily:""}),isShownByDefault:!0,panelId:m},(0,e.createElement)(t.__experimentalFontFamilyControl,{fontFamilies:d,value:q,onChange:e=>S({fontFamily:e||""}),size:"__unstable-large",__nextHasNoMarginBottom:!0})):d.length>0?(0,e.createElement)(o.__experimentalToolsPanelItem,{hasValue:C,label:(0,l.__)("Font","4wp-faq"),onDeselect:()=>S({fontFamily:""}),isShownByDefault:!0,panelId:m},(0,e.createElement)(o.SelectControl,{label:(0,l.__)("Font","4wp-faq"),hideLabelFromVision:!0,value:q,options:[{label:(0,l.__)("Default","4wp-faq"),value:""},...d.map(e=>({label:e.name,value:e.fontFamily}))],onChange:e=>S({fontFamily:e||""}),__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0})):null,(0,e.createElement)(o.__experimentalToolsPanelItem,{hasValue:()=>!!y,label:(0,l.__)("Size","4wp-faq"),onDeselect:()=>S({fontSize:""}),isShownByDefault:!0,panelId:m},(0,e.createElement)(t.FontSizePicker,{fontSizes:w,value:y||void 0,onChange:e=>S({fontSize:i(e)}),withReset:!1,size:"__unstable-large",__next40pxDefaultSize:!0})),t.__experimentalFontAppearanceControl?(0,e.createElement)(o.__experimentalToolsPanelItem,{hasValue:E,label:(0,l.__)("Appearance","4wp-faq"),onDeselect:()=>S({fontWeight:""}),isShownByDefault:!0,panelId:m},(0,e.createElement)(t.__experimentalFontAppearanceControl,{value:{fontStyle:"normal",fontWeight:b||void 0},onChange:e=>S({fontWeight:e?.fontWeight?String(e.fontWeight):""}),hasFontStyles:!1,hasFontWeights:!0})):(0,e.createElement)(o.__experimentalToolsPanelItem,{hasValue:E,label:(0,l.__)("Appearance","4wp-faq"),onDeselect:()=>S({fontWeight:""}),isShownByDefault:!0,panelId:m},(0,e.createElement)(o.SelectControl,{label:(0,l.__)("Weight","4wp-faq"),hideLabelFromVision:!0,value:b,options:[{label:(0,l.__)("Default","4wp-faq"),value:""},{label:(0,l.__)("Normal","4wp-faq"),value:"400"},{label:(0,l.__)("Medium","4wp-faq"),value:"500"},{label:(0,l.__)("Semibold","4wp-faq"),value:"600"},{label:(0,l.__)("Bold","4wp-faq"),value:"700"}],onChange:e=>S({fontWeight:e||""}),__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}))))}(0,a.registerBlockType)("forwp/faq-card",{edit:({attributes:a,setAttributes:n})=>{const{displayMode:r="accordion",showSources:i=!1,sourcesLabel:s=(0,l.__)("Used in","4wp-faq"),showPostType:p=!1,questionStyle:f={},answerStyle:_={}}=a,m=(0,t.useBlockProps)({className:`forwp-faq-card-editor is-display-${r}`,style:{...f?.fontSize?{"--forwp-faq-q-size":f.fontSize}:{},...f?.fontFamily?{"--forwp-faq-q-family":f.fontFamily}:{},...f?.fontWeight?{"--forwp-faq-q-weight":f.fontWeight}:{},...f?.color?{"--forwp-faq-q-color":f.color}:{},..._?.fontSize?{"--forwp-faq-a-size":_.fontSize}:{},..._?.fontFamily?{"--forwp-faq-a-family":_.fontFamily}:{},..._?.fontWeight?{"--forwp-faq-a-weight":_.fontWeight}:{},..._?.color?{"--forwp-faq-a-color":_.color}:{}}});return(0,e.createElement)("div",{...m},(0,e.createElement)(t.InspectorControls,null,(0,e.createElement)(o.PanelBody,{title:(0,l.__)("Card","4wp-faq"),initialOpen:!0},(0,e.createElement)(o.RadioControl,{label:(0,l.__)("Display","4wp-faq"),selected:r,options:[{label:(0,l.__)("Accordion","4wp-faq"),value:"accordion"},{label:(0,l.__)("Heading and description","4wp-faq"),value:"heading"}],onChange:e=>n({displayMode:e||"accordion"})}),(0,e.createElement)(o.ToggleControl,{label:(0,l.__)("Show source links","4wp-faq"),checked:!!i,onChange:e=>n({showSources:!!e})}),i?(0,e.createElement)(e.Fragment,null,(0,e.createElement)(o.TextControl,{label:(0,l.__)("Sources label","4wp-faq"),placeholder:(0,l.__)("Used in","4wp-faq"),help:(0,l.__)("Placeholder above the source links. Leave empty to hide the label.","4wp-faq"),value:s,onChange:e=>n({sourcesLabel:e})}),(0,e.createElement)(o.ToggleControl,{label:(0,l.__)("Show CPT type","4wp-faq"),help:(0,l.__)("Show the source post type next to each link.","4wp-faq"),checked:!!p,onChange:e=>n({showPostType:!!e})})):null)),(0,e.createElement)(t.InspectorControls,{group:"styles"},(0,e.createElement)(c,{panelId:"forwp-faq-card-question-style",title:(0,l.__)("Question","4wp-faq"),help:(0,l.__)("Empty values inherit from the theme or parent block.","4wp-faq"),value:f,onChange:e=>n({questionStyle:e})}),(0,e.createElement)(c,{panelId:"forwp-faq-card-answer-style",title:(0,l.__)("Answer","4wp-faq"),help:(0,l.__)("Empty values inherit from the theme or parent block.","4wp-faq"),value:_,onChange:e=>n({answerStyle:e})})),"heading"===r?(0,e.createElement)("div",{className:"forwp-faq-card-editor__heading"},(0,e.createElement)("strong",{className:"forwp-faq-card-editor__question"},(0,l.__)("Question","4wp-faq")),(0,e.createElement)("p",{className:"forwp-faq-card-editor__answer"},(0,l.__)("Answer","4wp-faq"))):(0,e.createElement)("details",{className:"forwp-faq-card-editor__details",open:!0},(0,e.createElement)("summary",{className:"forwp-faq-card-editor__question"},(0,l.__)("Question","4wp-faq")),(0,e.createElement)("p",{className:"forwp-faq-card-editor__answer"},(0,l.__)("Answer","4wp-faq"))),i?(0,e.createElement)("p",{className:"forwp-faq-card-editor__sources"},s,p?(s?" · ":"")+(0,l.__)("CPT type","4wp-faq"):""):null)},save:()=>null})}},t={};function o(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return a[e](n,n.exports,o),n.exports}o.m=a,e=[],o.O=(a,t,l,n)=>{if(!t){var r=1/0;for(f=0;f<e.length;f++){for(var[t,l,n]=e[f],i=!0,s=0;s<t.length;s++)(!1&n||r>=n)&&Object.keys(o.O).every(e=>o.O[e](t[s]))?t.splice(s--,1):(i=!1,n<r&&(r=n));if(i){e.splice(f--,1);var p=l();void 0!==p&&(a=p)}}return a}n=n||0;for(var f=e.length;f>0&&e[f-1][2]>n;f--)e[f]=e[f-1];e[f]=[t,l,n]},o.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),(()=>{var e={296:0,289:0};o.O.j=a=>0===e[a];var a=(a,t)=>{var l,n,[r,i,s]=t,p=0;if(r.some(a=>0!==e[a])){for(l in i)o.o(i,l)&&(o.m[l]=i[l]);if(s)var f=s(o)}for(a&&a(t);p<r.length;p++)n=r[p],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(f)},t=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];t.forEach(a.bind(null,0)),t.push=a.bind(null,t.push.bind(t))})();var l=o.O(void 0,[289],()=>o(49));l=o.O(l)})();1 (()=>{"use strict";var e,t={532(){const e=window.React,t=window.wp.blocks,a=window.wp.blockEditor,o=window.wp.components,n=window.wp.i18n,l=window.wp.compose,r=window.wp.data,i=window.wp.element,s={},c={popoverProps:{placement:"left-start",offset:259}},p=e=>{const t=[],a=new Set,o=e=>{if(!e||"object"!=typeof e)return;const o="string"==typeof e.fontFamily?e.fontFamily:"",n="string"==typeof e.slug?e.slug:"",l=o||n;l&&!a.has(l)&&(a.add(l),t.push({name:"string"==typeof e.name&&e.name||n||o,slug:n||l.replace(/[^a-z0-9\-]+/gi,"-").toLowerCase(),fontFamily:o||(n?`var(--wp--preset--font-family--${n})`:"")}))};return Array.isArray(e)?(e.forEach(o),t):(e&&"object"==typeof e&&Object.values(e).forEach(e=>{Array.isArray(e)&&e.forEach(o)}),t)},f=e=>null==e||""===e?"":"number"==typeof e&&Number.isFinite(e)?`${e}px`:String(e),m=e=>{if(null==e||""===e)return"";const t=String(e).trim(),a=t.match(/^var:preset\|color\|([a-z0-9\-]+)$/i);return a?`var(--wp--preset--color--${a[1].toLowerCase()})`:t},_={color:"",fontFamily:"",fontSize:"",fontStyle:"",fontWeight:"",lineHeight:"",letterSpacing:"",textDecoration:"",textTransform:""},u={fontSize:"size",fontFamily:"family",fontWeight:"weight",fontStyle:"style",lineHeight:"line",letterSpacing:"spacing",textDecoration:"decoration",textTransform:"transform",color:"color"},d=(e,t)=>{const a={};return t&&"object"==typeof t?(Object.entries(u).forEach(([o,n])=>{t[o]&&(a[`--forwp-faq-${e}-${n}`]=t[o])}),a):a},h={colors:[],gradients:[],disableCustomColors:!1,disableCustomGradients:!0,hasColorsOrGradients:!1};function w({value:t={},onChange:u,title:d,panelId:w}){const{fontSizes:g,fontFamilies:y}=(0,r.useSelect)(e=>{var t,a;const o=e("core/block-editor")?.getSettings?.()||{},n=o.__experimentalFeatures||{},l=null!==(t=null!==(a=n?.typography?.fontFamilies)&&void 0!==a?a:o.fontFamilies)&&void 0!==t?t:null;return{fontSizes:Array.isArray(o.fontSizes)?o.fontSizes:Array.isArray(n?.typography?.fontSizes)?n.typography.fontSizes:void 0,fontFamilies:p(l)}},[]),S=(()=>{const e=(0,l.useViewportMatch)("medium","<");return(0,i.useMemo)(()=>e?s:c,[e])})(),v=("function"==typeof a.__experimentalUseMultipleOriginColorsAndGradients?(0,a.__experimentalUseMultipleOriginColorsAndGradients)():null)||h,b=t&&"object"==typeof t?t:{},q=e=>u({...b,...e}),C=e=>()=>!!b[e],E=(...e)=>()=>q(Object.fromEntries(e.map(e=>[e,""])));return(0,e.createElement)(o.__experimentalToolsPanel,{label:d,resetAll:()=>u({..._}),panelId:w,__experimentalFirstVisibleItemClass:"first",dropdownMenuProps:S},(0,e.createElement)(a.__experimentalColorGradientSettingsDropdown,{__experimentalIsRenderedInSidebar:!0,settings:[{colorValue:b.color||void 0,label:(0,n.__)("Color","4wp-faq"),onColorChange:e=>q({color:m(e)}),isShownByDefault:!0,resetAllFilter:()=>q({color:""}),hasValue:C("color"),onDeselect:E("color")}],panelId:w,...v}),y.length>0?(0,e.createElement)(o.__experimentalToolsPanelItem,{label:(0,n.__)("Font","4wp-faq"),hasValue:C("fontFamily"),onDeselect:E("fontFamily"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.__experimentalFontFamilyControl,{fontFamilies:y,value:b.fontFamily||"",onChange:e=>q({fontFamily:e||""})})):null,(0,e.createElement)(o.__experimentalToolsPanelItem,{label:(0,n.__)("Size","4wp-faq"),hasValue:C("fontSize"),onDeselect:E("fontSize"),isShownByDefault:!0,panelId:w},(0,e.createElement)(o.FontSizePicker,{fontSizes:g,value:b.fontSize||void 0,onChange:e=>q({fontSize:f(e)}),withReset:!1,withSlider:!0})),(0,e.createElement)(o.__experimentalToolsPanelItem,{label:(0,n.__)("Appearance","4wp-faq"),hasValue:()=>!!b.fontWeight||!!b.fontStyle,onDeselect:E("fontWeight","fontStyle"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.__experimentalFontAppearanceControl,{value:{fontStyle:b.fontStyle||void 0,fontWeight:b.fontWeight||void 0},onChange:e=>q({fontStyle:e?.fontStyle?String(e.fontStyle):"",fontWeight:e?.fontWeight?String(e.fontWeight):""}),hasFontStyles:!0,hasFontWeights:!0})),(0,e.createElement)(o.__experimentalToolsPanelItem,{className:"single-column",label:(0,n.__)("Line height","4wp-faq"),hasValue:C("lineHeight"),onDeselect:E("lineHeight"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.LineHeightControl,{__unstableInputWidth:"auto",value:b.lineHeight||void 0,onChange:e=>q({lineHeight:e?String(e):""})})),(0,e.createElement)(o.__experimentalToolsPanelItem,{className:"single-column",label:(0,n.__)("Letter spacing","4wp-faq"),hasValue:C("letterSpacing"),onDeselect:E("letterSpacing"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.__experimentalLetterSpacingControl,{__unstableInputWidth:"auto",value:b.letterSpacing||void 0,onChange:e=>q({letterSpacing:e||""})})),(0,e.createElement)(o.__experimentalToolsPanelItem,{label:(0,n.__)("Decoration","4wp-faq"),hasValue:C("textDecoration"),onDeselect:E("textDecoration"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.__experimentalTextDecorationControl,{value:b.textDecoration||void 0,onChange:e=>q({textDecoration:e||""})})),(0,e.createElement)(o.__experimentalToolsPanelItem,{label:(0,n.__)("Letter case","4wp-faq"),hasValue:C("textTransform"),onDeselect:E("textTransform"),isShownByDefault:!0,panelId:w},(0,e.createElement)(a.__experimentalTextTransformControl,{value:b.textTransform||void 0,onChange:e=>q({textTransform:e||""})})))}(0,t.registerBlockType)("forwp/faq-card",{edit:({attributes:t,setAttributes:l})=>{const{displayMode:r="accordion",showSources:i=!1,sourcesLabel:s=(0,n.__)("Used in","4wp-faq"),sourcesSeparator:c=", ",showPostType:p=!1,questionStyle:f={},answerStyle:m={}}=t,_=(0,a.useBlockProps)({className:`forwp-faq-card-editor is-display-${r}`,style:{...d("q",f),...d("a",m)}});return(0,e.createElement)("div",{..._},(0,e.createElement)(a.InspectorControls,null,(0,e.createElement)(o.PanelBody,{title:(0,n.__)("Card","4wp-faq"),initialOpen:!0},(0,e.createElement)(o.RadioControl,{label:(0,n.__)("Display","4wp-faq"),selected:r,options:[{label:(0,n.__)("Accordion","4wp-faq"),value:"accordion"},{label:(0,n.__)("Heading and description","4wp-faq"),value:"heading"}],onChange:e=>l({displayMode:e||"accordion"})}),(0,e.createElement)(o.ToggleControl,{label:(0,n.__)("Show source links","4wp-faq"),checked:!!i,onChange:e=>l({showSources:!!e})}),i?(0,e.createElement)(e.Fragment,null,(0,e.createElement)(o.TextControl,{label:(0,n.__)("Sources label","4wp-faq"),placeholder:(0,n.__)("Used in","4wp-faq"),help:(0,n.__)("Placeholder above the source links. Leave empty to hide the label.","4wp-faq"),value:s,onChange:e=>l({sourcesLabel:e})}),(0,e.createElement)(o.TextControl,{label:(0,n.__)("Separator","4wp-faq"),help:(0,n.__)("Enter character(s) used to separate source links.","4wp-faq"),value:c,onChange:e=>l({sourcesSeparator:e})}),(0,e.createElement)(o.ToggleControl,{label:(0,n.__)("Show CPT type","4wp-faq"),help:(0,n.__)("Show the source post type next to each link.","4wp-faq"),checked:!!p,onChange:e=>l({showPostType:!!e})})):null)),(0,e.createElement)(a.InspectorControls,{group:"styles"},(0,e.createElement)(w,{panelId:"forwp-faq-card-question-style",title:(0,n.__)("Question","4wp-faq"),value:f,onChange:e=>l({questionStyle:e})}),(0,e.createElement)(w,{panelId:"forwp-faq-card-answer-style",title:(0,n.__)("Answer","4wp-faq"),value:m,onChange:e=>l({answerStyle:e})})),"heading"===r?(0,e.createElement)("div",{className:"forwp-faq-card-editor__heading"},(0,e.createElement)("strong",{className:"forwp-faq-card-editor__question"},(0,n.__)("Question","4wp-faq")),(0,e.createElement)("p",{className:"forwp-faq-card-editor__answer"},(0,n.__)("Answer","4wp-faq"))):(0,e.createElement)("details",{className:"forwp-faq-card-editor__details",open:!0},(0,e.createElement)("summary",{className:"forwp-faq-card-editor__question"},(0,n.__)("Question","4wp-faq")),(0,e.createElement)("p",{className:"forwp-faq-card-editor__answer"},(0,n.__)("Answer","4wp-faq"))),i?(0,e.createElement)("p",{className:"forwp-faq-card-editor__sources"},s?`${s}: `:"",[(0,n.__)("Page","4wp-faq"),(0,n.__)("Post","4wp-faq")].map(e=>p?`${e} (${(0,n.__)("CPT type","4wp-faq")})`:e).join(c)):null)},save:()=>null})}},a={};function o(e){var n=a[e];if(void 0!==n)return n.exports;var l=a[e]={exports:{}};return t[e](l,l.exports,o),l.exports}o.m=t,e=[],o.O=(t,a,n,l)=>{if(!a){var r=1/0;for(p=0;p<e.length;p++){for(var[a,n,l]=e[p],i=!0,s=0;s<a.length;s++)(!1&l||r>=l)&&Object.keys(o.O).every(e=>o.O[e](a[s]))?a.splice(s--,1):(i=!1,l<r&&(r=l));if(i){e.splice(p--,1);var c=n();void 0!==c&&(t=c)}}return t}l=l||0;for(var p=e.length;p>0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[a,n,l]},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={296:0,289:0};o.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[r,i,s]=a,c=0;if(r.some(t=>0!==e[t])){for(n in i)o.o(i,n)&&(o.m[n]=i[n]);if(s)var p=s(o)}for(t&&t(a);c<r.length;c++)l=r[c],o.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return o.O(p)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var n=o.O(void 0,[289],()=>o(532));n=o.O(n)})(); -
4wp-faq/trunk/build/faq-categories.asset.php
r3691205 r3748403 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp- data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '1557c7631ebb76b5d5d1');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '0f4acf9458cbc2f67151'); -
4wp-faq/trunk/build/faq-categories.js
r3691205 r3748403 1 (()=>{"use strict";var e,t={ 884(e,t,a){const r=window.React,l=window.wp.blocks,n=window.wp.blockEditor,o=window.wp.components,i=window.wp.element,s=window.wp.i18n,c=window.wp.apiFetch;var d=a.n(c);const p=window.wp.serverSideRender;var u=a.n(p);const f=window.wp.data,g=["forwp/faq-list","forwp/faq-categories"],h=(e,t=[])=>((e||[]).forEach(e=>{g.includes(e.name)&&t.push(e),e.innerBlocks&&e.innerBlocks.length&&h(e.innerBlocks,t)}),t),m=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0).sort((e,t)=>e-t).join(","),w=()=>"undefined"!=typeof window&&window.forwpFaqDisplay?window.forwpFaqDisplay:{},_=(e,t)=>(e||[]).map(e=>t.find(t=>t.id===e)?.name).filter(Boolean),b=(e,t)=>(e||[]).map(e=>t.find(t=>t.name===e)?.id).filter(Boolean);(0,l.registerBlockType)("forwp/faq-categories",{edit:({attributes:e,setAttributes:t,clientId:a})=>{const{orientation:l="vertical",label:c=(0,s.__)("Categories","4wp-faq"),showAll:p=!0,allLabel:g=(0,s.__)("All categories","4wp-faq"),showCount:v=!0,collapseChildren:y=!0,seoUrls:E=!1,includeTermIds:q=[],excludeTermIds:T=[]}=e,{terms:C,loading:k,registryReady:I}=(()=>{const[e,t]=(0,i.useState)([]),[a,r]=(0,i.useState)(!1),l=w(),n=!!l.registrySetupComplete,o=l.categoriesPath||"/forwp-faq/v1/editor/categories";return(0,i.useEffect)(()=>{if(!n)return void t([]);let e=!1;return r(!0),d()({path:o}).then(a=>{e||t(Array.isArray(a?.terms)?a.terms:[])}).catch(()=>{e||t([])}).finally(()=>{e||r(!1)}),()=>{e=!0}},[n,o]),{terms:e,loading:a,registryReady:n}})();((e,t,a)=>{const{updateBlockAttributes:r}=(0,f.useDispatch)("core/block-editor"),l=(0,f.useSelect)(t=>h(t("core/block-editor").getBlocks()).filter(t=>t.clientId!==e).map(e=>`${e.clientId}:${m(e.attributes?.includeTermIds)}:${m(e.attributes?.excludeTermIds)}`).join("|"),[e]),n=(0,i.useRef)(!1);(0,i.useEffect)(()=>{const l=(e=>h((0,f.select)("core/block-editor").getBlocks()).filter(t=>t.clientId!==e))(e);if(!n.current){n.current=!0;const o=l.find(e=>(e.attributes?.includeTermIds||[]).length>0||(e.attributes?.excludeTermIds||[]).length>0),i=0===(t||[]).length&&0===(a||[]).length;return void(o&&i&&r(e,{includeTermIds:o.attributes.includeTermIds||[],excludeTermIds:o.attributes.excludeTermIds||[]}))}const o=t||[],i=a||[];l.forEach(e=>{m(e.attributes?.includeTermIds)===m(o)&&m(e.attributes?.excludeTermIds)===m(i)||r(e.clientId,{includeTermIds:o,excludeTermIds:i})})},[e,t,a,l,r])})(a,q,T);const x=(0,i.useMemo)(()=>C.map(e=>e.name),[C]),O=(0,n.useBlockProps)({className:"forwp-faq-categories-editor"});return(0,r.createElement)("div",{...O},(0,r.createElement)(n.InspectorControls,null,(0,r.createElement)(o.PanelBody,{title:(0,s.__)("Navigation","4wp-faq"),initialOpen:!0},(0,r.createElement)(o.RadioControl,{label:(0,s.__)("Orientation","4wp-faq"),selected:l,options:[{label:(0,s.__)("Vertical","4wp-faq"),value:"vertical"},{label:(0,s.__)("Horizontal","4wp-faq"),value:"horizontal"}],onChange:e=>t({orientation:e||"vertical"})}),(0,r.createElement)(o.TextControl,{label:(0,s.__)("Label","4wp-faq"),value:c,onChange:e=>t({label:e||""})}),(0,r.createElement)(o.ToggleControl,{label:(0,s.__)("Show “All categories”","4wp-faq"),help:(0,s.__)("Shows the full list using the same category filters as 4WP FAQ List.","4wp-faq"),checked:!!p,onChange:e=>t({showAll:!!e})}),p?(0,r.createElement)(o.TextControl,{label:(0,s.__)("All categories label","4wp-faq"),value:g,onChange:e=>t({allLabel:e||""})}):null,(0,r.createElement)(o.ToggleControl,{label:(0,s.__)("Show counts","4wp-faq"),checked:!!v,onChange:e=>t({showCount:!!e})}),(0,r.createElement)(o.ToggleControl,{label:(0,s.__)("Collapse subcategories","4wp-faq"),help:(0,s.__)("Parents start closed. Visitors can expand them; the browser remembers their choice. The branch for the current category stays open.","4wp-faq"),checked:!1!==y,onChange:e=>t({collapseChildren:!!e})})),(0,r.createElement)(o.PanelBody,{title:(0,s.__)("Categories","4wp-faq"),initialOpen:!0},I?k?(0,r.createElement)(o.Spinner,null):(0,r.createElement)(r.Fragment,null,(0,r.createElement)(o.FormTokenField,{label:(0,s.__)("Include categories","4wp-faq"),value:_(q,C),suggestions:x,onChange:e=>t({includeTermIds:b(e,C)}),__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),(0,r.createElement)("p",{className:"forwp-faq-categories-editor__help"},(0,s.__)("Shared with 4WP FAQ List on this page. Leave empty to include all categories.","4wp-faq")),(0,r.createElement)(o.FormTokenField,{label:(0,s.__)("Exclude categories","4wp-faq"),value:_(T,C),suggestions:x,onChange:e=>t({excludeTermIds:b(e,C)}),__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0})):(0,r.createElement)(o.Notice,{status:"warning",isDismissible:!1},(0,s.__)("Complete FAQ registry setup to filter by category.","4wp-faq"))),(0,r.createElement)(o.PanelBody,{title:(0,s.__)("SEO","4wp-faq"),initialOpen:!1},w().seoUrlsEnabled?null:(0,r.createElement)(o.Notice,{status:"warning",isDismissible:!1},(0,s.__)("Pretty category URLs are off in 4WP FAQ Settings. Turn them on there first, then enable this toggle. Until then, clicks filter the list in place and the page URL stays unchanged.","4wp-faq")),(0,r.createElement)(o.ToggleControl,{label:(0,s.__)("SEO-friendly category URLs","4wp-faq"),help:(0,s.__)("Adds /term-slug/ after this page when Settings → SEO: pretty category URLs is also on. That URL uses the category Display title as H1 and the category SEO title/description as document meta. Off here: filter in place, URL unchanged.","4wp-faq"),checked:!!E,onChange:e=>t({seoUrls:!!e})}))),(0,r.createElement)(o.Disabled,null,(0,r.createElement)(u(),{block:"forwp/faq-categories",attributes:e})))},save:()=>null})}},a={};function r(e){var l=a[e];if(void 0!==l)return l.exports;var n=a[e]={exports:{}};return t[e](n,n.exports,r),n.exports}r.m=t,e=[],r.O=(t,a,l,n)=>{if(!a){var o=1/0;for(d=0;d<e.length;d++){for(var[a,l,n]=e[d],i=!0,s=0;s<a.length;s++)(!1&n||o>=n)&&Object.keys(r.O).every(e=>r.O[e](a[s]))?a.splice(s--,1):(i=!1,n<o&&(o=n));if(i){e.splice(d--,1);var c=l();void 0!==c&&(t=c)}}return t}n=n||0;for(var d=e.length;d>0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[a,l,n]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={30:0,715:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var l,n,[o,i,s]=a,c=0;if(o.some(t=>0!==e[t])){for(l in i)r.o(i,l)&&(r.m[l]=i[l]);if(s)var d=s(r)}for(t&&t(a);c<o.length;c++)n=o[c],r.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return r.O(d)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var l=r.O(void 0,[715],()=>r(884));l=r.O(l)})();1 (()=>{"use strict";var e,t={382(e,t,a){const r=window.React,l=window.wp.blocks,n=window.wp.blockEditor,o=window.wp.components,i=window.wp.data,s=window.wp.element,c=window.wp.i18n,p=window.wp.apiFetch;var u=a.n(p);const d=window.wp.serverSideRender;var f=a.n(d);const m=["forwp/faq-list","forwp/faq-categories"],g=(e,t=[])=>((e||[]).forEach(e=>{m.includes(e.name)&&t.push(e),e.innerBlocks&&e.innerBlocks.length&&g(e.innerBlocks,t)}),t),w=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0).sort((e,t)=>e-t).join(","),h=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0),_=(e,t,a,r)=>{const l=w(e),n=(0,s.useMemo)(()=>((e,t)=>(e||[]).map(e=>{const a=Number(e);return t.find(e=>Number(e.id)===a)?.name}).filter(Boolean))(e,t),[l,t]),o=(0,s.useCallback)(e=>{const n=((e,t)=>(e||[]).map(e=>t.find(t=>t.name===e)?.id).map(e=>Number(e)).filter(e=>e>0))(e,t);w(n)!==l&&a({[r]:n})},[r,a,t,l]);return{value:n,onChange:o}},b=window.wp.compose,y={},v={popoverProps:{placement:"left-start",offset:259}},S=e=>{const t=[],a=new Set,r=e=>{if(!e||"object"!=typeof e)return;const r="string"==typeof e.fontFamily?e.fontFamily:"",l="string"==typeof e.slug?e.slug:"",n=r||l;n&&!a.has(n)&&(a.add(n),t.push({name:"string"==typeof e.name&&e.name||l||r,slug:l||n.replace(/[^a-z0-9\-]+/gi,"-").toLowerCase(),fontFamily:r||(l?`var(--wp--preset--font-family--${l})`:"")}))};return Array.isArray(e)?(e.forEach(r),t):(e&&"object"==typeof e&&Object.values(e).forEach(e=>{Array.isArray(e)&&e.forEach(r)}),t)},E=e=>null==e||""===e?"":"number"==typeof e&&Number.isFinite(e)?`${e}px`:String(e),q=()=>"undefined"!=typeof window&&window.forwpFaqDisplay?window.forwpFaqDisplay:{};(0,l.registerBlockType)("forwp/faq-categories",{edit:({attributes:e,setAttributes:t,clientId:a})=>{const{orientation:l="vertical",label:p=(0,c.__)("Categories","4wp-faq"),showAll:d=!0,allLabel:m=(0,c.__)("All categories","4wp-faq"),showCount:C=!0,collapseChildren:I=!0,seoUrls:F=!1,includeTermIds:T=[],excludeTermIds:x=[],allItemFontSize:k="",itemFontSize:z="",itemGap:A=""}=e,{terms:O,loading:P,registryReady:B}=(()=>{const[e,t]=(0,s.useState)([]),[a,r]=(0,s.useState)(!1),l=q(),n=!!l.registrySetupComplete,o=l.categoriesPath||"/forwp-faq/v1/editor/categories",c=(0,i.useSelect)(e=>e("core/editor")?.getCurrentPostId?.(),[]),p="number"==typeof c&&c>0?`?post_id=${c}`:"";return(0,s.useEffect)(()=>{if(!n)return void t([]);let e=!1;return r(!0),u()({path:`${o}${p}`}).then(a=>{e||t(Array.isArray(a?.terms)?a.terms:[])}).catch(()=>{e||t([])}).finally(()=>{e||r(!1)}),()=>{e=!0}},[n,o,p]),{terms:e,loading:a,registryReady:n}})(),{fontSizes:R}=(0,i.useSelect)(e=>{var t,a;const r=e("core/block-editor")?.getSettings?.()||{},l=r.__experimentalFeatures||{},n=null!==(t=null!==(a=l?.typography?.fontFamilies)&&void 0!==a?a:r.fontFamilies)&&void 0!==t?t:null;return{fontSizes:Array.isArray(r.fontSizes)?r.fontSizes:Array.isArray(l?.typography?.fontSizes)?l.typography.fontSizes:void 0,fontFamilies:S(n)}},[]),D=(()=>{const e=(0,b.useViewportMatch)("medium","<");return(0,s.useMemo)(()=>e?y:v,[e])})();((e,t,a)=>{const{updateBlockAttributes:r}=(0,i.useDispatch)("core/block-editor"),l=w(t),n=w(a),o=`${l}|${n}`,c=(0,s.useRef)(""),p=(0,s.useRef)(!1),u=(0,i.useSelect)(t=>g(t("core/block-editor").getBlocks()).filter(t=>t.clientId!==e).map(e=>`${w(e.attributes?.includeTermIds)}:${w(e.attributes?.excludeTermIds)}`).join("|"),[e]);(0,s.useEffect)(()=>{const s=(e=>g((0,i.select)("core/block-editor").getBlocks()).filter(t=>t.clientId!==e))(e),u=h(t),d=h(a);if(!p.current){p.current=!0;const t=s.find(e=>(e.attributes?.includeTermIds||[]).length>0||(e.attributes?.excludeTermIds||[]).length>0);if(t&&!l&&!n){const a=h(t.attributes.includeTermIds),l=h(t.attributes.excludeTermIds);return c.current=`${w(a)}|${w(l)}`,void r(e,{includeTermIds:a,excludeTermIds:l})}return void(c.current=o)}c.current!==o&&(c.current=o,s.forEach(e=>{w(e.attributes?.includeTermIds)===l&&w(e.attributes?.excludeTermIds)===n||r(e.clientId,{includeTermIds:u,excludeTermIds:d})}))},[e,l,n,o,u,r])})(a,T,x);const N=_(T,O,t,"includeTermIds"),L=_(x,O,t,"excludeTermIds"),$=(0,s.useMemo)(()=>O.map(e=>e.name),[O]),M=(0,n.useBlockProps)({className:"forwp-faq-categories-editor"});return(0,r.createElement)("div",{...M},(0,r.createElement)(n.InspectorControls,null,(0,r.createElement)(o.PanelBody,{title:(0,c.__)("Navigation","4wp-faq"),initialOpen:!0},(0,r.createElement)(o.RadioControl,{label:(0,c.__)("Orientation","4wp-faq"),selected:l,options:[{label:(0,c.__)("Vertical","4wp-faq"),value:"vertical"},{label:(0,c.__)("Horizontal","4wp-faq"),value:"horizontal"}],onChange:e=>t({orientation:e||"vertical"})}),(0,r.createElement)(o.TextControl,{label:(0,c.__)("Label","4wp-faq"),value:p,onChange:e=>t({label:e||""})}),(0,r.createElement)(o.ToggleControl,{label:(0,c.__)("Show “All categories”","4wp-faq"),help:(0,c.__)("Shows the full list using the same category filters as 4WP FAQ List.","4wp-faq"),checked:!!d,onChange:e=>t({showAll:!!e})}),d?(0,r.createElement)(o.TextControl,{label:(0,c.__)("All categories label","4wp-faq"),value:m,onChange:e=>t({allLabel:e||""})}):null,(0,r.createElement)(o.ToggleControl,{label:(0,c.__)("Show counts","4wp-faq"),checked:!!C,onChange:e=>t({showCount:!!e})}),(0,r.createElement)(o.ToggleControl,{label:(0,c.__)("Collapse subcategories","4wp-faq"),help:(0,c.__)("Parents start closed. Visitors can expand them; the browser remembers their choice. The branch for the current category stays open.","4wp-faq"),checked:!1!==I,onChange:e=>t({collapseChildren:!!e})})),(0,r.createElement)(o.PanelBody,{title:(0,c.__)("Categories","4wp-faq"),initialOpen:!0},B?P?(0,r.createElement)(o.Spinner,null):(0,r.createElement)(r.Fragment,null,(0,r.createElement)(o.FormTokenField,{label:(0,c.__)("Include categories","4wp-faq"),value:N.value,suggestions:$,onChange:N.onChange,__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),(0,r.createElement)("p",{className:"forwp-faq-categories-editor__help"},(0,c.__)("Shared with 4WP FAQ List on this page. Leave empty to include all categories.","4wp-faq")),(0,r.createElement)(o.FormTokenField,{label:(0,c.__)("Exclude categories","4wp-faq"),value:L.value,suggestions:$,onChange:L.onChange,__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0})):(0,r.createElement)(o.Notice,{status:"warning",isDismissible:!1},(0,c.__)("Complete FAQ registry setup to filter by category.","4wp-faq"))),(0,r.createElement)(o.PanelBody,{title:(0,c.__)("SEO","4wp-faq"),initialOpen:!1},q().seoUrlsEnabled?null:(0,r.createElement)(o.Notice,{status:"warning",isDismissible:!1},(0,c.__)("Pretty category URLs are off in 4WP FAQ Settings. Turn them on there first, then enable this toggle. Until then, clicks filter the list in place and the page URL stays unchanged.","4wp-faq")),(0,r.createElement)(o.ToggleControl,{label:(0,c.__)("SEO-friendly category URLs","4wp-faq"),help:(0,c.__)("Adds /term-slug/ after this page when Settings → SEO: pretty category URLs is also on. That URL uses the category Display title as H1 and the category SEO title/description as document meta. Off here: filter in place, URL unchanged.","4wp-faq"),checked:!!F,onChange:e=>t({seoUrls:!!e})}))),(0,r.createElement)(n.InspectorControls,{group:"styles"},(0,r.createElement)(o.__experimentalToolsPanel,{label:(0,c.__)("Sizes","4wp-faq"),panelId:"forwp-faq-categories-sizes",__experimentalFirstVisibleItemClass:"first",dropdownMenuProps:D,resetAll:()=>t({allItemFontSize:"",itemFontSize:"",itemGap:""})},(0,r.createElement)(o.__experimentalToolsPanelItem,{label:(0,c.__)("All questions","4wp-faq"),hasValue:()=>!!k,onDeselect:()=>t({allItemFontSize:""}),isShownByDefault:!0,panelId:"forwp-faq-categories-sizes"},(0,r.createElement)(o.FontSizePicker,{fontSizes:R,value:k||void 0,onChange:e=>t({allItemFontSize:E(e)}),withReset:!1,withSlider:!0})),(0,r.createElement)(o.__experimentalToolsPanelItem,{label:(0,c.__)("Headings","4wp-faq"),hasValue:()=>!!z,onDeselect:()=>t({itemFontSize:""}),isShownByDefault:!0,panelId:"forwp-faq-categories-sizes"},(0,r.createElement)(o.FontSizePicker,{fontSizes:R,value:z||void 0,onChange:e=>t({itemFontSize:E(e)}),withReset:!1,withSlider:!0})),(0,r.createElement)(o.__experimentalToolsPanelItem,{label:(0,c.__)("Space between items","4wp-faq"),hasValue:()=>!!A,onDeselect:()=>t({itemGap:""}),isShownByDefault:!0,panelId:"forwp-faq-categories-sizes"},(0,r.createElement)(o.RangeControl,{label:(0,c.__)("Space between items","4wp-faq"),value:A?parseFloat(A):void 0,onChange:e=>t({itemGap:null==e?"":`${e}px`}),min:0,max:48,step:1,allowReset:!0,resetFallbackValue:void 0,__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0})))),(0,r.createElement)(o.Disabled,null,(0,r.createElement)(f(),{block:"forwp/faq-categories",attributes:e,httpMethod:"POST"})))},save:()=>null})}},a={};function r(e){var l=a[e];if(void 0!==l)return l.exports;var n=a[e]={exports:{}};return t[e](n,n.exports,r),n.exports}r.m=t,e=[],r.O=(t,a,l,n)=>{if(!a){var o=1/0;for(p=0;p<e.length;p++){for(var[a,l,n]=e[p],i=!0,s=0;s<a.length;s++)(!1&n||o>=n)&&Object.keys(r.O).every(e=>r.O[e](a[s]))?a.splice(s--,1):(i=!1,n<o&&(o=n));if(i){e.splice(p--,1);var c=l();void 0!==c&&(t=c)}}return t}n=n||0;for(var p=e.length;p>0&&e[p-1][2]>n;p--)e[p]=e[p-1];e[p]=[a,l,n]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={30:0,715:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var l,n,[o,i,s]=a,c=0;if(o.some(t=>0!==e[t])){for(l in i)r.o(i,l)&&(r.m[l]=i[l]);if(s)var p=s(r)}for(t&&t(a);c<o.length;c++)n=o[c],r.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return r.O(p)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var l=r.O(void 0,[715],()=>r(382));l=r.O(l)})(); -
4wp-faq/trunk/build/faq-count.asset.php
r3678667 r3748403 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n', 'wp-server-side-render'), 'version' => ' 494659158c6e9ef14549');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n', 'wp-server-side-render'), 'version' => '923cdb1cababc7a90d8f'); -
4wp-faq/trunk/build/faq-count.js
r3678667 r3748403 1 (()=>{"use strict";var e={n:t=>{var o=t&&t.__esModule?()=>t.default:()=>t;return e.d(o,{a:o}),o},d:(t,o)=>{for(var r in o)e.o(o,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:o[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,o=window.wp.blocks,r=window.wp.blockEditor,n=window.wp.components,a=window.wp.i18n,l=window.wp.serverSideRender;var c=e.n(l);(0,o.registerBlockType)("forwp/faq-count",{edit:()=>{const e=(0,r.useBlockProps)({className:"forwp-faq-count-editor"});return(0,t.createElement)("div",{...e},(0,t.createElement)(r.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,a.__)("Count","4wp-faq"),initialOpen:!0},(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,a.__)("Shows how many questions are on the page: all categories (preview), the current category URL, or the current search.","4wp-faq")))),(0,t.createElement)(n.Disabled,null,(0,t.createElement)(c(),{block:"forwp/faq-count" })))},save:()=>null})})();1 (()=>{"use strict";var e={n:t=>{var o=t&&t.__esModule?()=>t.default:()=>t;return e.d(o,{a:o}),o},d:(t,o)=>{for(var r in o)e.o(o,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:o[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,o=window.wp.blocks,r=window.wp.blockEditor,n=window.wp.components,a=window.wp.i18n,l=window.wp.serverSideRender;var c=e.n(l);(0,o.registerBlockType)("forwp/faq-count",{edit:()=>{const e=(0,r.useBlockProps)({className:"forwp-faq-count-editor"});return(0,t.createElement)("div",{...e},(0,t.createElement)(r.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,a.__)("Count","4wp-faq"),initialOpen:!0},(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,a.__)("Shows how many questions are on the page: all categories (preview), the current category URL, or the current search.","4wp-faq")))),(0,t.createElement)(n.Disabled,null,(0,t.createElement)(c(),{block:"forwp/faq-count",httpMethod:"POST"})))},save:()=>null})})(); -
4wp-faq/trunk/build/faq-list.asset.php
r3685374 r3748403 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp- data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'fe2efc8ef2bd970504d6');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '7f14cd6eefac1c3d83b7'); -
4wp-faq/trunk/build/faq-list.js
r3685374 r3748403 1 (()=>{"use strict";var e,t={ 970(e,t,a){const o=window.React,l=window.wp.blocks,r=window.wp.blockEditor,n=window.wp.components,s=window.wp.data,i=window.wp.element,c=window.wp.i18n,p=window.wp.apiFetch;var u=a.n(p);const d=window.wp.serverSideRender;var f=a.n(d);const m=["forwp/faq-list","forwp/faq-categories"],y=(e,t=[])=>((e||[]).forEach(e=>{m.includes(e.name)&&t.push(e),e.innerBlocks&&e.innerBlocks.length&&y(e.innerBlocks,t)}),t),w=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0).sort((e,t)=>e-t).join(","),_=e=>{const t=[],a=new Set,o=e=>{if(!e||"object"!=typeof e)return;const o="string"==typeof e.fontFamily?e.fontFamily:"",l="string"==typeof e.slug?e.slug:"",r=o||l;r&&!a.has(r)&&(a.add(r),t.push({name:"string"==typeof e.name&&e.name||l||o,slug:l||r.replace(/[^a-z0-9\-]+/gi,"-").toLowerCase(),fontFamily:o||(l?`var(--wp--preset--font-family--${l})`:"")}))};return Array.isArray(e)?(e.forEach(o),t):(e&&"object"==typeof e&&Object.values(e).forEach(e=>{Array.isArray(e)&&e.forEach(o)}),t)},h=e=>null==e||""===e?"":"number"==typeof e&&Number.isFinite(e)?`${e}px`:String(e),b=e=>{if(null==e||""===e)return"";const t=String(e).trim(),a=t.match(/^var:preset\|color\|([a-z0-9\-]+)$/i);return a?`var(--wp--preset--color--${a[1].toLowerCase()})`:t},g={fontSize:"",fontFamily:"",fontWeight:"",color:""},S={colors:[],gradients:[],disableCustomColors:!1,disableCustomGradients:!0,hasColorsOrGradients:!1};function v({value:e={},onChange:t,title:a,panelId:l,help:i=""}){const{fontSizes:p,fontFamilies:u}=(0,s.useSelect)(e=>{var t,a;const o=e("core/block-editor")?.getSettings?.()||{},l=o.__experimentalFeatures||{},r=null!==(t=null!==(a=l?.typography?.fontFamilies)&&void 0!==a?a:o.fontFamilies)&&void 0!==t?t:null;return{fontSizes:Array.isArray(o.fontSizes)?o.fontSizes:Array.isArray(l?.typography?.fontSizes)?l.typography.fontSizes:void 0,fontFamilies:_(r)}},[]),d=("function"==typeof r.__experimentalUseMultipleOriginColorsAndGradients?(0,r.__experimentalUseMultipleOriginColorsAndGradients)():null)||S,f=e&&"object"==typeof e?e:{},m=f.fontSize||"",y=f.fontFamily||"",w=f.fontWeight||"",v=f.color||"",q=e=>t({...f,...e}),E=()=>!!y,F=()=>!!w;return(0,o.createElement)(o.Fragment,null,i?(0,o.createElement)("p",{className:"forwp-faq-typography-help"},i):null,(0,o.createElement)(n.__experimentalToolsPanel,{label:a,resetAll:()=>t({...g}),panelId:l,hasInnerWrapper:!0},r.__experimentalColorGradientSettingsDropdown?(0,o.createElement)(r.__experimentalColorGradientSettingsDropdown,{__experimentalIsRenderedInSidebar:!0,settings:[{colorValue:v||void 0,label:(0,c.__)("Color","4wp-faq"),onColorChange:e=>q({color:b(e)}),isShownByDefault:!0,resetAllFilter:()=>q({color:""}),hasValue:()=>!!v,onDeselect:()=>q({color:""})}],panelId:l,...d}):null,u.length>0&&r.__experimentalFontFamilyControl?(0,o.createElement)(n.__experimentalToolsPanelItem,{hasValue:E,label:(0,c.__)("Font","4wp-faq"),onDeselect:()=>q({fontFamily:""}),isShownByDefault:!0,panelId:l},(0,o.createElement)(r.__experimentalFontFamilyControl,{fontFamilies:u,value:y,onChange:e=>q({fontFamily:e||""}),size:"__unstable-large",__nextHasNoMarginBottom:!0})):u.length>0?(0,o.createElement)(n.__experimentalToolsPanelItem,{hasValue:E,label:(0,c.__)("Font","4wp-faq"),onDeselect:()=>q({fontFamily:""}),isShownByDefault:!0,panelId:l},(0,o.createElement)(n.SelectControl,{label:(0,c.__)("Font","4wp-faq"),hideLabelFromVision:!0,value:y,options:[{label:(0,c.__)("Default","4wp-faq"),value:""},...u.map(e=>({label:e.name,value:e.fontFamily}))],onChange:e=>q({fontFamily:e||""}),__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0})):null,(0,o.createElement)(n.__experimentalToolsPanelItem,{hasValue:()=>!!m,label:(0,c.__)("Size","4wp-faq"),onDeselect:()=>q({fontSize:""}),isShownByDefault:!0,panelId:l},(0,o.createElement)(r.FontSizePicker,{fontSizes:p,value:m||void 0,onChange:e=>q({fontSize:h(e)}),withReset:!1,size:"__unstable-large",__next40pxDefaultSize:!0})),r.__experimentalFontAppearanceControl?(0,o.createElement)(n.__experimentalToolsPanelItem,{hasValue:F,label:(0,c.__)("Appearance","4wp-faq"),onDeselect:()=>q({fontWeight:""}),isShownByDefault:!0,panelId:l},(0,o.createElement)(r.__experimentalFontAppearanceControl,{value:{fontStyle:"normal",fontWeight:w||void 0},onChange:e=>q({fontWeight:e?.fontWeight?String(e.fontWeight):""}),hasFontStyles:!1,hasFontWeights:!0})):(0,o.createElement)(n.__experimentalToolsPanelItem,{hasValue:F,label:(0,c.__)("Appearance","4wp-faq"),onDeselect:()=>q({fontWeight:""}),isShownByDefault:!0,panelId:l},(0,o.createElement)(n.SelectControl,{label:(0,c.__)("Weight","4wp-faq"),hideLabelFromVision:!0,value:w,options:[{label:(0,c.__)("Default","4wp-faq"),value:""},{label:(0,c.__)("Normal","4wp-faq"),value:"400"},{label:(0,c.__)("Medium","4wp-faq"),value:"500"},{label:(0,c.__)("Semibold","4wp-faq"),value:"600"},{label:(0,c.__)("Bold","4wp-faq"),value:"700"}],onChange:e=>q({fontWeight:e||""}),__next40pxDefaultSize:!0,__nextHasNoMarginBottom:!0}))))}const q=[["forwp/faq-card",{}]],E=(e,t)=>JSON.stringify(e&&"object"==typeof e?e:{})===JSON.stringify(t&&"object"==typeof t?t:{}),F=(e,t)=>(e||[]).map(e=>t.find(t=>t.id===e)?.name).filter(Boolean),I=(e,t)=>(e||[]).map(e=>t.find(t=>t.name===e)?.id).filter(Boolean);(0,l.registerBlockType)("forwp/faq-list",{edit:({attributes:e,setAttributes:t,clientId:a})=>{const{layout:l="grouped",includeTermIds:p=[],excludeTermIds:d=[],cardDisplayMode:m="accordion",cardShowSources:_=!1,cardSourcesLabel:h="Used in",cardShowPostType:b=!1,cardQuestionStyle:g={},cardAnswerStyle:S={}}=e,{terms:x,loading:C,registryReady:k}=(()=>{const[e,t]=(0,i.useState)([]),[a,o]=(0,i.useState)(!1),l="undefined"!=typeof window&&window.forwpFaqDisplay?window.forwpFaqDisplay:{},r=!!l.registrySetupComplete,n=l.categoriesPath||"/forwp-faq/v1/editor/categories";return(0,i.useEffect)(()=>{if(!r)return void t([]);let e=!1;return o(!0),u()({path:n}).then(a=>{e||t(Array.isArray(a?.terms)?a.terms:[])}).catch(()=>{e||t([])}).finally(()=>{e||o(!1)}),()=>{e=!0}},[r,n]),{terms:e,loading:a,registryReady:r}})();((e,t,a)=>{const{updateBlockAttributes:o}=(0,s.useDispatch)("core/block-editor"),l=(0,s.useSelect)(t=>y(t("core/block-editor").getBlocks()).filter(t=>t.clientId!==e).map(e=>`${e.clientId}:${w(e.attributes?.includeTermIds)}:${w(e.attributes?.excludeTermIds)}`).join("|"),[e]),r=(0,i.useRef)(!1);(0,i.useEffect)(()=>{const l=(e=>y((0,s.select)("core/block-editor").getBlocks()).filter(t=>t.clientId!==e))(e);if(!r.current){r.current=!0;const n=l.find(e=>(e.attributes?.includeTermIds||[]).length>0||(e.attributes?.excludeTermIds||[]).length>0),s=0===(t||[]).length&&0===(a||[]).length;return void(n&&s&&o(e,{includeTermIds:n.attributes.includeTermIds||[],excludeTermIds:n.attributes.excludeTermIds||[]}))}const n=t||[],i=a||[];l.forEach(e=>{w(e.attributes?.includeTermIds)===w(n)&&w(e.attributes?.excludeTermIds)===w(i)||o(e.clientId,{includeTermIds:n,excludeTermIds:i})})},[e,t,a,l,o])})(a,p,d);const{updateBlockAttributes:O}=(0,s.useDispatch)("core/block-editor"),T=(0,r.useBlockProps)({className:"forwp-faq-list-editor"}),B=(0,i.useMemo)(()=>x.map(e=>e.name),[x]),A=(0,s.useSelect)(e=>{const t=e("core/block-editor").getBlock(a);return t?.innerBlocks?.[0]||null},[a]);(0,i.useEffect)(()=>{if(!A||"forwp/faq-card"!==A.name)return;const e=A.attributes?.displayMode||"accordion",a=!!A.attributes?.showSources,o="string"==typeof A.attributes?.sourcesLabel?A.attributes.sourcesLabel:"Used in",l=!!A.attributes?.showPostType,r=A.attributes?.questionStyle&&"object"==typeof A.attributes.questionStyle?A.attributes.questionStyle:{},n=A.attributes?.answerStyle&&"object"==typeof A.attributes.answerStyle?A.attributes.answerStyle:{};e===m&&a===_&&o===h&&l===b&&E(r,g)&&E(n,S)||t({cardDisplayMode:e,cardShowSources:a,cardSourcesLabel:o,cardShowPostType:l,cardQuestionStyle:r,cardAnswerStyle:n})},[A?.attributes?.displayMode,A?.attributes?.showSources,A?.attributes?.sourcesLabel,A?.attributes?.showPostType,A?.attributes?.questionStyle,A?.attributes?.answerStyle,m,_,h,b,g,S,t,A]);const D=e=>{if(!A?.clientId)return;O(A.clientId,e);const a={};Object.prototype.hasOwnProperty.call(e,"answerStyle")&&(a.cardAnswerStyle=e.answerStyle),Object.prototype.hasOwnProperty.call(e,"questionStyle")&&(a.cardQuestionStyle=e.questionStyle),Object.prototype.hasOwnProperty.call(e,"displayMode")&&(a.cardDisplayMode=e.displayMode),Object.prototype.hasOwnProperty.call(e,"showSources")&&(a.cardShowSources=e.showSources),Object.prototype.hasOwnProperty.call(e,"sourcesLabel")&&(a.cardSourcesLabel=e.sourcesLabel),Object.prototype.hasOwnProperty.call(e,"showPostType")&&(a.cardShowPostType=e.showPostType),Object.keys(a).length&&t(a)};return(0,o.createElement)("div",{...T},(0,o.createElement)(r.InspectorControls,null,(0,o.createElement)(n.PanelBody,{title:(0,c.__)("List","4wp-faq"),initialOpen:!0},(0,o.createElement)(n.RadioControl,{label:(0,c.__)("Layout","4wp-faq"),selected:l,options:[{label:(0,c.__)("Grouped by category","4wp-faq"),value:"grouped"},{label:(0,c.__)("Single list","4wp-faq"),value:"flat"}],onChange:e=>t({layout:e||"grouped"})})),(0,o.createElement)(n.PanelBody,{title:(0,c.__)("Categories","4wp-faq"),initialOpen:!0},k?C?(0,o.createElement)(n.Spinner,null):(0,o.createElement)(o.Fragment,null,(0,o.createElement)(n.FormTokenField,{label:(0,c.__)("Include categories","4wp-faq"),value:F(p,x),suggestions:B,onChange:e=>t({includeTermIds:I(e,x)}),__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),(0,o.createElement)("p",{className:"forwp-faq-list-editor__help"},(0,c.__)("Shared with 4WP FAQ Categories on this page. Leave empty to include all categories.","4wp-faq")),(0,o.createElement)(n.FormTokenField,{label:(0,c.__)("Exclude categories","4wp-faq"),value:F(d,x),suggestions:B,onChange:e=>t({excludeTermIds:I(e,x)}),__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0})):(0,o.createElement)(n.Notice,{status:"warning",isDismissible:!1},(0,c.__)("Complete FAQ registry setup to filter by category.","4wp-faq")))),(0,o.createElement)(r.InspectorControls,{group:"styles"},(0,o.createElement)(v,{panelId:"forwp-faq-list-question-style",title:(0,c.__)("Question","4wp-faq"),help:(0,c.__)("Empty values inherit from the theme or parent Group/Column.","4wp-faq"),value:A?.attributes?.questionStyle||g||{},onChange:e=>D({questionStyle:e})}),(0,o.createElement)(v,{panelId:"forwp-faq-list-answer-style",title:(0,c.__)("Answer","4wp-faq"),help:(0,c.__)("Empty values inherit from the theme or parent Group/Column.","4wp-faq"),value:A?.attributes?.answerStyle||S||{},onChange:e=>D({answerStyle:e})})),(0,o.createElement)("div",{className:"forwp-faq-list-editor__template"},(0,o.createElement)("p",{className:"forwp-faq-list-editor__hint"},(0,c.__)("FAQ Card controls display mode, source links, and question/answer styles.","4wp-faq")),(0,o.createElement)(r.InnerBlocks,{allowedBlocks:["forwp/faq-card"],template:q,templateLock:"all"})),(0,o.createElement)(n.Disabled,null,(0,o.createElement)(f(),{block:"forwp/faq-list",attributes:e})))},save:()=>(0,o.createElement)(r.InnerBlocks.Content,null)})}},a={};function o(e){var l=a[e];if(void 0!==l)return l.exports;var r=a[e]={exports:{}};return t[e](r,r.exports,o),r.exports}o.m=t,e=[],o.O=(t,a,l,r)=>{if(!a){var n=1/0;for(p=0;p<e.length;p++){for(var[a,l,r]=e[p],s=!0,i=0;i<a.length;i++)(!1&r||n>=r)&&Object.keys(o.O).every(e=>o.O[e](a[i]))?a.splice(i--,1):(s=!1,r<n&&(n=r));if(s){e.splice(p--,1);var c=l();void 0!==c&&(t=c)}}return t}r=r||0;for(var p=e.length;p>0&&e[p-1][2]>r;p--)e[p]=e[p-1];e[p]=[a,l,r]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var a in t)o.o(t,a)&&!o.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={610:0,135:0};o.O.j=t=>0===e[t];var t=(t,a)=>{var l,r,[n,s,i]=a,c=0;if(n.some(t=>0!==e[t])){for(l in s)o.o(s,l)&&(o.m[l]=s[l]);if(i)var p=i(o)}for(t&&t(a);c<n.length;c++)r=n[c],o.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return o.O(p)},a=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var l=o.O(void 0,[135],()=>o(970));l=o.O(l)})();1 (()=>{"use strict";var e,t={658(e,t,r){const o=window.React,a=window.wp.blocks,n=window.wp.blockEditor,l=window.wp.components,s=window.wp.data,i=window.wp.element,c=window.wp.i18n,u=window.wp.apiFetch;var p=r.n(u);const d=window.wp.serverSideRender;var f=r.n(d);const m=["forwp/faq-list","forwp/faq-categories"],y=(e,t=[])=>((e||[]).forEach(e=>{m.includes(e.name)&&t.push(e),e.innerBlocks&&e.innerBlocks.length&&y(e.innerBlocks,t)}),t),w=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0).sort((e,t)=>e-t).join(","),h=e=>[...e||[]].map(e=>Number(e)).filter(e=>e>0),g=(e,t,r,o)=>{const a=w(e),n=(0,i.useMemo)(()=>((e,t)=>(e||[]).map(e=>{const r=Number(e);return t.find(e=>Number(e.id)===r)?.name}).filter(Boolean))(e,t),[a,t]),l=(0,i.useCallback)(e=>{const n=((e,t)=>(e||[]).map(e=>t.find(t=>t.name===e)?.id).map(e=>Number(e)).filter(e=>e>0))(e,t);w(n)!==a&&r({[o]:n})},[o,r,t,a]);return{value:n,onChange:l}},b=window.wp.compose,S={},_={popoverProps:{placement:"left-start",offset:259}},v=e=>{const t=[],r=new Set,o=e=>{if(!e||"object"!=typeof e)return;const o="string"==typeof e.fontFamily?e.fontFamily:"",a="string"==typeof e.slug?e.slug:"",n=o||a;n&&!r.has(n)&&(r.add(n),t.push({name:"string"==typeof e.name&&e.name||a||o,slug:a||n.replace(/[^a-z0-9\-]+/gi,"-").toLowerCase(),fontFamily:o||(a?`var(--wp--preset--font-family--${a})`:"")}))};return Array.isArray(e)?(e.forEach(o),t):(e&&"object"==typeof e&&Object.values(e).forEach(e=>{Array.isArray(e)&&e.forEach(o)}),t)},q=e=>null==e||""===e?"":"number"==typeof e&&Number.isFinite(e)?`${e}px`:String(e),E=e=>{if(null==e||""===e)return"";const t=String(e).trim(),r=t.match(/^var:preset\|color\|([a-z0-9\-]+)$/i);return r?`var(--wp--preset--color--${r[1].toLowerCase()})`:t},I={color:"",fontFamily:"",fontSize:"",fontStyle:"",fontWeight:"",lineHeight:"",letterSpacing:"",textDecoration:"",textTransform:""},x={colors:[],gradients:[],disableCustomColors:!1,disableCustomGradients:!0,hasColorsOrGradients:!1};function C({value:e={},onChange:t,title:r,panelId:a}){const{fontSizes:u,fontFamilies:p}=(0,s.useSelect)(e=>{var t,r;const o=e("core/block-editor")?.getSettings?.()||{},a=o.__experimentalFeatures||{},n=null!==(t=null!==(r=a?.typography?.fontFamilies)&&void 0!==r?r:o.fontFamilies)&&void 0!==t?t:null;return{fontSizes:Array.isArray(o.fontSizes)?o.fontSizes:Array.isArray(a?.typography?.fontSizes)?a.typography.fontSizes:void 0,fontFamilies:v(n)}},[]),d=(()=>{const e=(0,b.useViewportMatch)("medium","<");return(0,i.useMemo)(()=>e?S:_,[e])})(),f=("function"==typeof n.__experimentalUseMultipleOriginColorsAndGradients?(0,n.__experimentalUseMultipleOriginColorsAndGradients)():null)||x,m=e&&"object"==typeof e?e:{},y=e=>t({...m,...e}),w=e=>()=>!!m[e],h=(...e)=>()=>y(Object.fromEntries(e.map(e=>[e,""])));return(0,o.createElement)(l.__experimentalToolsPanel,{label:r,resetAll:()=>t({...I}),panelId:a,__experimentalFirstVisibleItemClass:"first",dropdownMenuProps:d},(0,o.createElement)(n.__experimentalColorGradientSettingsDropdown,{__experimentalIsRenderedInSidebar:!0,settings:[{colorValue:m.color||void 0,label:(0,c.__)("Color","4wp-faq"),onColorChange:e=>y({color:E(e)}),isShownByDefault:!0,resetAllFilter:()=>y({color:""}),hasValue:w("color"),onDeselect:h("color")}],panelId:a,...f}),p.length>0?(0,o.createElement)(l.__experimentalToolsPanelItem,{label:(0,c.__)("Font","4wp-faq"),hasValue:w("fontFamily"),onDeselect:h("fontFamily"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.__experimentalFontFamilyControl,{fontFamilies:p,value:m.fontFamily||"",onChange:e=>y({fontFamily:e||""})})):null,(0,o.createElement)(l.__experimentalToolsPanelItem,{label:(0,c.__)("Size","4wp-faq"),hasValue:w("fontSize"),onDeselect:h("fontSize"),isShownByDefault:!0,panelId:a},(0,o.createElement)(l.FontSizePicker,{fontSizes:u,value:m.fontSize||void 0,onChange:e=>y({fontSize:q(e)}),withReset:!1,withSlider:!0})),(0,o.createElement)(l.__experimentalToolsPanelItem,{label:(0,c.__)("Appearance","4wp-faq"),hasValue:()=>!!m.fontWeight||!!m.fontStyle,onDeselect:h("fontWeight","fontStyle"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.__experimentalFontAppearanceControl,{value:{fontStyle:m.fontStyle||void 0,fontWeight:m.fontWeight||void 0},onChange:e=>y({fontStyle:e?.fontStyle?String(e.fontStyle):"",fontWeight:e?.fontWeight?String(e.fontWeight):""}),hasFontStyles:!0,hasFontWeights:!0})),(0,o.createElement)(l.__experimentalToolsPanelItem,{className:"single-column",label:(0,c.__)("Line height","4wp-faq"),hasValue:w("lineHeight"),onDeselect:h("lineHeight"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.LineHeightControl,{__unstableInputWidth:"auto",value:m.lineHeight||void 0,onChange:e=>y({lineHeight:e?String(e):""})})),(0,o.createElement)(l.__experimentalToolsPanelItem,{className:"single-column",label:(0,c.__)("Letter spacing","4wp-faq"),hasValue:w("letterSpacing"),onDeselect:h("letterSpacing"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.__experimentalLetterSpacingControl,{__unstableInputWidth:"auto",value:m.letterSpacing||void 0,onChange:e=>y({letterSpacing:e||""})})),(0,o.createElement)(l.__experimentalToolsPanelItem,{label:(0,c.__)("Decoration","4wp-faq"),hasValue:w("textDecoration"),onDeselect:h("textDecoration"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.__experimentalTextDecorationControl,{value:m.textDecoration||void 0,onChange:e=>y({textDecoration:e||""})})),(0,o.createElement)(l.__experimentalToolsPanelItem,{label:(0,c.__)("Letter case","4wp-faq"),hasValue:w("textTransform"),onDeselect:h("textTransform"),isShownByDefault:!0,panelId:a},(0,o.createElement)(n.__experimentalTextTransformControl,{value:m.textTransform||void 0,onChange:e=>y({textTransform:e||""})})))}const T=[["forwp/faq-card",{}],["forwp/faq-no-results",{},[["core/paragraph",{content:(0,c.__)("No questions found. Try another search.","4wp-faq")}]]]];(0,a.registerBlockType)("forwp/faq-no-results",{edit:()=>{const e=(0,n.useBlockProps)({className:"forwp-faq-no-results-editor"});return(0,o.createElement)("div",{...e},(0,o.createElement)("p",{className:"forwp-faq-list-editor__hint"},(0,c.__)("Shown when the search finds no questions.","4wp-faq")),(0,o.createElement)(n.InnerBlocks,{templateLock:!1}))},save:()=>(0,o.createElement)(n.InnerBlocks.Content,null)});const k=(e,t)=>JSON.stringify(e&&"object"==typeof e?e:{})===JSON.stringify(t&&"object"==typeof t?t:{});(0,a.registerBlockType)("forwp/faq-list",{edit:({attributes:e,setAttributes:t,clientId:r})=>{const{layout:a="grouped",includeTermIds:u=[],excludeTermIds:d=[],cardDisplayMode:m="accordion",cardShowSources:b=!1,cardSourcesLabel:S="Used in",cardSourcesSeparator:_=", ",cardShowPostType:v=!1,cardQuestionStyle:q={},cardAnswerStyle:E={},groupTitleStyle:I={}}=e,{terms:x,loading:O,registryReady:F}=(()=>{const[e,t]=(0,i.useState)([]),[r,o]=(0,i.useState)(!1),a="undefined"!=typeof window&&window.forwpFaqDisplay?window.forwpFaqDisplay:{},n=!!a.registrySetupComplete,l=a.categoriesPath||"/forwp-faq/v1/editor/categories",c=(0,s.useSelect)(e=>e("core/editor")?.getCurrentPostId?.(),[]),u="number"==typeof c&&c>0?`?post_id=${c}`:"";return(0,i.useEffect)(()=>{if(!n)return void t([]);let e=!1;return o(!0),p()({path:`${l}${u}`}).then(r=>{e||t(Array.isArray(r?.terms)?r.terms:[])}).catch(()=>{e||t([])}).finally(()=>{e||o(!1)}),()=>{e=!0}},[n,l,u]),{terms:e,loading:r,registryReady:n}})();((e,t,r)=>{const{updateBlockAttributes:o}=(0,s.useDispatch)("core/block-editor"),a=w(t),n=w(r),l=`${a}|${n}`,c=(0,i.useRef)(""),u=(0,i.useRef)(!1),p=(0,s.useSelect)(t=>y(t("core/block-editor").getBlocks()).filter(t=>t.clientId!==e).map(e=>`${w(e.attributes?.includeTermIds)}:${w(e.attributes?.excludeTermIds)}`).join("|"),[e]);(0,i.useEffect)(()=>{const i=(e=>y((0,s.select)("core/block-editor").getBlocks()).filter(t=>t.clientId!==e))(e),p=h(t),d=h(r);if(!u.current){u.current=!0;const t=i.find(e=>(e.attributes?.includeTermIds||[]).length>0||(e.attributes?.excludeTermIds||[]).length>0);if(t&&!a&&!n){const r=h(t.attributes.includeTermIds),a=h(t.attributes.excludeTermIds);return c.current=`${w(r)}|${w(a)}`,void o(e,{includeTermIds:r,excludeTermIds:a})}return void(c.current=l)}c.current!==l&&(c.current=l,i.forEach(e=>{w(e.attributes?.includeTermIds)===a&&w(e.attributes?.excludeTermIds)===n||o(e.clientId,{includeTermIds:p,excludeTermIds:d})}))},[e,a,n,l,p,o])})(r,u,d);const P=g(u,x,t,"includeTermIds"),D=g(d,x,t,"excludeTermIds"),{updateBlockAttributes:B}=(0,s.useDispatch)("core/block-editor"),A=(0,n.useBlockProps)({className:"forwp-faq-list-editor"}),j=(0,i.useMemo)(()=>x.map(e=>e.name),[x]),L=(0,s.useSelect)(e=>{const t=e("core/block-editor").getBlock(r);return t?.innerBlocks?.[0]||null},[r]);(0,i.useEffect)(()=>{if(!L||"forwp/faq-card"!==L.name)return;const e=L.attributes?.displayMode||"accordion",r=!!L.attributes?.showSources,o="string"==typeof L.attributes?.sourcesLabel?L.attributes.sourcesLabel:"Used in",a="string"==typeof L.attributes?.sourcesSeparator?L.attributes.sourcesSeparator:", ",n=!!L.attributes?.showPostType,l=L.attributes?.questionStyle&&"object"==typeof L.attributes.questionStyle?L.attributes.questionStyle:{},s=L.attributes?.answerStyle&&"object"==typeof L.attributes.answerStyle?L.attributes.answerStyle:{};e===m&&r===b&&o===S&&a===_&&n===v&&k(l,q)&&k(s,E)||t({cardDisplayMode:e,cardShowSources:r,cardSourcesLabel:o,cardSourcesSeparator:a,cardShowPostType:n,cardQuestionStyle:l,cardAnswerStyle:s})},[L?.attributes?.displayMode,L?.attributes?.showSources,L?.attributes?.sourcesLabel,L?.attributes?.sourcesSeparator,L?.attributes?.showPostType,L?.attributes?.questionStyle,L?.attributes?.answerStyle,m,b,S,_,v,q,E,t,L]);const N=e=>{if(!L?.clientId)return;B(L.clientId,e);const r={};Object.prototype.hasOwnProperty.call(e,"answerStyle")&&(r.cardAnswerStyle=e.answerStyle),Object.prototype.hasOwnProperty.call(e,"questionStyle")&&(r.cardQuestionStyle=e.questionStyle),Object.prototype.hasOwnProperty.call(e,"displayMode")&&(r.cardDisplayMode=e.displayMode),Object.prototype.hasOwnProperty.call(e,"showSources")&&(r.cardShowSources=e.showSources),Object.prototype.hasOwnProperty.call(e,"sourcesLabel")&&(r.cardSourcesLabel=e.sourcesLabel),Object.prototype.hasOwnProperty.call(e,"sourcesSeparator")&&(r.cardSourcesSeparator=e.sourcesSeparator),Object.prototype.hasOwnProperty.call(e,"showPostType")&&(r.cardShowPostType=e.showPostType),Object.keys(r).length&&t(r)};return(0,o.createElement)("div",{...A},(0,o.createElement)(n.InspectorControls,null,(0,o.createElement)(l.PanelBody,{title:(0,c.__)("List","4wp-faq"),initialOpen:!0},(0,o.createElement)(l.RadioControl,{label:(0,c.__)("Layout","4wp-faq"),selected:a,options:[{label:(0,c.__)("Grouped by category","4wp-faq"),value:"grouped"},{label:(0,c.__)("Single list","4wp-faq"),value:"flat"}],onChange:e=>t({layout:e||"grouped"})})),(0,o.createElement)(l.PanelBody,{title:(0,c.__)("Categories","4wp-faq"),initialOpen:!0},F?O?(0,o.createElement)(l.Spinner,null):(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.FormTokenField,{label:(0,c.__)("Include categories","4wp-faq"),value:P.value,suggestions:j,onChange:P.onChange,__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),(0,o.createElement)("p",{className:"forwp-faq-list-editor__help"},(0,c.__)("Shared with 4WP FAQ Categories on this page. Leave empty to include all categories.","4wp-faq")),(0,o.createElement)(l.FormTokenField,{label:(0,c.__)("Exclude categories","4wp-faq"),value:D.value,suggestions:j,onChange:D.onChange,__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0})):(0,o.createElement)(l.Notice,{status:"warning",isDismissible:!1},(0,c.__)("Complete FAQ registry setup to filter by category.","4wp-faq")))),(0,o.createElement)(n.InspectorControls,{group:"styles"},(0,o.createElement)(C,{panelId:"forwp-faq-list-group-title-style",title:(0,c.__)("Category title","4wp-faq"),value:I,onChange:e=>t({groupTitleStyle:e})}),(0,o.createElement)(C,{panelId:"forwp-faq-list-question-style",title:(0,c.__)("Question","4wp-faq"),value:L?.attributes?.questionStyle||q||{},onChange:e=>N({questionStyle:e})}),(0,o.createElement)(C,{panelId:"forwp-faq-list-answer-style",title:(0,c.__)("Answer","4wp-faq"),value:L?.attributes?.answerStyle||E||{},onChange:e=>N({answerStyle:e})})),(0,o.createElement)("div",{className:"forwp-faq-list-editor__template"},(0,o.createElement)("p",{className:"forwp-faq-list-editor__hint"},(0,c.__)("FAQ Card controls display mode, source links, and question/answer styles.","4wp-faq")),(0,o.createElement)(n.InnerBlocks,{allowedBlocks:["forwp/faq-card","forwp/faq-no-results"],template:T,templateLock:"all"})),(0,o.createElement)(l.Disabled,null,(0,o.createElement)(f(),{block:"forwp/faq-list",attributes:e,httpMethod:"POST"})))},save:()=>(0,o.createElement)(n.InnerBlocks.Content,null)})}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var n=r[e]={exports:{}};return t[e](n,n.exports,o),n.exports}o.m=t,e=[],o.O=(t,r,a,n)=>{if(!r){var l=1/0;for(u=0;u<e.length;u++){for(var[r,a,n]=e[u],s=!0,i=0;i<r.length;i++)(!1&n||l>=n)&&Object.keys(o.O).every(e=>o.O[e](r[i]))?r.splice(i--,1):(s=!1,n<l&&(l=n));if(s){e.splice(u--,1);var c=a();void 0!==c&&(t=c)}}return t}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[r,a,n]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={610:0,135:0};o.O.j=t=>0===e[t];var t=(t,r)=>{var a,n,[l,s,i]=r,c=0;if(l.some(t=>0!==e[t])){for(a in s)o.o(s,a)&&(o.m[a]=s[a]);if(i)var u=i(o)}for(t&&t(r);c<l.length;c++)n=l[c],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(u)},r=globalThis.webpackChunkforwp_faq=globalThis.webpackChunkforwp_faq||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var a=o.O(void 0,[135],()=>o(658));a=o.O(a)})(); -
4wp-faq/trunk/build/index.asset.php
r3685374 r3748403 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => ' e5bc29fc46a5f8f653fe');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'd763aa49ed0dffc25df4'); -
4wp-faq/trunk/build/index.js
r3685374 r3748403 1 (()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var o in r)e.o(r,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:r[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,r=window.wp.blocks,o=window.wp.blockEditor,n=window.wp.components, a=window.wp.data,c=window.wp.element,l=window.wp.hooks,i=window.wp.compose,s=window.wp.apiFetch;var d=e.n(s);const p=window.wp.i18n;(0,l.addFilter)("blocks.registerBlockType","forwp/faq/search-faq-filter-attribute",(e,t)=>"core/search"!==t?e:{...e,attributes:{...e.attributes,forwpFaqFilter:{type:"boolean",default:!1}}});const m=(0,i.createHigherOrderComponent)(e=>r=>{if("core/search"!==r.name)return(0,t.createElement)(e,{...r});const{attributes:a,setAttributes:l}=r;return(0,t.createElement)(c.Fragment,null,(0,t.createElement)(e,{...r}),(0,t.createElement)(o.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,p.__)("4WP FAQ","4wp-faq"),initialOpen:!1},(0,t.createElement)(n.ToggleControl,{label:(0,p.__)("Filter 4WP FAQ List","4wp-faq"),help:(0,p.__)("When on, this Search filters FAQ cards on the same page via the Interactivity API.","4wp-faq"),checked:!!a.forwpFaqFilter,onChange:e=>l({forwpFaqFilter:!!e})}))))},"withFaqSearchFilter");(0,l.addFilter)("editor.BlockEdit","forwp/faq/search-faq-filter-control",m);const f=e=>{if(!e||!e.length)return"";const t=(0,r.serialize)(e);return((new DOMParser).parseFromString(t,"text/html").body.textContent||"").trim()},u=e=>"string"==typeof e&&e.includes("accordion")&&!e.includes("accordion-item"),g=()=>"undefined"!=typeof window&&window.forwpFaqEditor?window.forwpFaqEditor:{},k=()=>g().globalJsonLdEnabled,h="none",w="existing",B=["core/accordion","core/accordion-group","core/details"],b=()=>(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:(0,p.__)("Question","4wp-faq")}),(0,r.createBlock)("core/accordion-panel",{},[(0,r.createBlock)("core/paragraph",{placeholder:(0,p.__)("Answer…","4wp-faq")})])]),y=()=>(0,r.createBlock)("core/accordion",{},[b()]),q=e=>e&&"number"==typeof e.level,_=["core/paragraph","core/heading","core/list","core/quote"],E=e=>!(!Array.isArray(e)||e.length<2)&&e.every(e=>_.includes(e?.name)),A=e=>(0,r.createBlock)(e.name,{...e.attributes||{}},(e.innerBlocks||[]).map(A)),F=e=>String(e||"").replace(/<[^>]+>/g," ").replace(/ /gi," ").replace(/\s+/g," ").trim(),C=e=>e?"core/heading"===e.name||"core/paragraph"===e.name?e.attributes?.content||"":"core/list"===e.name?L(e.innerBlocks)[0]||"":f(e.innerBlocks?.length?e.innerBlocks:[e]):"",v=e=>"core/heading"===e?.name||/\?\s*$/.test(F(C(e))),I=e=>{if((e=>{if(!Array.isArray(e)||e.length<2||e.length%2!=0)return!1;if(2===e.length)return(e=>{if(!Array.isArray(e)||2!==e.length)return!1;const t=e.map(e=>e.name);return"core/heading"===t[0]&&"core/paragraph"===t[1]||"core/paragraph"===t[0]&&"core/heading"===t[1]})(e);for(let t=0;t<e.length;t+=2)if("core/heading"!==e[t]?.name||"core/paragraph"!==e[t+1]?.name)return!1;return!0})(e))return O(e.map(e=>e.attributes),e.map(e=>e.innerBlocks));const t=(e=>{if(e.some(v)){const t=[];let r=null;return e.forEach(e=>{if(!r||v(e))return r&&t.push(r),void(r={question:C(e),answers:[]});r.answers.push(e)}),r&&t.push(r),t}const t=[];for(let r=0;r<e.length;r+=2)t.push({question:C(e[r]),answers:e[r+1]?[e[r+1]]:[]});return t})(e);return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},t.map(e=>((e,t)=>{const o=F(e)?e:(0,p.__)("Question","4wp-faq"),n=t.length>0?t.map(A):[(0,r.createBlock)("core/paragraph",{placeholder:(0,p.__)("Answer…","4wp-faq")})];return(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:o}),(0,r.createBlock)("core/accordion-panel",{},n)])})(e.question,e.answers)))])},S=(e,t)=>{const o=Array.isArray(e),n=o?e:[e],a=o?t:[t||[]];return(0,r.createBlock)("forwp/faq",{},n.map((e,t)=>(0,r.createBlock)("core/details",e||{},a[t]||[])))},M=(e,t)=>{const o=Array.isArray(e),n=o?e:[e],a=o?t:[t||[]];return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},n.map((e,t)=>(0,r.createBlock)("core/accordion-item",e||{},a[t]||[])))])},O=(e,t)=>{if(2===e.length&&!q(e[0]))return((e,t)=>{let o=e[0],n=e[1],a=t[1]||[];q(o)||(o=e[1],n=e[0],a=t[0]||[]);const c=o.content||"",l=(0,r.createBlock)("core/paragraph",n,a);return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},[(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:c}),(0,r.createBlock)("core/accordion-panel",{},[l])])])])})(e,t);const o=[];for(let n=0;n<e.length;n+=2){const a=e[n]?.content||"",c=(0,r.createBlock)("core/paragraph",e[n+1]||{},t[n+1]||[]);o.push((0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:a}),(0,r.createBlock)("core/accordion-panel",{},[c])]))}return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},o)])},x=(0,p.__)("Convert to 4WP FAQ","4wp-faq"),T={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,isMatch:(e,t)=>E(t),__experimentalConvert:e=>I(e)},Q={type:"block",blocks:["*"],isMultiBlock:!0,isMatch:(e,t)=>E(t),__experimentalConvert:e=>I(e)},P={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,transform:(e,t)=>S(e,t)},N={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,transform:(e,t)=>M(e,t)},D={type:"block",blocks:["forwp/faq"],transform:(e,t)=>(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",e,t)])},L=e=>{const t=[];return(e||[]).forEach(e=>{if("core/list-item"!==e.name)return;const r=(e.attributes?.content||"").trim();r&&t.push(r)}),t},J=(e,t)=>{let o=L(t);return!o.length&&e?.values&&(o=(e=>{if(!e||"string"!=typeof e)return[];const t=(new DOMParser).parseFromString(`<ul>${e}</ul>`,"text/html");return Array.from(t.querySelectorAll("li")).map(e=>(e.innerHTML||e.textContent||"").trim()).filter(Boolean)})(e.values)),o.length?(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},o.map(e=>(e=>(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:e}),(0,r.createBlock)("core/accordion-panel",{},[(0,r.createBlock)("core/paragraph",{placeholder:(0,p.__)("Answer…","4wp-faq")})])]))(e)))]):(0,r.createBlock)("forwp/faq",{},[y()])},R={type:"block",blocks:["forwp/faq"],transform:(e,t)=>J(e,t)};(0,r.registerBlockType)("forwp/faq",{edit:e=>{const{attributes:r,setAttributes:l,clientId:i}=e,{getBlock:s,postId:m}=(0,a.useSelect)(e=>({getBlock:e("core/block-editor").getBlock,postId:e("core/editor")?.getCurrentPostId?.()||0}),[e.clientId]),{insertBlock:u}=(0,a.useDispatch)("core/block-editor"),q=s(i),_=(0,c.useMemo)(()=>(e=>{const t=[],r=e=>{e.forEach(e=>{const o=e.name;if((e=>"string"==typeof e&&("core/accordion-item"===e||e.includes("accordion-item")))(o)||(e=>"string"==typeof e&&("core/details"===e||e.endsWith("/details")))(o)){const{question:r,answer:o}=(e=>{const t=e.attributes||{};let r=(t.title||t.summary||t.question||t.heading||"").trim(),o="";const n=e.innerBlocks||[];return!r&&n.length&&(r=f([n[0]]),n.length>1&&(o=f(n.slice(1)))),!o&&n.length&&(o=f(n)),{question:r.trim(),answer:o.trim()}})(e);r&&o&&t.push({question:r,answer:o})}e.innerBlocks&&e.innerBlocks.length&&r(e.innerBlocks)})};return r(e||[]),t})(q?.innerBlocks||[]),[q]),E=(0,c.useMemo)(()=>(q?.innerBlocks||[]).find(e=>"core/accordion"===e.name||"core/accordion-group"===e.name)||null,[q]),A=r.jsonLd||"",F=Array.isArray(r.categoryTermIds)?r.categoryTermIds:[],C=r.categoryTermId||0,v=F.length>0?F:C?[C]:[],I=r.categoryName||"",[S,M]=(0,c.useState)(!(!I||!String(I).trim())),{terms:O,loading:x,registryReady:T}=(e=>{const[t,r]=(0,c.useState)([]),[o,n]=(0,c.useState)(!1),a=!!g().registrySetupComplete,l=g().categoriesPath||"/forwp-faq/v1/editor/categories";return(0,c.useEffect)(()=>{if(!a)return void r([]);let t=!1;n(!0);const o=e?`?post_id=${e}`:"";return d()({path:`${l}${o}`}).then(e=>{t||r(Array.isArray(e?.terms)?e.terms:[])}).catch(()=>{t||r([])}).finally(()=>{t||n(!1)}),()=>{t=!0}},[a,l,e]),{terms:t,loading:o,registryReady:a}})(m),Q=(e=>{const t=e||"";return"enable"===t||"disable"!==t&&!!k()})(A),P=k(),N=(0,c.useMemo)(()=>_.length&&Q?JSON.stringify({"@context":"https://schema.org","@type":"FAQPage",mainEntity:_.map(e=>({"@type":"Question",name:e.question,acceptedAnswer:{"@type":"Answer",text:e.answer}}))},null,2):"",[_,Q]),D=P?(0,p.__)("Site-wide JSON-LD is on. Choose “Off for this block” to exclude this FAQ from structured data.","4wp-faq"):(0,p.__)("Site-wide JSON-LD is off. Choose “On for this block” to output FAQPage schema for this block only.","4wp-faq");return(0,t.createElement)(c.Fragment,null,(0,t.createElement)(o.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,p.__)("SEO","4wp-faq"),initialOpen:!0},(0,t.createElement)(n.SelectControl,{label:(0,p.__)("JSON-LD on front end","4wp-faq"),help:D,value:A,options:[{label:P?(0,p.__)("Default (on — site setting)","4wp-faq"):(0,p.__)("Default (off — site setting)","4wp-faq"),value:""},{label:(0,p.__)("On for this block","4wp-faq"),value:"enable"},{label:(0,p.__)("Off for this block","4wp-faq"),value:"disable"}],onChange:e=>l({jsonLd:e||""})})),(0,t.createElement)(n.PanelBody,{title:(0,p.__)("Registry category","4wp-faq"),initialOpen:!1},T?x?(0,t.createElement)(n.Spinner,null):(0,t.createElement)(c.Fragment,null,(0,t.createElement)(n.FormTokenField,{label:(0,p.__)("FAQ categories","4wp-faq"),help:(0,p.__)("Search by name. The first category is the primary group for this FAQ. Applied on scan.","4wp-faq"),value:(v||[]).map(e=>O.find(t=>t.id===e)?.name).filter(Boolean),suggestions:O.map(e=>e.name),onChange:e=>{const t=(e||[]).map(e=>O.find(t=>t.name===e)?.id).filter(Boolean);l({categoryTermIds:t,categoryTermId:t[0]||0,categoryMode:t.length?w:I?"new":h})},__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),S?(0,t.createElement)(n.TextControl,{label:(0,p.__)("New category name","4wp-faq"),help:(0,p.__)("Created in the FAQ registry taxonomy on scan (language follows this page). Becomes primary if no existing category is selected.","4wp-faq"),value:I,onChange:e=>l({categoryName:e||"",categoryMode:v.length?w:e?"new":h})}):(0,t.createElement)(n.Button,{variant:"secondary",onClick:()=>M(!0)},(0,p.__)("Add new","4wp-faq"))):(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,p.__)("Complete FAQ registry setup to assign categories during scan.","4wp-faq"))),(0,t.createElement)(n.PanelBody,{title:(0,p.__)("FAQ preview","4wp-faq"),initialOpen:!1},0===_.length?(0,t.createElement)(n.Notice,{status:"warning",isDismissible:!1},(0,p.__)("Add accordion items to generate FAQ schema.","4wp-faq")):null,!Q&&_.length>0?(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,p.__)("JSON-LD is off for this block on the front end.","4wp-faq")):null,(0,t.createElement)("p",null,(0,p.__)("Items:","4wp-faq")," ",_.length),(0,t.createElement)(n.TextareaControl,{label:(0,p.__)("Schema JSON-LD (preview)","4wp-faq"),value:N,rows:Math.min(12,Math.max(6,2*_.length)),readOnly:!0}))),(0,t.createElement)("div",{className:e.className},(0,t.createElement)(o.InnerBlocks,{allowedBlocks:B,template:[["core/accordion",{},[["core/accordion-item",{},[["core/accordion-heading",{content:(0,p.__)("Question","4wp-faq")}],["core/accordion-panel",{},[["core/paragraph",{placeholder:(0,p.__)("Answer…","4wp-faq")}]]]]]]]],templateLock:!1}),(0,t.createElement)("div",{className:"forwp-faq-editor-actions",style:{marginTop:"12px"}},(0,t.createElement)(n.Button,{variant:"secondary",onClick:()=>{const e=b();E?u(e,E.clientId,E.innerBlocks?.length||0):u(y(),i,0)}},(0,p.__)("Add FAQ item","4wp-faq")))))},save:()=>(0,t.createElement)(o.InnerBlocks.Content,null),transforms:{from:[{type:"block",blocks:["core/accordion","core/accordion-group"],transform:(e,t)=>(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",e,t)])},{type:"block",blocks:["core/accordion-item"],isMultiBlock:!0,transform:(e,t)=>M(e,t)},{type:"block",blocks:["core/details"],isMultiBlock:!0,transform:(e,t)=>S(e,t)},Q,{type:"block",blocks:["core/list"],transform:(e,t)=>J(e,t)}]}});const H=(0,i.createHigherOrderComponent)(e=>l=>{const i=u(l.name),s="core/accordion-item"===l.name,d="core/details"===l.name,p="core/list"===l.name;if(!(i||s||d||p))return(0,t.createElement)(e,{...l});const{replaceBlock:m,replaceBlocks:f}=(0,a.useDispatch)("core/block-editor"),{getBlock:g,getBlockRootClientId:k,getMultiSelectedBlockClientIds:h}=(0,a.useSelect)(e=>({getBlock:e("core/block-editor").getBlock,getBlockRootClientId:e("core/block-editor").getBlockRootClientId,getMultiSelectedBlockClientIds:e("core/block-editor").getMultiSelectedBlockClientIds}),[l.clientId]),w=h(),B=(w||[]).map(e=>g(e)).filter(Boolean),b=B.length>1&&B.every(e=>e.name===l.name)&&(d||s);return b&&w[0]!==l.clientId?(0,t.createElement)(e,{...l}):(0,t.createElement)(c.Fragment,null,(0,t.createElement)(e,{...l}),(0,t.createElement)(o.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,null,(0,t.createElement)(n.ToolbarButton,{icon:"editor-help",text:x,label:x,onClick:()=>{if(b){const e=B.map(e=>e.attributes),t=B.map(e=>e.innerBlocks),r=d?S(e,t):M(e,t);return void f(w,[r])}if(p)return void m(l.clientId,J(l.attributes,l.innerBlocks));if(d)return void m(l.clientId,S(l.attributes,l.innerBlocks));if(i)return void m(l.clientId,(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)(l.name,l.attributes,l.innerBlocks)]));const e=k(l.clientId),t=e?g(e):null;t&&u(t.name)?m(e,(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)(t.name,t.attributes,t.innerBlocks)])):m(l.clientId,M(l.attributes,l.innerBlocks))}}))))},"withFaqTransform");(0,l.addFilter)("editor.BlockEdit","forwp/faq/with-transform",H);const W=(0,i.createHigherOrderComponent)(e=>r=>{if(!_.includes(r.name))return(0,t.createElement)(e,{...r});const{getMultiSelectedBlockClientIds:l,getBlock:i}=(0,a.useSelect)(e=>({getMultiSelectedBlockClientIds:e("core/block-editor").getMultiSelectedBlockClientIds,getBlock:e("core/block-editor").getBlock}),[]),{replaceBlocks:s}=(0,a.useDispatch)("core/block-editor"),d=l(),p=d.length>=2?d.map(e=>i(e)).filter(Boolean):[],m=E(p),f=m&&d[0]===r.clientId;return(0,t.createElement)(c.Fragment,null,(0,t.createElement)(e,{...r}),f?(0,t.createElement)(o.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,null,(0,t.createElement)(n.ToolbarButton,{icon:"editor-help",text:x,label:x,onClick:()=>{m&&s(d,[I(p)])}}))):null)},"withHeadingParagraphFaqConvert");(0,l.addFilter)("editor.BlockEdit","forwp/faq/with-heading-paragraph-convert",W),(0,l.addFilter)("blocks.registerBlockType","forwp/faq/block-to-faq-transforms",(e,t)=>{if("core/heading"===t||"core/paragraph"===t||"core/quote"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,T]}}}if("core/list"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,R,T]}}}if("core/details"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,P]}}}if("core/accordion-item"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,N]}}}if("core/accordion"===t||"core/accordion-group"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,D]}}}return e})})();1 (()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var o in r)e.o(r,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:r[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,r=window.wp.blocks,o=window.wp.blockEditor,n=window.wp.components,c=window.wp.data,a=window.wp.element,l=window.wp.hooks,i=window.wp.compose,s=window.wp.apiFetch;var p=e.n(s);const d=window.wp.i18n;(0,l.addFilter)("blocks.registerBlockType","forwp/faq/search-faq-filter-attribute",(e,t)=>"core/search"!==t?e:{...e,attributes:{...e.attributes,forwpFaqFilter:{type:"boolean",default:!1}}});const m=(0,i.createHigherOrderComponent)(e=>r=>{if("core/search"!==r.name)return(0,t.createElement)(e,{...r});const{attributes:c,setAttributes:l}=r;return(0,t.createElement)(a.Fragment,null,(0,t.createElement)(e,{...r}),(0,t.createElement)(o.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,d.__)("4WP FAQ","4wp-faq"),initialOpen:!1},(0,t.createElement)(n.ToggleControl,{label:(0,d.__)("Filter 4WP FAQ List","4wp-faq"),help:(0,d.__)("When on, this Search filters FAQ cards on the same page via the Interactivity API.","4wp-faq"),checked:!!c.forwpFaqFilter,onChange:e=>l({forwpFaqFilter:!!e})}))))},"withFaqSearchFilter");(0,l.addFilter)("editor.BlockEdit","forwp/faq/search-faq-filter-control",m);const f=e=>(0,r.createBlock)("forwp/faq",{},[(0,r.cloneBlock)(e)]),u=e=>{if(!e||!e.length)return"";const t=(0,r.serialize)(e);return((new DOMParser).parseFromString(t,"text/html").body.textContent||"").trim()},g=e=>"string"==typeof e&&e.includes("accordion")&&!e.includes("accordion-item"),k=()=>"undefined"!=typeof window&&window.forwpFaqEditor?window.forwpFaqEditor:{},h=()=>k().globalJsonLdEnabled,w="none",B="existing",b=["core/accordion","core/accordion-group","core/details"],y=()=>(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:(0,d.__)("Question","4wp-faq")}),(0,r.createBlock)("core/accordion-panel",{},[(0,r.createBlock)("core/paragraph",{placeholder:(0,d.__)("Answer…","4wp-faq")})])]),q=()=>(0,r.createBlock)("core/accordion",{},[y()]),_=e=>e&&"number"==typeof e.level,E=["core/paragraph","core/heading","core/list","core/quote"],A=e=>!(!Array.isArray(e)||e.length<2)&&e.every(e=>E.includes(e?.name)),F=e=>(0,r.createBlock)(e.name,{...e.attributes||{}},(e.innerBlocks||[]).map(F)),C=e=>String(e||"").replace(/<[^>]+>/g," ").replace(/ /gi," ").replace(/\s+/g," ").trim(),v=e=>e?"core/heading"===e.name||"core/paragraph"===e.name?e.attributes?.content||"":"core/list"===e.name?H(e.innerBlocks)[0]||"":u(e.innerBlocks?.length?e.innerBlocks:[e]):"",I=e=>"core/heading"===e?.name||/\?\s*$/.test(C(v(e))),S=e=>{if((e=>{if(!Array.isArray(e)||e.length<2||e.length%2!=0)return!1;if(2===e.length)return(e=>{if(!Array.isArray(e)||2!==e.length)return!1;const t=e.map(e=>e.name);return"core/heading"===t[0]&&"core/paragraph"===t[1]||"core/paragraph"===t[0]&&"core/heading"===t[1]})(e);for(let t=0;t<e.length;t+=2)if("core/heading"!==e[t]?.name||"core/paragraph"!==e[t+1]?.name)return!1;return!0})(e))return T(e.map(e=>e.attributes),e.map(e=>e.innerBlocks));const t=(e=>{if(e.some(I)){const t=[];let r=null;return e.forEach(e=>{if(!r||I(e))return r&&t.push(r),void(r={question:v(e),answers:[]});r.answers.push(e)}),r&&t.push(r),t}const t=[];for(let r=0;r<e.length;r+=2)t.push({question:v(e[r]),answers:e[r+1]?[e[r+1]]:[]});return t})(e);return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},t.map(e=>((e,t)=>{const o=C(e)?e:(0,d.__)("Question","4wp-faq"),n=t.length>0?t.map(F):[(0,r.createBlock)("core/paragraph",{placeholder:(0,d.__)("Answer…","4wp-faq")})];return(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:o}),(0,r.createBlock)("core/accordion-panel",{},n)])})(e.question,e.answers)))])},M=e=>(e||[]).map(e=>e&&"object"==typeof e&&e.name?(0,r.cloneBlock)(e):e),O=(e,t)=>{const o=Array.isArray(e),n=o?e:[e],c=o?t:[t||[]];return(0,r.createBlock)("forwp/faq",{},n.map((e,t)=>(0,r.createBlock)("core/details",e||{},M(c[t]||[]))))},x=(e,t)=>{const o=Array.isArray(e),n=o?e:[e],c=o?t:[t||[]];return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},n.map((e,t)=>(0,r.createBlock)("core/accordion-item",e||{},M(c[t]||[]))))])},T=(e,t)=>{if(2===e.length&&!_(e[0]))return((e,t)=>{let o=e[0],n=e[1],c=t[1]||[];_(o)||(o=e[1],n=e[0],c=t[0]||[]);const a=o.content||"",l=(0,r.createBlock)("core/paragraph",n,c);return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},[(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:a}),(0,r.createBlock)("core/accordion-panel",{},[l])])])])})(e,t);const o=[];for(let n=0;n<e.length;n+=2){const c=e[n]?.content||"",a=(0,r.createBlock)("core/paragraph",e[n+1]||{},t[n+1]||[]);o.push((0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:c}),(0,r.createBlock)("core/accordion-panel",{},[a])]))}return(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},o)])},Q=(0,d.__)("Convert to 4WP FAQ","4wp-faq"),P=(0,d.__)("Unwrap 4WP FAQ","4wp-faq"),N={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,isMatch:(e,t)=>A(t),__experimentalConvert:e=>S(e)},D={type:"block",blocks:["*"],isMultiBlock:!0,isMatch:(e,t)=>A(t),__experimentalConvert:e=>S(e)},L={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,transform:(e,t)=>O(e,t)},J={type:"block",blocks:["forwp/faq"],isMultiBlock:!0,transform:(e,t)=>x(e,t)},R={type:"block",blocks:["forwp/faq"],transform:(e,t)=>(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",e,t)])},H=e=>{const t=[];return(e||[]).forEach(e=>{if("core/list-item"!==e.name)return;const r=(e.attributes?.content||"").trim();r&&t.push(r)}),t},W=(e,t)=>{let o=H(t);return!o.length&&e?.values&&(o=(e=>{if(!e||"string"!=typeof e)return[];const t=(new DOMParser).parseFromString(`<ul>${e}</ul>`,"text/html");return Array.from(t.querySelectorAll("li")).map(e=>(e.innerHTML||e.textContent||"").trim()).filter(Boolean)})(e.values)),o.length?(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",{},o.map(e=>(e=>(0,r.createBlock)("core/accordion-item",{},[(0,r.createBlock)("core/accordion-heading",{content:e}),(0,r.createBlock)("core/accordion-panel",{},[(0,r.createBlock)("core/paragraph",{placeholder:(0,d.__)("Answer…","4wp-faq")})])]))(e)))]):(0,r.createBlock)("forwp/faq",{},[q()])},j={type:"block",blocks:["forwp/faq"],transform:(e,t)=>W(e,t)};(0,r.registerBlockType)("forwp/faq",{edit:e=>{const{attributes:l,setAttributes:i,clientId:s}=e,{getBlock:m,postId:f}=(0,c.useSelect)(e=>({getBlock:e("core/block-editor").getBlock,postId:e("core/editor")?.getCurrentPostId?.()||0}),[e.clientId]),{insertBlock:g,replaceBlock:_,replaceBlocks:E}=(0,c.useDispatch)("core/block-editor"),A=m(s),F=(A?.innerBlocks||[]).length>0,C=(0,a.useMemo)(()=>(e=>{const t=[],r=e=>{e.forEach(e=>{const o=e.name;if((e=>"string"==typeof e&&("core/accordion-item"===e||e.includes("accordion-item")))(o)||(e=>"string"==typeof e&&("core/details"===e||e.endsWith("/details")))(o)){const{question:r,answer:o}=(e=>{const t=e.attributes||{};let r=(t.title||t.summary||t.question||t.heading||"").trim(),o="";const n=e.innerBlocks||[];return!r&&n.length&&(r=u([n[0]]),n.length>1&&(o=u(n.slice(1)))),!o&&n.length&&(o=u(n)),{question:r.trim(),answer:o.trim()}})(e);r&&o&&t.push({question:r,answer:o})}e.innerBlocks&&e.innerBlocks.length&&r(e.innerBlocks)})};return r(e||[]),t})(A?.innerBlocks||[]),[A]),v=(0,a.useMemo)(()=>(A?.innerBlocks||[]).find(e=>"core/accordion"===e.name||"core/accordion-group"===e.name)||null,[A]),I=l.jsonLd||"",S=Array.isArray(l.categoryTermIds)?l.categoryTermIds:[],M=l.categoryTermId||0,O=S.length>0?S:M?[M]:[],x=l.categoryName||"",[T,Q]=(0,a.useState)(!(!x||!String(x).trim())),{terms:N,loading:D,registryReady:L}=(e=>{const[t,r]=(0,a.useState)([]),[o,n]=(0,a.useState)(!1),c=!!k().registrySetupComplete,l=k().categoriesPath||"/forwp-faq/v1/editor/categories";return(0,a.useEffect)(()=>{if(!c)return void r([]);let t=!1;n(!0);const o=e?`?post_id=${e}`:"";return p()({path:`${l}${o}`}).then(e=>{t||r(Array.isArray(e?.terms)?e.terms:[])}).catch(()=>{t||r([])}).finally(()=>{t||n(!1)}),()=>{t=!0}},[c,l,e]),{terms:t,loading:o,registryReady:c}})(f),J=(e=>{const t=e||"";return"enable"===t||"disable"!==t&&!!h()})(I),R=h(),H=(0,a.useMemo)(()=>C.length&&J?JSON.stringify({"@context":"https://schema.org","@type":"FAQPage",mainEntity:C.map(e=>({"@type":"Question",name:e.question,acceptedAnswer:{"@type":"Answer",text:e.answer}}))},null,2):"",[C,J]),W=R?(0,d.__)("Site-wide JSON-LD is on. Choose “Off for this block” to exclude this FAQ from structured data.","4wp-faq"):(0,d.__)("Site-wide JSON-LD is off. Choose “On for this block” to output FAQPage schema for this block only.","4wp-faq");return(0,t.createElement)(a.Fragment,null,(0,t.createElement)(o.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,null,(0,t.createElement)(n.ToolbarButton,{icon:"undo",text:P,label:P,onClick:()=>{const e=A?.innerBlocks||[];e.length?E([s],e.map(e=>(0,r.cloneBlock)(e))):_(s,q())}}))),(0,t.createElement)(o.InspectorControls,null,(0,t.createElement)(n.PanelBody,{title:(0,d.__)("SEO","4wp-faq"),initialOpen:!0},(0,t.createElement)(n.SelectControl,{label:(0,d.__)("JSON-LD on front end","4wp-faq"),help:W,value:I,options:[{label:R?(0,d.__)("Default (on — site setting)","4wp-faq"):(0,d.__)("Default (off — site setting)","4wp-faq"),value:""},{label:(0,d.__)("On for this block","4wp-faq"),value:"enable"},{label:(0,d.__)("Off for this block","4wp-faq"),value:"disable"}],onChange:e=>i({jsonLd:e||""})})),(0,t.createElement)(n.PanelBody,{title:(0,d.__)("Registry category","4wp-faq"),initialOpen:!1},L?D?(0,t.createElement)(n.Spinner,null):(0,t.createElement)(a.Fragment,null,(0,t.createElement)(n.FormTokenField,{label:(0,d.__)("FAQ categories","4wp-faq"),help:(0,d.__)("Search by name. The first category is the primary group for this FAQ. Applied on scan.","4wp-faq"),value:(O||[]).map(e=>N.find(t=>t.id===e)?.name).filter(Boolean),suggestions:N.map(e=>e.name),onChange:e=>{const t=(e||[]).map(e=>N.find(t=>t.name===e)?.id).filter(Boolean);i({categoryTermIds:t,categoryTermId:t[0]||0,categoryMode:t.length?B:x?"new":w})},__experimentalExpandOnFocus:!0,__nextHasNoMarginBottom:!0}),T?(0,t.createElement)(n.TextControl,{label:(0,d.__)("New category name","4wp-faq"),help:(0,d.__)("Created in the FAQ registry taxonomy on scan (language follows this page). Becomes primary if no existing category is selected.","4wp-faq"),value:x,onChange:e=>i({categoryName:e||"",categoryMode:O.length?B:e?"new":w})}):(0,t.createElement)(n.Button,{variant:"secondary",onClick:()=>Q(!0)},(0,d.__)("Add new","4wp-faq"))):(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,d.__)("Complete FAQ registry setup to assign categories during scan.","4wp-faq"))),(0,t.createElement)(n.PanelBody,{title:(0,d.__)("FAQ preview","4wp-faq"),initialOpen:!1},0===C.length?(0,t.createElement)(n.Notice,{status:"warning",isDismissible:!1},(0,d.__)("Add accordion items to generate FAQ schema.","4wp-faq")):null,!J&&C.length>0?(0,t.createElement)(n.Notice,{status:"info",isDismissible:!1},(0,d.__)("JSON-LD is off for this block on the front end.","4wp-faq")):null,(0,t.createElement)("p",null,(0,d.__)("Items:","4wp-faq")," ",C.length),(0,t.createElement)(n.TextareaControl,{label:(0,d.__)("Schema JSON-LD (preview)","4wp-faq"),value:H,rows:Math.min(12,Math.max(6,2*C.length)),readOnly:!0}))),(0,t.createElement)("div",{className:e.className},(0,t.createElement)(o.InnerBlocks,{allowedBlocks:b,template:F?void 0:[["core/accordion",{},[["core/accordion-item",{},[["core/accordion-heading",{content:(0,d.__)("Question","4wp-faq")}],["core/accordion-panel",{},[["core/paragraph",{placeholder:(0,d.__)("Answer…","4wp-faq")}]]]]]]]],templateLock:!1}),(0,t.createElement)("div",{className:"forwp-faq-editor-actions",style:{marginTop:"12px"}},(0,t.createElement)(n.Button,{variant:"secondary",onClick:()=>{const e=y();v?g(e,v.clientId,v.innerBlocks?.length||0):g(q(),s,0)}},(0,d.__)("Add FAQ item","4wp-faq")))))},save:()=>(0,t.createElement)(o.InnerBlocks.Content,null),transforms:{from:[{type:"block",blocks:["core/accordion","core/accordion-group"],transform:(e,t)=>(0,r.createBlock)("forwp/faq",{},[(0,r.createBlock)("core/accordion",e,t)])},{type:"block",blocks:["core/accordion-item"],isMultiBlock:!0,transform:(e,t)=>x(e,t)},{type:"block",blocks:["core/details"],isMultiBlock:!0,transform:(e,t)=>O(e,t)},D,{type:"block",blocks:["core/list"],transform:(e,t)=>W(e,t)}]}});const $=(0,i.createHigherOrderComponent)(e=>r=>{const l=g(r.name),i="core/accordion-item"===r.name,s="core/details"===r.name,p="core/list"===r.name;if(!(l||i||s||p))return(0,t.createElement)(e,{...r});const{replaceBlock:d,replaceBlocks:m}=(0,c.useDispatch)("core/block-editor"),{getBlock:u,getBlockRootClientId:k,getMultiSelectedBlockClientIds:h}=(0,c.useSelect)(e=>({getBlock:e("core/block-editor").getBlock,getBlockRootClientId:e("core/block-editor").getBlockRootClientId,getMultiSelectedBlockClientIds:e("core/block-editor").getMultiSelectedBlockClientIds}),[r.clientId]),w=h(),B=(w||[]).map(e=>u(e)).filter(Boolean),b=B.length>1&&B.every(e=>e.name===r.name)&&(s||i);return b&&w[0]!==r.clientId?(0,t.createElement)(e,{...r}):(0,t.createElement)(a.Fragment,null,(0,t.createElement)(e,{...r}),(0,t.createElement)(o.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,null,(0,t.createElement)(n.ToolbarButton,{icon:"editor-help",text:Q,label:Q,onClick:()=>{if(b){const e=B.map(e=>e.attributes),t=B.map(e=>e.innerBlocks),r=s?O(e,t):x(e,t);return void m(w,[r])}const e=u(r.clientId);if(!e)return;if(p)return void d(r.clientId,W(e.attributes,e.innerBlocks));if(s)return void d(r.clientId,f(e));if(l)return void d(r.clientId,f(e));const t=k(r.clientId),o=t?u(t):null;o&&g(o.name)?d(t,f(o)):d(r.clientId,x(e.attributes,e.innerBlocks))}}))))},"withFaqTransform");(0,l.addFilter)("editor.BlockEdit","forwp/faq/with-transform",$);const G=(0,i.createHigherOrderComponent)(e=>r=>{if(!E.includes(r.name))return(0,t.createElement)(e,{...r});const{getMultiSelectedBlockClientIds:l,getBlock:i}=(0,c.useSelect)(e=>({getMultiSelectedBlockClientIds:e("core/block-editor").getMultiSelectedBlockClientIds,getBlock:e("core/block-editor").getBlock}),[]),{replaceBlocks:s}=(0,c.useDispatch)("core/block-editor"),p=l(),d=p.length>=2?p.map(e=>i(e)).filter(Boolean):[],m=A(d),f=m&&p[0]===r.clientId;return(0,t.createElement)(a.Fragment,null,(0,t.createElement)(e,{...r}),f?(0,t.createElement)(o.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,null,(0,t.createElement)(n.ToolbarButton,{icon:"editor-help",text:Q,label:Q,onClick:()=>{m&&s(p,[S(d)])}}))):null)},"withHeadingParagraphFaqConvert");(0,l.addFilter)("editor.BlockEdit","forwp/faq/with-heading-paragraph-convert",G),(0,l.addFilter)("blocks.registerBlockType","forwp/faq/block-to-faq-transforms",(e,t)=>{if("core/heading"===t||"core/paragraph"===t||"core/quote"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,N]}}}if("core/list"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,j,N]}}}if("core/details"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,L]}}}if("core/accordion-item"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,J]}}}if("core/accordion"===t||"core/accordion-group"===t){const t=e.transforms?.to||[];return{...e,transforms:{...e.transforms,to:[...t,R]}}}return e})})(); -
4wp-faq/trunk/build/style-faq-card-rtl.css
r3685374 r3748403 1 .forwp-faq-card,.wp-block-forwp-faq-card{border-bottom:1px solid rgba(15,23,42,.12);margin:0}.forwp-faq-card__details{margin:0}.forwp-faq-card__question{color:var(--forwp-faq-q-color,inherit);cursor:pointer;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font- weight:var(--forwp-faq-q-weight,650);line-height:var(--forwp-faq-q-line,inherit);list-style:none;margin:0;padding:.9rem 0}.forwp-faq-card__question::-webkit-details-marker{display:none}.forwp-faq-card__details .forwp-faq-card__question:after{content:"+";float:left;font-weight:500;margin-right:.75rem}.forwp-faq-card__details[open] .forwp-faq-card__question:after{content:"–"}.forwp-faq-card.is-display-heading .forwp-faq-card__question{cursor:default;padding-bottom:.35rem}.forwp-faq-card__body{padding:0 0 1rem}.forwp-faq-card__answer{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-weight:var(--forwp-faq-a-weight,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:0}.forwp-faq-card .forwp-faq-card__answer div,.forwp-faq-card .forwp-faq-card__answer li,.forwp-faq-card .forwp-faq-card__answer p,.forwp-faq-card .forwp-faq-card__answer span,.wp-block-forwp-faq-card .forwp-faq-card__answer div,.wp-block-forwp-faq-card .forwp-faq-card__answer li,.wp-block-forwp-faq-card .forwp-faq-card__answer p,.wp-block-forwp-faq-card .forwp-faq-card__answer span{color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit}.forwp-faq-card__answer>:first-child{margin-top:0}.forwp-faq-card__answer>:last-child{margin-bottom:0}.forwp-faq-card__sources{margin-top:.85rem}.forwp-faq-card__sources-label{font-size:.75rem;font-weight:700;letter-spacing:.04em;margin:0 0 .35rem;opacity:.7;text-transform:uppercase}.forwp-faq-card__sources-list{list-style:none;margin:0;padding:0}.forwp-faq-card__sources-item{display:flex;flex-wrap:wrap;font-size:.875rem;gap:.35rem .75rem;margin:.2rem 0}.forwp-faq-card__sources-type{opacity:.65}.forwp-faq-card-editor{padding:.25rem 0}.forwp-faq-card-editor__question{color:var(--forwp-faq-q-color,inherit);display:block;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-weight:var(--forwp-faq-q-weight,650);margin:0}.forwp-faq-card-editor__answer,.forwp-faq-card-editor__sources{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-weight:var(--forwp-faq-a-weight,inherit);margin:.35rem 0 0;opacity:.75}1 .forwp-faq-card,.wp-block-forwp-faq-card{border-bottom:1px solid rgba(15,23,42,.12);margin:0}.forwp-faq-card__details{margin:0}.forwp-faq-card__question{color:var(--forwp-faq-q-color,inherit);cursor:pointer;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-style:var(--forwp-faq-q-style,inherit);font-weight:var(--forwp-faq-q-weight,650);letter-spacing:var(--forwp-faq-q-spacing,inherit);line-height:var(--forwp-faq-q-line,inherit);list-style:none;margin:0;padding:.9rem 0;-webkit-text-decoration:var(--forwp-faq-q-decoration,inherit);text-decoration:var(--forwp-faq-q-decoration,inherit);text-transform:var(--forwp-faq-q-transform,inherit)}.forwp-faq-card__question::-webkit-details-marker{display:none}.forwp-faq-card__details .forwp-faq-card__question:after{content:"+";float:left;font-weight:500;margin-right:.75rem}.forwp-faq-card__details[open] .forwp-faq-card__question:after{content:"–"}.forwp-faq-card.is-display-heading .forwp-faq-card__question{cursor:default;padding-bottom:.35rem}.forwp-faq-card__body{padding:0 0 1rem}.forwp-faq-card__answer{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-style:var(--forwp-faq-a-style,inherit);font-weight:var(--forwp-faq-a-weight,inherit);letter-spacing:var(--forwp-faq-a-spacing,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:0;-webkit-text-decoration:var(--forwp-faq-a-decoration,inherit);text-decoration:var(--forwp-faq-a-decoration,inherit);text-transform:var(--forwp-faq-a-transform,inherit)}.forwp-faq-card .forwp-faq-card__answer div,.forwp-faq-card .forwp-faq-card__answer li,.forwp-faq-card .forwp-faq-card__answer p,.forwp-faq-card .forwp-faq-card__answer span,.wp-block-forwp-faq-card .forwp-faq-card__answer div,.wp-block-forwp-faq-card .forwp-faq-card__answer li,.wp-block-forwp-faq-card .forwp-faq-card__answer p,.wp-block-forwp-faq-card .forwp-faq-card__answer span{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-transform:inherit}.forwp-faq-card__answer>:first-child{margin-top:0}.forwp-faq-card__answer>:last-child{margin-bottom:0}.forwp-faq-card__sources{align-items:baseline;display:flex;flex-wrap:wrap;gap:.25rem .5rem;margin-top:.85rem}.forwp-faq-card__sources-label{font-size:.75rem;font-weight:700;letter-spacing:.04em;margin:0;opacity:.7;text-transform:uppercase}.forwp-faq-card__sources-list{font-size:.875rem;margin:0}.forwp-faq-card__sources-item.is-inactive{cursor:not-allowed;opacity:.5}.forwp-faq-card__sources-type{opacity:.65}.forwp-faq-card-editor{padding:.25rem 0}.forwp-faq-card-editor__question{color:var(--forwp-faq-q-color,inherit);display:block;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-style:var(--forwp-faq-q-style,inherit);font-weight:var(--forwp-faq-q-weight,650);letter-spacing:var(--forwp-faq-q-spacing,inherit);line-height:var(--forwp-faq-q-line,inherit);margin:0;-webkit-text-decoration:var(--forwp-faq-q-decoration,inherit);text-decoration:var(--forwp-faq-q-decoration,inherit);text-transform:var(--forwp-faq-q-transform,inherit)}.forwp-faq-card-editor__answer,.forwp-faq-card-editor__sources{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-style:var(--forwp-faq-a-style,inherit);font-weight:var(--forwp-faq-a-weight,inherit);letter-spacing:var(--forwp-faq-a-spacing,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:.35rem 0 0;opacity:.75;-webkit-text-decoration:var(--forwp-faq-a-decoration,inherit);text-decoration:var(--forwp-faq-a-decoration,inherit);text-transform:var(--forwp-faq-a-transform,inherit)} -
4wp-faq/trunk/build/style-faq-card.css
r3685374 r3748403 1 .forwp-faq-card,.wp-block-forwp-faq-card{border-bottom:1px solid rgba(15,23,42,.12);margin:0}.forwp-faq-card__details{margin:0}.forwp-faq-card__question{color:var(--forwp-faq-q-color,inherit);cursor:pointer;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font- weight:var(--forwp-faq-q-weight,650);line-height:var(--forwp-faq-q-line,inherit);list-style:none;margin:0;padding:.9rem 0}.forwp-faq-card__question::-webkit-details-marker{display:none}.forwp-faq-card__details .forwp-faq-card__question:after{content:"+";float:right;font-weight:500;margin-left:.75rem}.forwp-faq-card__details[open] .forwp-faq-card__question:after{content:"–"}.forwp-faq-card.is-display-heading .forwp-faq-card__question{cursor:default;padding-bottom:.35rem}.forwp-faq-card__body{padding:0 0 1rem}.forwp-faq-card__answer{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-weight:var(--forwp-faq-a-weight,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:0}.forwp-faq-card .forwp-faq-card__answer div,.forwp-faq-card .forwp-faq-card__answer li,.forwp-faq-card .forwp-faq-card__answer p,.forwp-faq-card .forwp-faq-card__answer span,.wp-block-forwp-faq-card .forwp-faq-card__answer div,.wp-block-forwp-faq-card .forwp-faq-card__answer li,.wp-block-forwp-faq-card .forwp-faq-card__answer p,.wp-block-forwp-faq-card .forwp-faq-card__answer span{color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit}.forwp-faq-card__answer>:first-child{margin-top:0}.forwp-faq-card__answer>:last-child{margin-bottom:0}.forwp-faq-card__sources{margin-top:.85rem}.forwp-faq-card__sources-label{font-size:.75rem;font-weight:700;letter-spacing:.04em;margin:0 0 .35rem;opacity:.7;text-transform:uppercase}.forwp-faq-card__sources-list{list-style:none;margin:0;padding:0}.forwp-faq-card__sources-item{display:flex;flex-wrap:wrap;font-size:.875rem;gap:.35rem .75rem;margin:.2rem 0}.forwp-faq-card__sources-type{opacity:.65}.forwp-faq-card-editor{padding:.25rem 0}.forwp-faq-card-editor__question{color:var(--forwp-faq-q-color,inherit);display:block;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-weight:var(--forwp-faq-q-weight,650);margin:0}.forwp-faq-card-editor__answer,.forwp-faq-card-editor__sources{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-weight:var(--forwp-faq-a-weight,inherit);margin:.35rem 0 0;opacity:.75}1 .forwp-faq-card,.wp-block-forwp-faq-card{border-bottom:1px solid rgba(15,23,42,.12);margin:0}.forwp-faq-card__details{margin:0}.forwp-faq-card__question{color:var(--forwp-faq-q-color,inherit);cursor:pointer;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-style:var(--forwp-faq-q-style,inherit);font-weight:var(--forwp-faq-q-weight,650);letter-spacing:var(--forwp-faq-q-spacing,inherit);line-height:var(--forwp-faq-q-line,inherit);list-style:none;margin:0;padding:.9rem 0;-webkit-text-decoration:var(--forwp-faq-q-decoration,inherit);text-decoration:var(--forwp-faq-q-decoration,inherit);text-transform:var(--forwp-faq-q-transform,inherit)}.forwp-faq-card__question::-webkit-details-marker{display:none}.forwp-faq-card__details .forwp-faq-card__question:after{content:"+";float:right;font-weight:500;margin-left:.75rem}.forwp-faq-card__details[open] .forwp-faq-card__question:after{content:"–"}.forwp-faq-card.is-display-heading .forwp-faq-card__question{cursor:default;padding-bottom:.35rem}.forwp-faq-card__body{padding:0 0 1rem}.forwp-faq-card__answer{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-style:var(--forwp-faq-a-style,inherit);font-weight:var(--forwp-faq-a-weight,inherit);letter-spacing:var(--forwp-faq-a-spacing,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:0;-webkit-text-decoration:var(--forwp-faq-a-decoration,inherit);text-decoration:var(--forwp-faq-a-decoration,inherit);text-transform:var(--forwp-faq-a-transform,inherit)}.forwp-faq-card .forwp-faq-card__answer div,.forwp-faq-card .forwp-faq-card__answer li,.forwp-faq-card .forwp-faq-card__answer p,.forwp-faq-card .forwp-faq-card__answer span,.wp-block-forwp-faq-card .forwp-faq-card__answer div,.wp-block-forwp-faq-card .forwp-faq-card__answer li,.wp-block-forwp-faq-card .forwp-faq-card__answer p,.wp-block-forwp-faq-card .forwp-faq-card__answer span{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-transform:inherit}.forwp-faq-card__answer>:first-child{margin-top:0}.forwp-faq-card__answer>:last-child{margin-bottom:0}.forwp-faq-card__sources{align-items:baseline;display:flex;flex-wrap:wrap;gap:.25rem .5rem;margin-top:.85rem}.forwp-faq-card__sources-label{font-size:.75rem;font-weight:700;letter-spacing:.04em;margin:0;opacity:.7;text-transform:uppercase}.forwp-faq-card__sources-list{font-size:.875rem;margin:0}.forwp-faq-card__sources-item.is-inactive{cursor:not-allowed;opacity:.5}.forwp-faq-card__sources-type{opacity:.65}.forwp-faq-card-editor{padding:.25rem 0}.forwp-faq-card-editor__question{color:var(--forwp-faq-q-color,inherit);display:block;font-family:var(--forwp-faq-q-family,inherit);font-size:var(--forwp-faq-q-size,inherit);font-style:var(--forwp-faq-q-style,inherit);font-weight:var(--forwp-faq-q-weight,650);letter-spacing:var(--forwp-faq-q-spacing,inherit);line-height:var(--forwp-faq-q-line,inherit);margin:0;-webkit-text-decoration:var(--forwp-faq-q-decoration,inherit);text-decoration:var(--forwp-faq-q-decoration,inherit);text-transform:var(--forwp-faq-q-transform,inherit)}.forwp-faq-card-editor__answer,.forwp-faq-card-editor__sources{color:var(--forwp-faq-a-color,inherit);font-family:var(--forwp-faq-a-family,inherit);font-size:var(--forwp-faq-a-size,inherit);font-style:var(--forwp-faq-a-style,inherit);font-weight:var(--forwp-faq-a-weight,inherit);letter-spacing:var(--forwp-faq-a-spacing,inherit);line-height:var(--forwp-faq-a-line,inherit);margin:.35rem 0 0;opacity:.75;-webkit-text-decoration:var(--forwp-faq-a-decoration,inherit);text-decoration:var(--forwp-faq-a-decoration,inherit);text-transform:var(--forwp-faq-a-transform,inherit)} -
4wp-faq/trunk/build/style-faq-categories-rtl.css
r3691205 r3748403 1 .forwp-faq-categories,.wp-block-forwp-faq-categories{margin:0}.forwp-faq-categories__label{font-size:.7rem;font-weight:700;letter-spacing:.08em;margin:0 0 .75rem;opacity:.7;text-transform:uppercase}.forwp-faq-categories__ list{display:flex;flex-direction:column;gap:0;list-style:none;margin:0;padding:0}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__list{flex-direction:row;flex-wrap:wrap;gap:.35rem}.forwp-faq-categories.is-collapsible .forwp-faq-categories__item{align-items:center;display:grid;grid-template-columns:minmax(0,1fr) 1.75rem minmax(2.25em,max-content)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__link{grid-column:1;justify-content:flex-start;min-width:0}.forwp-faq-categories.is-collapsible .forwp-faq-categories__toggle{grid-column:2;grid-row:1;justify-self:center}.forwp-faq-categories.is-collapsible .forwp-faq-categories__count{font-variant-numeric:tabular-nums;grid-column:3;grid-row:1;justify-self:end;min-width:1.5em;text-align:left}.forwp-faq-categories.is-collapsible .forwp-faq-categories__children{grid-column:1/-1}.forwp-faq-categories__toggle{all:unset;align-items:center;background:transparent;border:0;border-radius:.25rem;box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;height:1.75rem;justify-content:center;line-height:0;margin:0;padding:0;width:1.75rem}.forwp-faq-categories__toggle:focus-visible,.forwp-faq-categories__toggle:hover{background:color-mix(in srgb,currentColor 12%,transparent);outline:none}.forwp-faq-categories__chevron{border:0;display:block;fill:none;height:.75rem;pointer-events:none;stroke:currentColor;transform:rotate(0deg);transform-origin:50% 50%;transition:transform .15s ease;width:.75rem}.forwp-faq-categories__item.is-expanded>.forwp-faq-categories__toggle .forwp-faq-categories__chevron{transform:rotate(-90deg)}.forwp-faq-categories__children{list-style:none;margin:0;padding:0 .85rem 0 0}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__children{flex-basis:100%;padding-right:0}.forwp-faq-categories__link{align-items:center;color:inherit;display:flex;gap:.5rem;justify-content:space-between;padding:.55rem 0;text-decoration:none}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__link{border:1px solid;padding:.4rem .75rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__toggle{height:1.5rem;width:1.5rem}.forwp-faq-categories__item.is-active .forwp-faq-categories__link,.forwp-faq-categories__link:focus-visible,.forwp-faq-categories__link:hover{font-weight:650;outline:none}.forwp-faq-categories__count{font-size:.75rem;opacity:.65}.forwp-faq-categories__empty{margin:0;opacity:.75}.forwp-faq-categories-editor__help{font-size:.8125rem;margin:.25rem 0 1rem;opacity:.75}1 .forwp-faq-categories,.wp-block-forwp-faq-categories{margin:0}.forwp-faq-categories__label{font-size:.7rem;font-weight:700;letter-spacing:.08em;margin:0 0 .75rem;opacity:.7;text-transform:uppercase}.forwp-faq-categories__menu{align-items:center;background:transparent;border:1px solid;color:inherit;cursor:pointer;display:none;font:inherit;gap:.5rem;line-height:1.2;margin:0 0 .75rem;padding:.6rem .75rem;text-align:right;width:100%}.forwp-faq-categories__menu-icon{display:block;flex:0 0 auto}.forwp-faq-categories__list{display:flex;flex-direction:column;gap:var(--forwp-faq-item-gap,0);list-style:none;margin:0;padding:0}@media(max-width:781px){.forwp-faq-categories__menu{display:flex}.forwp-faq-categories__list{display:none}.forwp-faq-categories.is-menu-open .forwp-faq-categories__list{display:flex;flex-direction:column}}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__list{flex-direction:row;flex-wrap:wrap;gap:var(--forwp-faq-item-gap,.35rem)}.forwp-faq-categories__item.is-all .forwp-faq-categories__term{font-size:var(--forwp-faq-all-size,inherit)}.forwp-faq-categories__item:not(.is-all) .forwp-faq-categories__term{font-size:var(--forwp-faq-item-size,inherit)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__item{align-items:center;display:grid;grid-template-columns:minmax(0,1fr) 1.75rem minmax(2.25em,max-content)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__link{grid-column:1;justify-content:flex-start;min-width:0}.forwp-faq-categories.is-collapsible .forwp-faq-categories__toggle{grid-column:2;grid-row:1;justify-self:center}.forwp-faq-categories.is-collapsible .forwp-faq-categories__count{font-variant-numeric:tabular-nums;grid-column:3;grid-row:1;justify-self:end;min-width:1.5em;text-align:left}.forwp-faq-categories.is-collapsible .forwp-faq-categories__children{grid-column:1/-1}.forwp-faq-categories__toggle{all:unset;align-items:center;background:transparent;border:0;border-radius:.25rem;box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;height:1.75rem;justify-content:center;line-height:0;margin:0;padding:0;width:1.75rem}.forwp-faq-categories__toggle:focus-visible,.forwp-faq-categories__toggle:hover{background:color-mix(in srgb,currentColor 12%,transparent);outline:none}.forwp-faq-categories__chevron{border:0;display:block;fill:none;height:.75rem;pointer-events:none;stroke:currentColor;transform:rotate(0deg);transform-origin:50% 50%;transition:transform .15s ease;width:.75rem}.forwp-faq-categories__item.is-expanded>.forwp-faq-categories__toggle .forwp-faq-categories__chevron{transform:rotate(-90deg)}.forwp-faq-categories__children{list-style:none;margin:0;padding:0 .85rem 0 0}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__children{flex-basis:100%;padding-right:0}.forwp-faq-categories__link{align-items:center;color:inherit;display:flex;gap:.5rem;justify-content:space-between;padding:.55rem 0;text-decoration:none}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__link{border:1px solid;padding:.4rem .75rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__toggle{height:1.5rem;width:1.5rem}.forwp-faq-categories__item.is-active .forwp-faq-categories__link,.forwp-faq-categories__link:focus-visible,.forwp-faq-categories__link:hover{font-weight:650;outline:none}.forwp-faq-categories__count{font-size:.75rem;opacity:.65}.forwp-faq-categories__empty{margin:0;opacity:.75}.forwp-faq-categories-editor__help{font-size:.8125rem;margin:.25rem 0 1rem;opacity:.75} -
4wp-faq/trunk/build/style-faq-categories.css
r3691205 r3748403 1 .forwp-faq-categories,.wp-block-forwp-faq-categories{margin:0}.forwp-faq-categories__label{font-size:.7rem;font-weight:700;letter-spacing:.08em;margin:0 0 .75rem;opacity:.7;text-transform:uppercase}.forwp-faq-categories__ list{display:flex;flex-direction:column;gap:0;list-style:none;margin:0;padding:0}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__list{flex-direction:row;flex-wrap:wrap;gap:.35rem}.forwp-faq-categories.is-collapsible .forwp-faq-categories__item{align-items:center;display:grid;grid-template-columns:minmax(0,1fr) 1.75rem minmax(2.25em,max-content)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__link{grid-column:1;justify-content:flex-start;min-width:0}.forwp-faq-categories.is-collapsible .forwp-faq-categories__toggle{grid-column:2;grid-row:1;justify-self:center}.forwp-faq-categories.is-collapsible .forwp-faq-categories__count{font-variant-numeric:tabular-nums;grid-column:3;grid-row:1;justify-self:end;min-width:1.5em;text-align:right}.forwp-faq-categories.is-collapsible .forwp-faq-categories__children{grid-column:1/-1}.forwp-faq-categories__toggle{all:unset;align-items:center;background:transparent;border:0;border-radius:.25rem;box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;height:1.75rem;justify-content:center;line-height:0;margin:0;padding:0;width:1.75rem}.forwp-faq-categories__toggle:focus-visible,.forwp-faq-categories__toggle:hover{background:color-mix(in srgb,currentColor 12%,transparent);outline:none}.forwp-faq-categories__chevron{border:0;display:block;fill:none;height:.75rem;pointer-events:none;stroke:currentColor;transform:rotate(0deg);transform-origin:50% 50%;transition:transform .15s ease;width:.75rem}.forwp-faq-categories__item.is-expanded>.forwp-faq-categories__toggle .forwp-faq-categories__chevron{transform:rotate(90deg)}.forwp-faq-categories__children{list-style:none;margin:0;padding:0 0 0 .85rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__children{flex-basis:100%;padding-left:0}.forwp-faq-categories__link{align-items:center;color:inherit;display:flex;gap:.5rem;justify-content:space-between;padding:.55rem 0;text-decoration:none}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__link{border:1px solid;padding:.4rem .75rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__toggle{height:1.5rem;width:1.5rem}.forwp-faq-categories__item.is-active .forwp-faq-categories__link,.forwp-faq-categories__link:focus-visible,.forwp-faq-categories__link:hover{font-weight:650;outline:none}.forwp-faq-categories__count{font-size:.75rem;opacity:.65}.forwp-faq-categories__empty{margin:0;opacity:.75}.forwp-faq-categories-editor__help{font-size:.8125rem;margin:.25rem 0 1rem;opacity:.75}1 .forwp-faq-categories,.wp-block-forwp-faq-categories{margin:0}.forwp-faq-categories__label{font-size:.7rem;font-weight:700;letter-spacing:.08em;margin:0 0 .75rem;opacity:.7;text-transform:uppercase}.forwp-faq-categories__menu{align-items:center;background:transparent;border:1px solid;color:inherit;cursor:pointer;display:none;font:inherit;gap:.5rem;line-height:1.2;margin:0 0 .75rem;padding:.6rem .75rem;text-align:left;width:100%}.forwp-faq-categories__menu-icon{display:block;flex:0 0 auto}.forwp-faq-categories__list{display:flex;flex-direction:column;gap:var(--forwp-faq-item-gap,0);list-style:none;margin:0;padding:0}@media(max-width:781px){.forwp-faq-categories__menu{display:flex}.forwp-faq-categories__list{display:none}.forwp-faq-categories.is-menu-open .forwp-faq-categories__list{display:flex;flex-direction:column}}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__list{flex-direction:row;flex-wrap:wrap;gap:var(--forwp-faq-item-gap,.35rem)}.forwp-faq-categories__item.is-all .forwp-faq-categories__term{font-size:var(--forwp-faq-all-size,inherit)}.forwp-faq-categories__item:not(.is-all) .forwp-faq-categories__term{font-size:var(--forwp-faq-item-size,inherit)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__item{align-items:center;display:grid;grid-template-columns:minmax(0,1fr) 1.75rem minmax(2.25em,max-content)}.forwp-faq-categories.is-collapsible .forwp-faq-categories__link{grid-column:1;justify-content:flex-start;min-width:0}.forwp-faq-categories.is-collapsible .forwp-faq-categories__toggle{grid-column:2;grid-row:1;justify-self:center}.forwp-faq-categories.is-collapsible .forwp-faq-categories__count{font-variant-numeric:tabular-nums;grid-column:3;grid-row:1;justify-self:end;min-width:1.5em;text-align:right}.forwp-faq-categories.is-collapsible .forwp-faq-categories__children{grid-column:1/-1}.forwp-faq-categories__toggle{all:unset;align-items:center;background:transparent;border:0;border-radius:.25rem;box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;height:1.75rem;justify-content:center;line-height:0;margin:0;padding:0;width:1.75rem}.forwp-faq-categories__toggle:focus-visible,.forwp-faq-categories__toggle:hover{background:color-mix(in srgb,currentColor 12%,transparent);outline:none}.forwp-faq-categories__chevron{border:0;display:block;fill:none;height:.75rem;pointer-events:none;stroke:currentColor;transform:rotate(0deg);transform-origin:50% 50%;transition:transform .15s ease;width:.75rem}.forwp-faq-categories__item.is-expanded>.forwp-faq-categories__toggle .forwp-faq-categories__chevron{transform:rotate(90deg)}.forwp-faq-categories__children{list-style:none;margin:0;padding:0 0 0 .85rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__children{flex-basis:100%;padding-left:0}.forwp-faq-categories__link{align-items:center;color:inherit;display:flex;gap:.5rem;justify-content:space-between;padding:.55rem 0;text-decoration:none}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__link{border:1px solid;padding:.4rem .75rem}.forwp-faq-categories.is-orientation-horizontal .forwp-faq-categories__toggle{height:1.5rem;width:1.5rem}.forwp-faq-categories__item.is-active .forwp-faq-categories__link,.forwp-faq-categories__link:focus-visible,.forwp-faq-categories__link:hover{font-weight:650;outline:none}.forwp-faq-categories__count{font-size:.75rem;opacity:.65}.forwp-faq-categories__empty{margin:0;opacity:.75}.forwp-faq-categories-editor__help{font-size:.8125rem;margin:.25rem 0 1rem;opacity:.75} -
4wp-faq/trunk/build/style-faq-list-rtl.css
r3685374 r3748403 1 .forwp-faq-list,.wp-block-forwp-faq-list{display:flex;flex-direction:column;gap:2rem}.forwp-faq-list__group{display:flex;flex-direction:column;gap:.75rem}.forwp-faq-list__group.is-child .forwp-faq-list__group-title{font-size:1.1rem}.forwp-faq-list __children{display:flex;flex-direction:column;gap:1.25rem;margin-top:.5rem;padding-right:.85rem}.forwp-faq-list__more{margin:.75rem 0 0}.forwp-faq-list__more-link{font-size:.9rem}.forwp-faq-list__items{display:flex;flex-direction:column;gap:0}.forwp-faq-list__empty{margin:0;opacity:.75}.forwp-faq-card[hidden],.forwp-faq-list__group[hidden],.wp-block-forwp-faq-card[hidden]{display:none!important}.forwp-faq-list-editor__template{border:1px dashed;margin-bottom:1.5rem;opacity:.9;padding:.75rem 1rem}.forwp-faq-list-editor__help,.forwp-faq-list-editor__hint{font-size:.8125rem;margin:0 0 .75rem;opacity:.75}.forwp-faq-list-editor__help{margin:.25rem 0 1rem}.forwp-faq-typography-help{color:#757575;font-size:12px;line-height:1.4;margin:0 16px 8px}1 .forwp-faq-list,.wp-block-forwp-faq-list{display:flex;flex-direction:column;gap:2rem}.forwp-faq-list__group{display:flex;flex-direction:column;gap:.75rem}.forwp-faq-list__group.is-child .forwp-faq-list__group-title{font-size:1.1rem}.forwp-faq-list.has-g-size .forwp-faq-list__group-title{font-size:var(--forwp-faq-g-size)}.forwp-faq-list.has-g-family .forwp-faq-list__group-title{font-family:var(--forwp-faq-g-family)}.forwp-faq-list.has-g-weight .forwp-faq-list__group-title{font-weight:var(--forwp-faq-g-weight)}.forwp-faq-list.has-g-color .forwp-faq-list__group-title{color:var(--forwp-faq-g-color)}.forwp-faq-list.has-g-style .forwp-faq-list__group-title{font-style:var(--forwp-faq-g-style)}.forwp-faq-list.has-g-line .forwp-faq-list__group-title{line-height:var(--forwp-faq-g-line)}.forwp-faq-list.has-g-spacing .forwp-faq-list__group-title{letter-spacing:var(--forwp-faq-g-spacing)}.forwp-faq-list.has-g-decoration .forwp-faq-list__group-title{-webkit-text-decoration:var(--forwp-faq-g-decoration);text-decoration:var(--forwp-faq-g-decoration)}.forwp-faq-list.has-g-transform .forwp-faq-list__group-title{text-transform:var(--forwp-faq-g-transform)}.forwp-faq-list__children{display:flex;flex-direction:column;gap:1.25rem;margin-top:.5rem;padding-right:.85rem}.forwp-faq-list__more{margin:.75rem 0 0}.forwp-faq-list__more-link{font-size:.9rem}.forwp-faq-list__items{display:flex;flex-direction:column;gap:0}.forwp-faq-list__empty{margin:0;opacity:.75}.forwp-faq-card[hidden],.forwp-faq-list__group[hidden],.forwp-faq-list__no-results[hidden],.wp-block-forwp-faq-card[hidden]{display:none!important}.forwp-faq-no-results-editor{border:1px dashed rgba(15,23,42,.25);margin-top:.75rem;padding:.5rem .75rem}.forwp-faq-list-editor__template{border:1px dashed;margin-bottom:1.5rem;opacity:.9;padding:.75rem 1rem}.forwp-faq-list-editor__help,.forwp-faq-list-editor__hint{font-size:.8125rem;margin:0 0 .75rem;opacity:.75}.forwp-faq-list-editor__help{margin:.25rem 0 1rem} -
4wp-faq/trunk/build/style-faq-list.css
r3685374 r3748403 1 .forwp-faq-list,.wp-block-forwp-faq-list{display:flex;flex-direction:column;gap:2rem}.forwp-faq-list__group{display:flex;flex-direction:column;gap:.75rem}.forwp-faq-list__group.is-child .forwp-faq-list__group-title{font-size:1.1rem}.forwp-faq-list __children{display:flex;flex-direction:column;gap:1.25rem;margin-top:.5rem;padding-left:.85rem}.forwp-faq-list__more{margin:.75rem 0 0}.forwp-faq-list__more-link{font-size:.9rem}.forwp-faq-list__items{display:flex;flex-direction:column;gap:0}.forwp-faq-list__empty{margin:0;opacity:.75}.forwp-faq-card[hidden],.forwp-faq-list__group[hidden],.wp-block-forwp-faq-card[hidden]{display:none!important}.forwp-faq-list-editor__template{border:1px dashed;margin-bottom:1.5rem;opacity:.9;padding:.75rem 1rem}.forwp-faq-list-editor__help,.forwp-faq-list-editor__hint{font-size:.8125rem;margin:0 0 .75rem;opacity:.75}.forwp-faq-list-editor__help{margin:.25rem 0 1rem}.forwp-faq-typography-help{color:#757575;font-size:12px;line-height:1.4;margin:0 16px 8px}1 .forwp-faq-list,.wp-block-forwp-faq-list{display:flex;flex-direction:column;gap:2rem}.forwp-faq-list__group{display:flex;flex-direction:column;gap:.75rem}.forwp-faq-list__group.is-child .forwp-faq-list__group-title{font-size:1.1rem}.forwp-faq-list.has-g-size .forwp-faq-list__group-title{font-size:var(--forwp-faq-g-size)}.forwp-faq-list.has-g-family .forwp-faq-list__group-title{font-family:var(--forwp-faq-g-family)}.forwp-faq-list.has-g-weight .forwp-faq-list__group-title{font-weight:var(--forwp-faq-g-weight)}.forwp-faq-list.has-g-color .forwp-faq-list__group-title{color:var(--forwp-faq-g-color)}.forwp-faq-list.has-g-style .forwp-faq-list__group-title{font-style:var(--forwp-faq-g-style)}.forwp-faq-list.has-g-line .forwp-faq-list__group-title{line-height:var(--forwp-faq-g-line)}.forwp-faq-list.has-g-spacing .forwp-faq-list__group-title{letter-spacing:var(--forwp-faq-g-spacing)}.forwp-faq-list.has-g-decoration .forwp-faq-list__group-title{-webkit-text-decoration:var(--forwp-faq-g-decoration);text-decoration:var(--forwp-faq-g-decoration)}.forwp-faq-list.has-g-transform .forwp-faq-list__group-title{text-transform:var(--forwp-faq-g-transform)}.forwp-faq-list__children{display:flex;flex-direction:column;gap:1.25rem;margin-top:.5rem;padding-left:.85rem}.forwp-faq-list__more{margin:.75rem 0 0}.forwp-faq-list__more-link{font-size:.9rem}.forwp-faq-list__items{display:flex;flex-direction:column;gap:0}.forwp-faq-list__empty{margin:0;opacity:.75}.forwp-faq-card[hidden],.forwp-faq-list__group[hidden],.forwp-faq-list__no-results[hidden],.wp-block-forwp-faq-card[hidden]{display:none!important}.forwp-faq-no-results-editor{border:1px dashed rgba(15,23,42,.25);margin-top:.75rem;padding:.5rem .75rem}.forwp-faq-list-editor__template{border:1px dashed;margin-bottom:1.5rem;opacity:.9;padding:.75rem 1rem}.forwp-faq-list-editor__help,.forwp-faq-list-editor__hint{font-size:.8125rem;margin:0 0 .75rem;opacity:.75}.forwp-faq-list-editor__help{margin:.25rem 0 1rem} -
4wp-faq/trunk/includes/class-admin-dashboard.php
r3685374 r3748403 268 268 $rows = [ 269 269 [ 270 'class' => 'questions',271 270 'url' => $list, 272 'html' => sprintf( 273 /* translators: %s: count */ 274 __( 'Questions <strong>%s</strong>', '4wp-faq' ), 275 number_format_i18n( (int) ( $stats['total_questions'] ?? 0 ) ) 276 ), 277 ], 278 [ 279 'class' => 'categories', 271 'value' => (int) ( $stats['total_questions'] ?? 0 ), 272 'label' => __( 'Questions', '4wp-faq' ), 273 ], 274 [ 280 275 'url' => $cats, 281 'html' => sprintf( 282 /* translators: %s: count */ 283 __( 'Categories <strong>%s</strong>', '4wp-faq' ), 284 number_format_i18n( (int) ( $stats['faq_categories'] ?? 0 ) ) 285 ), 286 ], 287 [ 288 'class' => 'reused', 276 'value' => (int) ( $stats['faq_categories'] ?? 0 ), 277 'label' => __( 'Categories', '4wp-faq' ), 278 ], 279 [ 289 280 'url' => $list, 290 'html' => sprintf( 291 /* translators: %s: count */ 292 __( 'Reused <strong>%s</strong>', '4wp-faq' ), 293 number_format_i18n( (int) ( $stats['reused_questions'] ?? 0 ) ) 294 ), 295 ], 296 [ 297 'class' => 'once', 281 'value' => (int) ( $stats['reused_questions'] ?? 0 ), 282 'label' => __( 'Reused', '4wp-faq' ), 283 ], 284 [ 298 285 'url' => $list, 299 'html' => sprintf( 300 /* translators: %s: count */ 301 __( 'Used once <strong>%s</strong>', '4wp-faq' ), 302 number_format_i18n( (int) ( $stats['single_use_questions'] ?? 0 ) ) 303 ), 304 ], 305 [ 306 'class' => 'pages', 286 'value' => (int) ( $stats['single_use_questions'] ?? 0 ), 287 'label' => __( 'Used once', '4wp-faq' ), 288 ], 289 [ 307 290 'url' => admin_url( 'edit.php?post_type=page' ), 308 'html' => sprintf( 309 /* translators: %s: count */ 310 __( 'Pages with FAQ <strong>%s</strong>', '4wp-faq' ), 311 number_format_i18n( (int) ( $stats['pages_with_faq'] ?? 0 ) ) 312 ), 313 ], 314 [ 315 'class' => 'posts', 291 'value' => (int) ( $stats['pages_with_faq'] ?? 0 ), 292 'label' => __( 'Pages with FAQ', '4wp-faq' ), 293 ], 294 [ 316 295 'url' => admin_url( 'edit.php' ), 317 'html' => sprintf( 318 /* translators: %s: count */ 319 __( 'Posts with FAQ <strong>%s</strong>', '4wp-faq' ), 320 number_format_i18n( (int) ( $stats['posts_with_faq'] ?? 0 ) ) 321 ), 322 ], 323 [ 324 'class' => 'uncat', 296 'value' => (int) ( $stats['posts_with_faq'] ?? 0 ), 297 'label' => __( 'Posts with FAQ', '4wp-faq' ), 298 ], 299 [ 325 300 'url' => $list, 326 'html' => sprintf( 327 /* translators: %s: count */ 328 __( 'Uncategorized <strong>%s</strong>', '4wp-faq' ), 329 number_format_i18n( (int) ( $stats['uncategorized'] ?? 0 ) ) 330 ), 331 ], 332 [ 333 'class' => 'unused', 301 'value' => (int) ( $stats['uncategorized'] ?? 0 ), 302 'label' => __( 'Uncategorized', '4wp-faq' ), 303 ], 304 [ 334 305 'url' => $list, 335 'html' => sprintf( 336 /* translators: %s: count */ 337 __( 'Unused <strong>%s</strong>', '4wp-faq' ), 338 number_format_i18n( (int) ( $stats['unused_questions'] ?? 0 ) ) 339 ), 306 'value' => (int) ( $stats['unused_questions'] ?? 0 ), 307 'label' => __( 'Unused', '4wp-faq' ), 340 308 ], 341 309 ]; 342 310 343 echo '<ul class="forwp-faq-status-list">'; 311 self::render_language_note( $data ); 312 313 echo '<div class="forwp-faq-stats">'; 344 314 foreach ( $rows as $row ) { 345 echo '< li class="' . esc_attr( $row['class'] ) . '">';346 echo '< a href="' . esc_url( $row['url'] ) . '">';347 echo wp_kses( $row['html'], [ 'strong' => [] ] );348 echo '</a> </li>';349 } 350 echo '</ ul>';315 echo '<a class="forwp-faq-stat-cell" href="' . esc_url( $row['url'] ) . '">'; 316 echo '<span class="forwp-faq-stat-cell__value">' . esc_html( number_format_i18n( $row['value'] ) ) . '</span>'; 317 echo '<span class="forwp-faq-stat-cell__label">' . esc_html( $row['label'] ) . '</span>'; 318 echo '</a>'; 319 } 320 echo '</div>'; 351 321 352 322 echo '<div class="forwp-faq-dash-meta">'; … … 374 344 } 375 345 echo '</div>'; 346 } 347 348 /** 349 * Which language the numbers are for; per-language breakdown when "All languages" is selected. 350 * 351 * @param array<string, mixed> $data Dashboard data. 352 */ 353 public static function render_language_note( $data ) { 354 $name = isset( $data['language']['name'] ) ? (string) $data['language']['name'] : ''; 355 if ( '' === $name ) { 356 return; 357 } 358 359 echo '<p class="forwp-faq-dash-lang">'; 360 echo esc_html( 361 sprintf( 362 /* translators: %s: language name or "All languages" */ 363 __( 'Language: %s', '4wp-faq' ), 364 $name 365 ) 366 ); 367 echo '</p>'; 368 369 $rows = isset( $data['by_language'] ) && is_array( $data['by_language'] ) ? $data['by_language'] : []; 370 if ( empty( $rows ) ) { 371 return; 372 } 373 374 echo '<table class="forwp-faq-dash-langs widefat striped"><thead><tr>'; 375 echo '<th>' . esc_html__( 'Language', '4wp-faq' ) . '</th>'; 376 echo '<th>' . esc_html__( 'Questions', '4wp-faq' ) . '</th>'; 377 echo '<th>' . esc_html__( 'Categories', '4wp-faq' ) . '</th>'; 378 echo '<th>' . esc_html__( 'Uncategorized', '4wp-faq' ) . '</th>'; 379 echo '<th>' . esc_html__( 'Pages with FAQ', '4wp-faq' ) . '</th>'; 380 echo '</tr></thead><tbody>'; 381 foreach ( $rows as $row ) { 382 echo '<tr>'; 383 echo '<td>' . esc_html( (string) ( $row['name'] ?? '' ) ) . '</td>'; 384 foreach ( [ 'questions', 'categories', 'uncategorized', 'pages' ] as $key ) { 385 echo '<td>' . esc_html( number_format_i18n( (int) ( $row[ $key ] ?? 0 ) ) ) . '</td>'; 386 } 387 echo '</tr>'; 388 } 389 echo '</tbody></table>'; 376 390 } 377 391 -
4wp-faq/trunk/includes/class-dashboard-setup.php
r3552602 r3748403 15 15 public static function init() { 16 16 add_action( 'wp_dashboard_setup', [ __CLASS__, 'register_widget' ] ); 17 add_action( 'admin_enqueue_scripts', [ __CLASS__, 'enqueue' ] ); 18 } 19 20 /** 21 * Status list styles on the main Dashboard. 22 * 23 * @param string $hook Current admin page. 24 */ 25 public static function enqueue( $hook ) { 26 if ( 'index.php' !== $hook ) { 27 return; 28 } 29 30 wp_enqueue_style( 31 'forwp-faq-dashboard', 32 FORWP_FAQ_PLUGIN_URL . 'assets/admin-dashboard.css', 33 [], 34 FORWP_FAQ_VERSION 35 ); 17 36 } 18 37 … … 21 40 */ 22 41 public static function register_widget() { 23 if ( ! current_user_can( ' manage_options' ) ) {42 if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'manage_options' ) ) { 24 43 return; 25 44 } 26 45 27 if ( Settings::is_setup_complete() ) { 46 if ( ! Settings::is_setup_complete() ) { 47 if ( ! current_user_can( 'manage_options' ) ) { 48 return; 49 } 50 51 wp_add_dashboard_widget( 52 'forwp_faq_dashboard_setup', 53 __( '4WP FAQ Setup', '4wp-faq' ), 54 [ __CLASS__, 'render_widget' ] 55 ); 28 56 return; 29 57 } 30 58 31 59 wp_add_dashboard_widget( 32 'forwp_faq_ dashboard_setup',33 __( ' 4WP FAQ Setup', '4wp-faq' ),34 [ __CLASS__, 'render_ widget' ]60 'forwp_faq_home', 61 __( 'FAQ', '4wp-faq' ), 62 [ __CLASS__, 'render_home' ] 35 63 ); 64 } 65 66 /** 67 * Condensed status on the main Dashboard, with a link to the FAQ dashboard. 68 */ 69 public static function render_home() { 70 $data = Plugin::get_dashboard_data(); 71 $stats = isset( $data['stats'] ) && is_array( $data['stats'] ) ? $data['stats'] : []; 72 $url = Admin_Settings::get_dashboard_url(); 73 $list = admin_url( 'edit.php?post_type=' . rawurlencode( Settings::get_post_type() ) ); 74 $cats = isset( $data['categories_url'] ) ? (string) $data['categories_url'] : $list; 75 76 $rows = [ 77 [ 78 'class' => 'questions', 79 'href' => $list, 80 'html' => sprintf( 81 /* translators: %s: count */ 82 __( 'Questions <strong>%s</strong>', '4wp-faq' ), 83 number_format_i18n( (int) ( $stats['total_questions'] ?? 0 ) ) 84 ), 85 ], 86 [ 87 'class' => 'categories', 88 'href' => $cats, 89 'html' => sprintf( 90 /* translators: %s: count */ 91 __( 'Categories <strong>%s</strong>', '4wp-faq' ), 92 number_format_i18n( (int) ( $stats['faq_categories'] ?? 0 ) ) 93 ), 94 ], 95 [ 96 'class' => 'reused', 97 'href' => $list, 98 'html' => sprintf( 99 /* translators: %s: count */ 100 __( 'Reused <strong>%s</strong>', '4wp-faq' ), 101 number_format_i18n( (int) ( $stats['reused_questions'] ?? 0 ) ) 102 ), 103 ], 104 [ 105 'class' => 'uncat', 106 'href' => $list, 107 'html' => sprintf( 108 /* translators: %s: count */ 109 __( 'Uncategorized <strong>%s</strong>', '4wp-faq' ), 110 number_format_i18n( (int) ( $stats['uncategorized'] ?? 0 ) ) 111 ), 112 ], 113 ]; 114 115 Admin_Dashboard::render_language_note( $data ); 116 117 echo '<ul class="forwp-faq-status-list">'; 118 foreach ( $rows as $row ) { 119 echo '<li class="' . esc_attr( $row['class'] ) . '">'; 120 echo '<a href="' . esc_url( $row['href'] ) . '">'; 121 echo wp_kses( $row['html'], [ 'strong' => [] ] ); 122 echo '</a></li>'; 123 } 124 echo '</ul>'; 125 126 echo '<div class="forwp-faq-dash-meta">'; 127 echo '<span>'; 128 if ( ! empty( $data['last_scan_label'] ) ) { 129 echo esc_html( 130 sprintf( 131 /* translators: %s: date/time */ 132 __( 'Last scan: %s', '4wp-faq' ), 133 $data['last_scan_label'] 134 ) 135 ); 136 } else { 137 echo esc_html__( 'Not scanned yet.', '4wp-faq' ); 138 } 139 echo '</span>'; 140 echo '<a class="button button-primary" href="' . esc_url( $url ) . '">'; 141 echo esc_html__( 'Open dashboard', '4wp-faq' ); 142 echo '</a>'; 143 echo '</div>'; 36 144 } 37 145 -
4wp-faq/trunk/includes/class-display-blocks.php
r3698640 r3748403 7 7 8 8 namespace ForWP\FAQ; 9 10 use ForWP\FAQ\Integrations\Polylang; 9 11 10 12 if ( ! defined( 'ABSPATH' ) ) { … … 20 22 public const CATEGORIES_BLOCK = 'forwp/faq-categories'; 21 23 public const COUNT_BLOCK = 'forwp/faq-count'; 24 public const NO_RESULTS_BLOCK = 'forwp/faq-no-results'; 22 25 public const STORE = 'forwp/faq'; 23 26 … … 38 41 add_action( 'init', [ __CLASS__, 'register_blocks' ] ); 39 42 add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'localize_editor_scripts' ], 20 ); 43 add_filter( 'rest_pre_dispatch', [ __CLASS__, 'strip_unknown_preview_attributes' ], 10, 3 ); 40 44 add_filter( 'render_block_core/search', [ __CLASS__, 'render_related_search' ], 10, 2 ); 41 45 /** … … 76 80 'render' => [ __CLASS__, 'render_count' ], 77 81 ], 82 'faq-no-results' => [ 83 'script' => self::LIST_SCRIPT, 84 'style' => self::LIST_STYLE, 85 'render' => [ __CLASS__, 'render_no_results' ], 86 ], 78 87 ]; 79 88 … … 184 193 ]; 185 194 186 foreach ( [ self::LIST_SCRIPT, self::CARD_SCRIPT, self::CATEGORIES_SCRIPT, self::COUNT_SCRIPT ] as $handle ) { 187 if ( wp_script_is( $handle, 'registered' ) ) { 195 $registry = \WP_Block_Type_Registry::get_instance(); 196 197 foreach ( [ self::LIST_BLOCK, self::CARD_BLOCK, self::CATEGORIES_BLOCK, self::COUNT_BLOCK ] as $block_name ) { 198 $block = $registry->get_registered( $block_name ); 199 200 if ( ! $block || empty( $block->editor_script_handles ) ) { 201 continue; 202 } 203 204 foreach ( $block->editor_script_handles as $handle ) { 188 205 wp_localize_script( $handle, 'forwpFaqDisplay', $config ); 189 206 } 190 207 } 208 } 209 210 /** 211 * Drop attributes the editor added but this block does not register. 212 * 213 * Other plugins attach attributes to every block in the editor. The block 214 * renderer rejects unknown keys with HTTP 400, and the preview then shows 215 * "Error loading block: [object Object]". 216 * 217 * @param mixed $result Response to replace, or null to continue. 218 * @param \WP_REST_Server $server Server instance. 219 * @param \WP_REST_Request $request Request used to generate the response. 220 * @return mixed 221 */ 222 public static function strip_unknown_preview_attributes( $result, $server, $request ) { 223 unset( $server ); 224 225 if ( null !== $result || ! $request instanceof \WP_REST_Request ) { 226 return $result; 227 } 228 229 $route = $request->get_route(); 230 $prefix = '/wp/v2/block-renderer/'; 231 232 if ( ! is_string( $route ) || ! str_starts_with( $route, $prefix ) ) { 233 return $result; 234 } 235 236 $name = rawurldecode( substr( $route, strlen( $prefix ) ) ); 237 $ours = [ self::LIST_BLOCK, self::CARD_BLOCK, self::CATEGORIES_BLOCK, self::COUNT_BLOCK ]; 238 239 if ( ! in_array( $name, $ours, true ) ) { 240 return $result; 241 } 242 243 // Polylang does not filter REST queries: preview in the edited page's language, like the front end. 244 $post_id = (int) $request->get_param( 'post_id' ); 245 if ( $post_id > 0 ) { 246 $lang = Polylang::get_post_language( $post_id ); 247 if ( '' !== $lang ) { 248 Polylang::force_language( $lang ); 249 } 250 } 251 252 $attributes = $request->get_param( 'attributes' ); 253 254 if ( ! is_array( $attributes ) ) { 255 return $result; 256 } 257 258 $block = \WP_Block_Type_Registry::get_instance()->get_registered( $name ); 259 260 if ( ! $block ) { 261 return $result; 262 } 263 264 $allowed = array_fill_keys( array_keys( $block->get_attributes() ), true ); 265 $request->set_param( 'attributes', array_intersect_key( $attributes, $allowed ) ); 266 267 return $result; 191 268 } 192 269 … … 252 329 self::ensure_runtime(); 253 330 331 $group_title = self::group_title_vars( $attributes['groupTitleStyle'] ?? [] ); 332 254 333 $wrapper_attrs = [ 255 'class' => 'forwp-faq-list is-layout-' . $layout,334 'class' => trim( 'forwp-faq-list is-layout-' . $layout . ' ' . $group_title['class'] ), 256 335 'data-wp-interactive' => self::STORE, 257 336 ]; 258 337 259 $typo_style = self::typography_style_attr( $card_attrs ); 338 $typo_style = implode( 339 ';', 340 array_filter( [ self::typography_style_attr( $card_attrs ), $group_title['style'] ] ) 341 ); 260 342 if ( '' !== $typo_style ) { 261 343 $wrapper_attrs['style'] = $typo_style; … … 289 371 } 290 372 373 $html .= self::render_list_no_results( $block ); 291 374 $html .= '</div>'; 292 375 293 376 return $html; 377 } 378 379 /** 380 * The list's inner No Results block, or a default message for lists saved before it existed. 381 * 382 * @param \WP_Block|null $block List block instance. 383 * @return string 384 */ 385 private static function render_list_no_results( $block ) { 386 if ( $block instanceof \WP_Block && ! empty( $block->parsed_block['innerBlocks'] ) ) { 387 foreach ( $block->parsed_block['innerBlocks'] as $inner ) { 388 if ( self::NO_RESULTS_BLOCK === ( $inner['blockName'] ?? '' ) ) { 389 return render_block( $inner ); 390 } 391 } 392 } 393 394 return '<div ' . self::plain_attributes( self::no_results_attrs() ) . ' hidden><p>' 395 . esc_html__( 'No questions found. Try another search.', '4wp-faq' ) 396 . '</p></div>'; 397 } 398 399 /** 400 * Render 4WP FAQ No Results (hidden until a search matches nothing). 401 * 402 * @param array $attributes Block attributes. 403 * @param string $content Inner blocks HTML. 404 * @return string 405 */ 406 public static function render_no_results( $attributes, $content = '' ) { 407 unset( $attributes ); 408 409 return '<div ' . get_block_wrapper_attributes( self::no_results_attrs() ) . ' hidden>' . $content . '</div>'; 410 } 411 412 /** 413 * @return array<string, string> 414 */ 415 private static function no_results_attrs() { 416 return [ 417 'class' => 'forwp-faq-list__no-results', 418 'data-wp-interactive' => self::STORE, 419 'data-wp-bind--hidden' => '!state.hasNoResults', 420 ]; 421 } 422 423 /** 424 * @param array<string, string> $attrs Attribute map. 425 * @return string 426 */ 427 private static function plain_attributes( $attrs ) { 428 $out = ''; 429 foreach ( $attrs as $name => $value ) { 430 $out .= ' ' . $name . '="' . esc_attr( $value ) . '"'; 431 } 432 433 return ltrim( $out ); 294 434 } 295 435 … … 315 455 ? $attributes['allLabel'] 316 456 : __( 'All categories', '4wp-faq' ); 317 $nav_label = isset( $attributes['label'] ) && is_string( $attributes['label'] ) && '' !== $attributes['label']318 ? $attributes['label']319 : __( 'Categories', '4wp-faq' );457 $nav_label = isset( $attributes['label'] ) && is_string( $attributes['label'] ) 458 ? trim( $attributes['label'] ) 459 : ''; 320 460 321 461 if ( 'horizontal' !== $orientation ) { … … 330 470 } 331 471 332 $wrapper = get_block_wrapper_attributes( 333 [ 334 'class' => $nav_class, 335 'data-wp-interactive' => self::STORE, 336 ] 337 ); 472 $wrapper_attrs = [ 473 'class' => $nav_class, 474 'data-wp-interactive' => self::STORE, 475 'data-wp-class--is-menu-open' => 'state.isMenuOpen', 476 ]; 477 $size_style = self::categories_size_vars( $attributes ); 478 if ( '' !== $size_style ) { 479 $wrapper_attrs['style'] = $size_style; 480 } 481 482 $wrapper = get_block_wrapper_attributes( $wrapper_attrs ); 338 483 339 484 if ( ! Settings::is_setup_complete() ) { … … 351 496 : 'forwp-faq-cats-label'; 352 497 353 $html = '<nav ' . $wrapper . ' aria-labelledby="' . esc_attr( $label_id ) . '">'; 354 $html .= '<p class="forwp-faq-categories__label" id="' . esc_attr( $label_id ) . '">' . esc_html( $nav_label ) . '</p>'; 355 $html .= '<ul class="forwp-faq-categories__list" role="list">'; 498 $list_id = function_exists( 'wp_unique_id' ) 499 ? wp_unique_id( 'forwp-faq-cats-list-' ) 500 : 'forwp-faq-cats-list'; 501 502 $html = '<nav ' . $wrapper; 503 if ( '' !== $nav_label ) { 504 $html .= ' aria-labelledby="' . esc_attr( $label_id ) . '"'; 505 } 506 $html .= '>'; 507 if ( '' !== $nav_label ) { 508 $html .= '<p class="forwp-faq-categories__label" id="' . esc_attr( $label_id ) . '">' . esc_html( $nav_label ) . '</p>'; 509 } 510 $html .= '<button type="button" class="forwp-faq-categories__menu"'; 511 $html .= ' data-wp-on--click="actions.toggleMenu"'; 512 $html .= ' data-wp-bind--aria-expanded="state.isMenuOpen"'; 513 $html .= ' aria-expanded="false" aria-controls="' . esc_attr( $list_id ) . '"'; 514 if ( '' === $nav_label ) { 515 $html .= ' aria-label="' . esc_attr__( 'Categories', '4wp-faq' ) . '"'; 516 } 517 $html .= '>'; 518 $html .= '<svg class="forwp-faq-categories__menu-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" focusable="false"><path d="M2 4h12M2 8h12M2 12h12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'; 519 if ( '' !== $nav_label ) { 520 $html .= '<span class="forwp-faq-categories__menu-text">' . esc_html( $nav_label ) . '</span>'; 521 } 522 $html .= '</button>'; 523 $html .= '<ul class="forwp-faq-categories__list" id="' . esc_attr( $list_id ) . '" role="list">'; 356 524 357 525 if ( $show_all ) { … … 382 550 unset( $attributes ); 383 551 552 return self::count_markup( true ); 553 } 554 555 /** 556 * Count span markup. 557 * 558 * @param bool $use_block_wrapper False for the shortcode: otherwise the enclosing block's classes (e.g. alignfull) leak in. 559 * @return string 560 */ 561 private static function count_markup( $use_block_wrapper ) { 384 562 self::ensure_runtime(); 385 563 386 564 $context = self::get_list_query_context(); 387 $count = Registry_Content::count_visible_posts( 388 $context['includeTermIds'], 389 $context['excludeTermIds'], 390 $context['activeSlug'], 391 $context['previewLimit'], 392 $context['layout'] 393 ); 394 395 $wrapper = get_block_wrapper_attributes( 396 [ 397 'class' => 'forwp-faq-count', 398 'data-wp-interactive' => self::STORE, 399 'data-wp-text' => 'state.visibleCount', 400 ] 401 ); 565 $totals = self::count_totals( $context ); 566 $count = (int) ( $totals[ $context['activeSlug'] ] ?? 0 ); 567 568 $attrs = [ 569 'class' => 'forwp-faq-count', 570 'data-wp-interactive' => self::STORE, 571 'data-wp-text' => 'state.visibleCount', 572 ]; 573 574 $wrapper = $use_block_wrapper ? get_block_wrapper_attributes( $attrs ) : self::plain_attributes( $attrs ); 402 575 403 576 return '<span ' . $wrapper . '>' . esc_html( (string) $count ) . '</span>'; 577 } 578 579 /** 580 * Question totals matching the category nav counts. 581 * 582 * Key '' = sum of top-level category counts; each slug = that category's nav count. 583 * 584 * @param array $context From get_list_query_context(). 585 * @return array<string, int> 586 */ 587 private static function count_totals( $context ) { 588 static $cache = null; 589 if ( null !== $cache ) { 590 return $cache; 591 } 592 593 $totals = [ '' => 0 ]; 594 $walk = static function ( $nodes, $top ) use ( &$walk, &$totals ) { 595 foreach ( (array) $nodes as $node ) { 596 $term = $node['term'] ?? null; 597 if ( ! $term instanceof \WP_Term ) { 598 continue; 599 } 600 $count = isset( $node['inclusive_count'] ) ? (int) $node['inclusive_count'] : (int) $term->count; 601 $totals[ $term->slug ] = $count; 602 if ( $top ) { 603 $totals[''] += $count; 604 } 605 if ( ! empty( $node['children'] ) ) { 606 $walk( $node['children'], false ); 607 } 608 } 609 }; 610 $walk( Registry_Content::get_nav_tree( $context['includeTermIds'], $context['excludeTermIds'] ), true ); 611 612 $cache = $totals; 613 614 return $totals; 404 615 } 405 616 … … 413 624 unset( $atts ); 414 625 415 return self:: render_count( []);626 return self::count_markup( false ); 416 627 } 417 628 … … 637 848 * @param array $attributes List attributes. 638 849 * @param \WP_Block|null $block List block instance. 639 * @return array{displayMode: string, showSources: bool, sourcesLabel: string, s howPostType: bool, questionStyle: array, answerStyle: array}850 * @return array{displayMode: string, showSources: bool, sourcesLabel: string, sourcesSeparator: string, showPostType: bool, questionStyle: array, answerStyle: array} 640 851 */ 641 852 private static function resolve_card_attributes( $attributes, $block ) { … … 667 878 } 668 879 880 if ( array_key_exists( 'sourcesSeparator', $inner ) ) { 881 $sources_separator = (string) $inner['sourcesSeparator']; 882 } elseif ( isset( $attributes['cardSourcesSeparator'] ) ) { 883 $sources_separator = (string) $attributes['cardSourcesSeparator']; 884 } else { 885 $sources_separator = ', '; 886 } 887 669 888 if ( array_key_exists( 'showPostType', $inner ) ) { 670 889 $show_post_type = ! empty( $inner['showPostType'] ); … … 688 907 689 908 return [ 690 'displayMode' => $display, 691 'showSources' => $show_sources, 692 'sourcesLabel' => $sources_label, 693 'showPostType' => $show_post_type, 694 'questionStyle' => self::sanitize_typography_style( $question_style ), 695 'answerStyle' => self::sanitize_typography_style( $answer_style ), 909 'displayMode' => $display, 910 'showSources' => $show_sources, 911 'sourcesLabel' => $sources_label, 912 'sourcesSeparator' => $sources_separator, 913 'showPostType' => $show_post_type, 914 'questionStyle' => self::sanitize_typography_style( $question_style ), 915 'answerStyle' => self::sanitize_typography_style( $answer_style ), 696 916 ]; 697 917 } … … 699 919 /** 700 920 * @param mixed $style Raw style object. 701 * @return array {fontSize?: string, fontFamily?: string, fontWeight?: string, color?: string}921 * @return array<string, string> Keys from typography_var_suffixes(). 702 922 */ 703 923 private static function sanitize_typography_style( $style ) { … … 736 956 } 737 957 958 $patterns = [ 959 'fontStyle' => '/^(normal|italic)$/', 960 'lineHeight' => '/^\d+(\.\d+)?(px|rem|em|%)?$/', 961 'letterSpacing' => '/^-?\d+(\.\d+)?(px|rem|em)$/', 962 'textDecoration' => '/^(none|underline|line-through)$/', 963 'textTransform' => '/^(none|uppercase|lowercase|capitalize)$/', 964 ]; 965 foreach ( $patterns as $key => $pattern ) { 966 if ( ! isset( $style[ $key ] ) || '' === $style[ $key ] ) { 967 continue; 968 } 969 $val = trim( sanitize_text_field( (string) $style[ $key ] ) ); 970 if ( preg_match( $pattern, $val ) ) { 971 $out[ $key ] = $val; 972 } 973 } 974 738 975 return $out; 976 } 977 978 /** 979 * Style keys → CSS custom property suffix (shared by q / a / g prefixes). 980 * 981 * @return array<string, string> 982 */ 983 private static function typography_var_suffixes() { 984 return [ 985 'fontSize' => 'size', 986 'fontFamily' => 'family', 987 'fontWeight' => 'weight', 988 'fontStyle' => 'style', 989 'lineHeight' => 'line', 990 'letterSpacing' => 'spacing', 991 'textDecoration' => 'decoration', 992 'textTransform' => 'transform', 993 'color' => 'color', 994 ]; 739 995 } 740 996 … … 841 1097 : []; 842 1098 843 $map = [ 844 '--forwp-faq-q-size' => $question['fontSize'] ?? '', 845 '--forwp-faq-q-family' => $question['fontFamily'] ?? '', 846 '--forwp-faq-q-weight' => $question['fontWeight'] ?? '', 847 '--forwp-faq-q-color' => $question['color'] ?? '', 848 '--forwp-faq-a-size' => $answer['fontSize'] ?? '', 849 '--forwp-faq-a-family' => $answer['fontFamily'] ?? '', 850 '--forwp-faq-a-weight' => $answer['fontWeight'] ?? '', 851 '--forwp-faq-a-color' => $answer['color'] ?? '', 852 ]; 1099 $map = []; 1100 foreach ( self::typography_var_suffixes() as $key => $suffix ) { 1101 $map[ '--forwp-faq-q-' . $suffix ] = $question[ $key ] ?? ''; 1102 $map[ '--forwp-faq-a-' . $suffix ] = $answer[ $key ] ?? ''; 1103 } 853 1104 854 1105 $parts = []; … … 862 1113 863 1114 return implode( ';', $parts ); 1115 } 1116 1117 /** 1118 * Category title typography: CSS variables plus one class per set property. 1119 * 1120 * Classes keep theme heading styles untouched for properties left empty. 1121 * 1122 * @param mixed $style Raw groupTitleStyle attribute. 1123 * @return array{class: string, style: string} 1124 */ 1125 private static function group_title_vars( $style ) { 1126 $clean = self::sanitize_typography_style( $style ); 1127 $vars = []; 1128 $classes = []; 1129 1130 foreach ( self::typography_var_suffixes() as $key => $suffix ) { 1131 if ( empty( $clean[ $key ] ) ) { 1132 continue; 1133 } 1134 $vars[] = '--forwp-faq-g-' . $suffix . ':' . $clean[ $key ]; 1135 $classes[] = 'has-g-' . $suffix; 1136 } 1137 1138 return [ 1139 'class' => implode( ' ', $classes ), 1140 'style' => implode( ';', $vars ), 1141 ]; 864 1142 } 865 1143 … … 901 1179 $html .= '<section class="' . esc_attr( $group_class ) . '"' . self::context_attr( 902 1180 [ 903 'slug' => $slug, 904 'ancestors' => implode( ' ', $ancestors ), 1181 'slug' => $slug, 1182 'ancestors' => implode( ' ', $ancestors ), 1183 'searchText' => self::group_search_text( $posts, $children ), 905 1184 ] 906 1185 ) . ' data-wp-bind--hidden="!state.isGroupVisible"' . ( $hidden ? ' hidden' : '' ) . '>'; … … 926 1205 927 1206 return $html; 1207 } 1208 1209 /** 1210 * Question and answer text for this group and its children, for search. 1211 * 1212 * @param \WP_Post[] $posts Posts rendered in the group. 1213 * @param array[] $children Nested groups. 1214 * @return string 1215 */ 1216 private static function group_search_text( $posts, $children ) { 1217 $parts = []; 1218 1219 foreach ( $posts as $post ) { 1220 if ( ! $post instanceof \WP_Post ) { 1221 continue; 1222 } 1223 $answer = Registry_Content::get_answer( (int) $post->ID ); 1224 $parts[] = strtolower( trim( get_the_title( $post ) . ' ' . ( $answer['text'] ?? '' ) ) ); 1225 } 1226 1227 foreach ( $children as $child ) { 1228 if ( ! is_array( $child ) ) { 1229 continue; 1230 } 1231 $child_posts = isset( $child['posts'] ) && is_array( $child['posts'] ) ? $child['posts'] : []; 1232 $child_nodes = isset( $child['children'] ) && is_array( $child['children'] ) ? $child['children'] : []; 1233 $parts[] = self::group_search_text( $child_posts, $child_nodes ); 1234 } 1235 1236 return trim( implode( ' ', array_filter( $parts ) ) ); 928 1237 } 929 1238 … … 982 1291 ? sanitize_text_field( (string) $attributes['sourcesLabel'] ) 983 1292 : __( 'Used in', '4wp-faq' ); 1293 $sources_separator = isset( $attributes['sourcesSeparator'] ) 1294 ? (string) $attributes['sourcesSeparator'] 1295 : ', '; 984 1296 if ( 'heading' !== $display ) { 985 1297 $display = 'accordion'; … … 1019 1331 1020 1332 $body = self::render_answer( $answer ); 1021 $body .= self::render_sources( $sources, $sources_label, $show_type );1333 $body .= self::render_sources( $sources, $sources_label, $show_type, $sources_separator ); 1022 1334 1023 1335 if ( 'heading' === $display ) { … … 1046 1358 1047 1359 /** 1360 * Drop color classes copied from dark page sections so the answer uses the card color. 1361 * 1362 * @param string $html Answer HTML. 1363 * @return string 1364 */ 1365 private static function strip_answer_color( $html ) { 1366 $html = preg_replace_callback( 1367 '/\sclass=("|\')([^"\']*)\1/', 1368 static function ( $matches ) { 1369 $classes = preg_split( '/\s+/', $matches[2], -1, PREG_SPLIT_NO_EMPTY ); 1370 $classes = array_values( 1371 array_filter( 1372 $classes, 1373 static function ( $class ) { 1374 if ( in_array( $class, [ 'has-text-color', 'has-background', 'has-link-color' ], true ) ) { 1375 return false; 1376 } 1377 1378 return ! preg_match( '/^has-.+-(color|background-color)$/', $class ); 1379 } 1380 ) 1381 ); 1382 1383 if ( ! $classes ) { 1384 return ''; 1385 } 1386 1387 return ' class=' . $matches[1] . implode( ' ', $classes ) . $matches[1]; 1388 }, 1389 $html 1390 ); 1391 1392 $html = preg_replace_callback( 1393 '/\sstyle=("|\')([^"\']*)\1/', 1394 static function ( $matches ) { 1395 $style = preg_replace( '/(?:^|;)\s*color\s*:[^;]*/i', '', $matches[2] ); 1396 $style = trim( (string) $style, " \t;" ); 1397 1398 if ( '' === $style ) { 1399 return ''; 1400 } 1401 1402 return ' style=' . $matches[1] . $style . $matches[1]; 1403 }, 1404 (string) $html 1405 ); 1406 1407 return (string) $html; 1408 } 1409 1410 /** 1048 1411 * @param array{text: string, html: string} $answer Answer payload. 1049 1412 * @return string … … 1054 1417 1055 1418 if ( '' !== $html ) { 1056 return '<div class="forwp-faq-card__answer">' . wp_kses_post( $html) . '</div>';1419 return '<div class="forwp-faq-card__answer">' . wp_kses_post( self::strip_answer_color( $html ) ) . '</div>'; 1057 1420 } 1058 1421 … … 1065 1428 1066 1429 /** 1067 * @param list<array{title: string, url: string, post_type_label: string}> $sources Sources. 1068 * @param string $sources_label Label placeholder. 1069 * @param bool $show_post_type Show CPT type. 1070 * @return string 1071 */ 1072 private static function render_sources( $sources, $sources_label = '', $show_post_type = false ) { 1430 * @param list<array{title: string, url: string, post_type_label: string, is_public?: bool}> $sources Sources. 1431 * @param string $sources_label Label placeholder. 1432 * @param bool $show_post_type Show CPT type. 1433 * @param string $separator Between items. 1434 * @return string 1435 */ 1436 private static function render_sources( $sources, $sources_label = '', $show_post_type = false, $separator = ', ' ) { 1073 1437 if ( empty( $sources ) ) { 1074 1438 return ''; … … 1079 1443 $html .= '<p class="forwp-faq-card__sources-label">' . esc_html( $sources_label ) . '</p>'; 1080 1444 } 1081 $html .= '<ul class="forwp-faq-card__sources-list">'; 1082 1445 $html .= '<p class="forwp-faq-card__sources-list">'; 1446 1447 $items = []; 1083 1448 foreach ( $sources as $source ) { 1084 $html .= '<li class="forwp-faq-card__sources-item">'; 1085 $html .= '<a href="' . esc_url( $source['url'] ) . '">' . esc_html( $source['title'] ) . '</a>'; 1449 $is_public = ! isset( $source['is_public'] ) || $source['is_public']; 1450 $item = $is_public 1451 ? '<a class="forwp-faq-card__sources-item" href="' . esc_url( $source['url'] ) . '">' . esc_html( $source['title'] ) . '</a>' 1452 : '<span class="forwp-faq-card__sources-item is-inactive" title="' . esc_attr__( 'Not public: visible to editors only', '4wp-faq' ) . '">' . esc_html( $source['title'] ) . '</span>'; 1086 1453 if ( $show_post_type && ! empty( $source['post_type_label'] ) ) { 1087 $html .= ' <span class="forwp-faq-card__sources-type">' . esc_html( $source['post_type_label'] ) . '</span>'; 1088 } 1089 $html .= '</li>'; 1090 } 1091 1092 $html .= '</ul></div>'; 1454 $item .= ' <span class="forwp-faq-card__sources-type">' . esc_html( $source['post_type_label'] ) . '</span>'; 1455 } 1456 $items[] = $item; 1457 } 1458 1459 $html .= implode( 1460 '<span class="forwp-faq-card__sources-separator">' . esc_html( $separator ) . '</span>', 1461 $items 1462 ); 1463 $html .= '</p></div>'; 1093 1464 1094 1465 return $html; … … 1209 1580 1210 1581 return '<p class="forwp-faq-list__more"><a class="forwp-faq-list__more-link" href="' . esc_url( $url ) . '">' . esc_html( $label ) . '</a></p>'; 1582 } 1583 1584 /** 1585 * CSS variables for the All link, category names, and the gap between them. 1586 * 1587 * @param array $attributes Block attributes. 1588 * @return string 1589 */ 1590 private static function categories_size_vars( $attributes ) { 1591 $map = [ 1592 'allItemFontSize' => '--forwp-faq-all-size', 1593 'itemFontSize' => '--forwp-faq-item-size', 1594 'itemGap' => '--forwp-faq-item-gap', 1595 ]; 1596 $parts = []; 1597 1598 foreach ( $map as $key => $var ) { 1599 $size = self::sanitize_css_size( $attributes[ $key ] ?? '' ); 1600 if ( '' !== $size ) { 1601 $parts[] = $var . ':' . $size; 1602 } 1603 } 1604 1605 return implode( ';', $parts ); 1211 1606 } 1212 1607 … … 1253 1648 1254 1649 $classes = 'forwp-faq-categories__item'; 1650 if ( '' === $slug ) { 1651 $classes .= ' is-all'; 1652 } 1255 1653 if ( $is_active ) { 1256 1654 $classes .= ' is-active'; … … 1323 1721 1324 1722 $context = self::get_list_query_context(); 1325 $count = Registry_Content::count_visible_posts( 1326 $context['includeTermIds'], 1327 $context['excludeTermIds'], 1328 $context['activeSlug'], 1329 $context['previewLimit'], 1330 $context['layout'] 1331 ); 1723 $totals = self::count_totals( $context ); 1332 1724 1333 1725 $done = true; … … 1337 1729 'category' => $context['activeSlug'], 1338 1730 'search' => '', 1339 'visibleCount' => $count, 1731 'visibleCount' => (int) ( $totals[ $context['activeSlug'] ] ?? 0 ), 1732 'totals' => (object) $totals, 1340 1733 'openBranches' => (object) [], 1341 1734 'isNavActive' => static function () { -
4wp-faq/trunk/includes/class-plugin.php
r3704354 r3748403 567 567 */ 568 568 public static function get_registry_stats() { 569 return Polylang::with_language( 570 Polylang::get_admin_language(), 571 [ __CLASS__, 'build_registry_stats' ] 572 ); 573 } 574 575 /** 576 * Registry stats for whatever language the current queries resolve to. 577 * 578 * @return array<string, int> 579 */ 580 public static function build_registry_stats() { 569 581 $stats = [ 570 582 'total_questions' => 0, … … 604 616 605 617 foreach ( $faq_ids as $faq_id ) { 606 $usage = (int) get_post_meta( $faq_id, 'count_usage', true ); 607 if ( $usage > 1 ) { 618 if ( Registry_Content::count_public_usage( $faq_id ) > 1 ) { 608 619 ++$reused; 609 620 } … … 633 644 */ 634 645 public static function get_dashboard_data() { 635 $stats = self::get_registry_stats(); 646 $lang = Polylang::get_admin_language(); 647 $data = Polylang::with_language( $lang, [ __CLASS__, 'build_dashboard_data' ] ); 648 649 $data['language'] = [ 650 'slug' => (string) $lang, 651 'name' => null === $lang ? '' : ( '' === $lang ? __( 'All languages', '4wp-faq' ) : Polylang::get_language_name( $lang ) ), 652 ]; 653 $data['by_language'] = []; 654 655 if ( '' === $lang ) { 656 foreach ( Polylang::get_language_slugs() as $slug ) { 657 $slice = Polylang::with_language( $slug, [ __CLASS__, 'build_dashboard_data' ] ); 658 $stats = isset( $slice['stats'] ) && is_array( $slice['stats'] ) ? $slice['stats'] : []; 659 660 $data['by_language'][] = [ 661 'slug' => $slug, 662 'name' => Polylang::get_language_name( $slug ), 663 'questions' => (int) ( $stats['total_questions'] ?? 0 ), 664 'categories' => (int) ( $stats['faq_categories'] ?? 0 ), 665 'uncategorized' => (int) ( $stats['uncategorized'] ?? 0 ), 666 'pages' => (int) ( $stats['pages_with_faq'] ?? 0 ), 667 ]; 668 } 669 } 670 671 return $data; 672 } 673 674 /** 675 * Dashboard data for whatever language the current queries resolve to. 676 * 677 * @return array<string, mixed> 678 */ 679 public static function build_dashboard_data() { 680 $stats = self::build_registry_stats(); 636 681 $last_scan = (int) get_option( 'forwp_faq_last_scan_at', 0 ); 637 682 $data = [ … … 687 732 foreach ( $faq_ids as $faq_id ) { 688 733 $faq_id = (int) $faq_id; 689 $usage = (int) get_post_meta( $faq_id, 'count_usage', true);734 $usage = Registry_Content::count_public_usage( $faq_id ); 690 735 if ( $usage < 1 ) { 691 736 ++$unused; -
4wp-faq/trunk/includes/class-registry-content.php
r3685374 r3748403 64 64 65 65 /** 66 * Published public pages/posts using this FAQ (internal post types excluded). 67 * 68 * @param int $post_id Registry post ID. 69 * @return int 70 */ 71 public static function count_public_usage( $post_id ) { 72 $used_in = get_post_meta( (int) $post_id, 'used_in_posts', true ); 73 if ( ! is_array( $used_in ) ) { 74 return 0; 75 } 76 77 $count = 0; 78 foreach ( array_unique( array_map( 'intval', $used_in ) ) as $source_id ) { 79 $source = $source_id > 0 ? get_post( $source_id ) : null; 80 if ( ! $source instanceof \WP_Post || 'publish' !== $source->post_status ) { 81 continue; 82 } 83 $type = get_post_type_object( $source->post_type ); 84 if ( $type && ! empty( $type->public ) ) { 85 ++$count; 86 } 87 } 88 89 return $count; 90 } 91 92 /** 93 * Block editor server-side preview (REST), not the front end. 94 * 95 * @return bool 96 */ 97 private static function is_editor_preview() { 98 return function_exists( 'wp_is_serving_rest_request' ) 99 ? wp_is_serving_rest_request() 100 : ( defined( 'REST_REQUEST' ) && REST_REQUEST ); 101 } 102 103 /** 66 104 * Public pages/posts where this FAQ registry entry appears. 67 105 * 68 106 * @param int $post_id Registry post ID. 69 * @return list<array{id: int, title: string, url: string, post_type: string, post_type_label: string }>107 * @return list<array{id: int, title: string, url: string, post_type: string, post_type_label: string, is_public: bool}> 70 108 */ 71 109 public static function get_sources( $post_id ) { … … 112 150 : $source_post->post_type; 113 151 152 // Internal (non-public) types have no working front URL: editor preview only, no link. 153 $is_public = $type_object && ! empty( $type_object->public ); 154 if ( ! $is_public && ! ( self::is_editor_preview() && current_user_can( 'edit_post', $source_id ) ) ) { 155 continue; 156 } 157 114 158 $sources[] = [ 115 159 'id' => $source_id, 116 160 'title' => $title, 117 'url' => $ url,161 'url' => $is_public ? $url : '', 118 162 'post_type' => $source_post->post_type, 119 163 'post_type_label' => $type_label, 164 'is_public' => $is_public, 120 165 ]; 121 166 $seen_url[ $url ] = true; … … 143 188 'post_type' => (string) ( $row['post_type'] ?? '' ), 144 189 'post_type_label' => (string) ( $row['post_type_label'] ?? '' ), 190 'is_public' => true, 145 191 ]; 146 192 } -
4wp-faq/trunk/includes/integrations/class-polylang.php
r3654057 r3748403 72 72 73 73 return $taxonomies; 74 } 75 76 /** 77 * Language picked in the admin bar filter: slug, '' for all languages, null without Polylang. 78 * 79 * Read from user meta so admin pages and REST (Settings app) agree. 80 */ 81 public static function get_admin_language(): ?string { 82 if ( ! self::is_active() || ! function_exists( 'pll_languages_list' ) ) { 83 return null; 84 } 85 86 $lang = (string) get_user_meta( get_current_user_id(), 'pll_filter_content', true ); 87 88 return in_array( $lang, self::get_language_slugs(), true ) ? $lang : ''; 89 } 90 91 /** 92 * @return string[] 93 */ 94 public static function get_language_slugs(): array { 95 if ( ! self::is_active() || ! function_exists( 'pll_languages_list' ) ) { 96 return []; 97 } 98 99 $slugs = pll_languages_list( [ 'fields' => 'slug' ] ); 100 101 return is_array( $slugs ) ? array_values( array_filter( array_map( 'strval', $slugs ) ) ) : []; 102 } 103 104 /** 105 * @param string $slug Language slug. 106 */ 107 public static function get_language_name( $slug ): string { 108 if ( ! self::is_active() || ! function_exists( 'pll_languages_list' ) ) { 109 return (string) $slug; 110 } 111 112 $slugs = pll_languages_list( [ 'fields' => 'slug' ] ); 113 $names = pll_languages_list( [ 'fields' => 'name' ] ); 114 $index = is_array( $slugs ) ? array_search( $slug, $slugs, true ) : false; 115 116 return false !== $index && isset( $names[ $index ] ) ? (string) $names[ $index ] : (string) $slug; 117 } 118 119 /** 120 * Run a callback with every post/term query forced to one language ('' = all languages). 121 * 122 * @param string|null $lang Language slug, '' for all, null = leave queries untouched. 123 * @param callable $fn Callback. 124 * @return mixed 125 */ 126 public static function with_language( $lang, callable $fn ) { 127 if ( null === $lang || ! self::is_active() ) { 128 return $fn(); 129 } 130 131 $hooks = self::force_language( $lang ); 132 133 try { 134 return $fn(); 135 } finally { 136 remove_action( 'parse_query', $hooks[0], 0 ); 137 remove_filter( 'get_terms_args', $hooks[1], 0 ); 138 } 139 } 140 141 /** 142 * Force every following post/term query to one language ('' = all languages). 143 * 144 * @param string $lang Language slug. 145 * @return callable[] The two hooked callbacks (parse_query, get_terms_args). 146 */ 147 public static function force_language( $lang ): array { 148 $posts = static function ( $query ) use ( $lang ) { 149 $query->query_vars['lang'] = $lang; 150 }; 151 $terms = static function ( $args ) use ( $lang ) { 152 $args['lang'] = $lang; 153 return $args; 154 }; 155 156 // Before Polylang's own parse_query / get_terms_args handlers read `lang`. 157 add_action( 'parse_query', $posts, 0 ); 158 add_filter( 'get_terms_args', $terms, 0 ); 159 160 return [ $posts, $terms ]; 74 161 } 75 162 -
4wp-faq/trunk/readme.txt
r3704354 r3748403 1 1 === 4WP FAQ === 2 2 Contributors: 4wpdev, anatolikkk 3 Tags: faq, accordion, json-ld, gutenberg, seo3 Tags: faq, faq schema, accordion, json-ld, structured data 4 4 Requires at least: 6.6 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 2.6. 17 Stable tag: 2.6.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 FAQ Page schema for core Accordion, optional registry you can edit or add from, hub pages, and AI via Connectors.11 FAQ schema for the core Accordion. Scan every question on your site into one registry, edit once, and build a searchable FAQ hub. 12 12 13 13 == Description == 14 14 15 4WP FAQ wraps WordPress core **Accordion** blocks so you can keep your design and still get: 16 17 * **FAQPage JSON-LD** for Google rich results (off by default; turn on when you are ready) 18 * An optional **FAQ registry** (scan of unique questions). Edit one record to push Q/A onto every **Used In** page. **Add FAQ** places a new item on category pages or one page. Site content stays the source of truth. 19 * **Hub pages** with List + Categories blocks, pretty category URLs, category SEO titles, collapsible subcategory nav, and drag-and-drop category order (admin + front end) 20 * **Drag-and-drop FAQ category order** on **FAQ → Categories** — same order in admin lists and on the front end (List / Categories hub) 21 * Optional **AI category copy** through the standard **WordPress AI Client** (Settings → Connectors) — description, display title, SEO title, and SEO description. No custom vendor SDK. 15 **Not another FAQ block.** 4WP FAQ wraps the core **Accordion** you already use, adds **FAQPage JSON-LD**, and turns every question on your site into one registry you can reuse, update everywhere, and show as a searchable hub. Your design stays the same. 16 17 https://www.youtube.com/watch?v=SI3slJFYVbg 18 19 👉 **Live demo, docs and comparison:** [4wp.dev/plugin/4wp-faq](https://4wp.dev/plugin/4wp-faq/) 20 💬 **Real hub with 296 questions in 9 categories:** [4wp.dev/faqs](https://4wp.dev/faqs/) 21 22 = Why 4WP FAQ = 23 24 * **Built on core.** A thin wrapper over the core Accordion. No new design, no lock-in: unwrap any time and the Accordion stays. 25 * **The only FAQ plugin that scans.** Questions live on your pages. A scan collects them into one registry. You never type a question twice. 26 * **Edit once, update everywhere.** Change a question in the registry and 4WP FAQ writes it onto every page listed in **Used in**. 27 * **SEO hub for free.** List, Categories, Search and Count blocks, pretty category URLs, category SEO titles, canonical and Open Graph. No Pro tier. 28 * **AI without a vendor.** Category copy through the standard **WordPress AI Client** (Connectors). No custom SDK, no API keys in the plugin. 29 30 = What you get = 31 32 * **FAQPage JSON-LD** — structured data for search engines and AI answers. Opt-in, site-wide or per block. Skips its own output when Yoast already prints FAQ schema. 33 * **Convert to FAQ** — one click on an Accordion, or **Transform to → 4WP FAQ** from Details, heading + paragraph pairs or a List. 34 * **FAQ registry** — every unique question with **Used in** sources, categories and a Dashboard. **Add FAQ** places a new question on every page of a category, or on one page. 35 * **FSE hub** — **4WP FAQ List**, **Categories**, **Count** and core **Search** with in-place filtering (Interactivity API). Nested categories, drag-and-drop order. 36 * **Polylang** — categories follow the page language; the Dashboard shows figures per language. 37 * **4WP Drive** — an H2 FAQ section with H3 questions in a Google Doc becomes a 4WP FAQ block on import. 22 38 23 39 A plugin by [4wp.dev](https://4wp.dev/). **4WP** is our project brand; this plugin is not affiliated with, endorsed, or sponsored by WordPress. 24 40 25 Source: [github.com/4wpdev/4wp-faq](https://github.com/4wpdev/4wp-faq) 41 Source: [github.com/4wpdev/4wp-faq](https://github.com/4wpdev/4wp-faq) · More plugins: [4wp.dev/plugins](https://4wp.dev/plugins/) 26 42 27 43 = How to work with it (short path) = … … 210 226 == Screenshots == 211 227 212 1. 4WP FAQ block wrapping core Accordion in the editor 213 2. Settings — rescan, JSON-LD, preview count, pretty category URLs, and how category titles are built 214 3. FAQ hub — List + Categories (and Count) in the Site Editor 228 1. A live FAQ hub on 4wp.dev: 296 questions, category navigation, search and count — built from the 4WP FAQ registry. 229 2. Convert to FAQ: one click wraps a core Accordion. Your design stays the same. 230 3. One Accordion Item = one question (heading) and one answer (panel). 231 4. FAQ → Settings: turn on FAQPage JSON-LD site-wide or per block. 232 5. FAQ Dashboard: registry status, Rescan, questions by category, reused and uncategorized. 233 6. Build the hub in the Site Editor: Categories, List, Search and Count blocks. 234 7. Add FAQ: place a new question on every page of a category, or on one page. 235 8. Edit once in the registry — the update is written to every page in Used in. 236 9. Generate category description and SEO titles with the WordPress AI Client. 215 237 216 238 == External services == … … 223 245 224 246 == Changelog == 247 248 = 2.6.5 = 249 * **Directory assets:** animated banner and icon GIFs for WordPress.org; nine screenshots aligned with the current hub and editor UI. 250 * **Docs:** README and readme.txt refreshed for the directory listing (demo, comparison, video). 251 252 = 2.6.4 = 253 * **Hub filter:** the host page slug (e.g. `/4wp-faq/`) no longer activates a FAQ category with the same slug. Pretty category URLs still match the full nav path (`/4wp-faq/hooks/`). Accordion FAQ on the page is unchanged; List / Categories keep their own settings. 254 * **Editor:** Include/Exclude category tokens no longer freeze the editor (Maximum update depth) when List and Categories sync filters. 255 * **Convert to FAQ:** wrapping an Accordion no longer drops its items (toolbar used empty innerBlocks). **Unwrap 4WP FAQ** restores the Accordion / Details. 256 257 = 2.6.3 = 258 * **Typography:** List, Card, and Categories panels match core (size, appearance, line height, letter spacing, decoration, letter case). 259 * **Used in:** sources stay on one line with a separator. Non-public sources are hidden on the front; the editor preview shows them greyed. 260 * **Count:** the badge is the sum of the categories on All, or that category’s count on a category page. The number and the label stay on one line. 261 * **No results:** an empty search shows a message you can edit, the same way as Query Loop no-results. 262 * **Dashboard:** figures follow the Polylang admin language and name it. All languages adds a per-language breakdown. Reused counts public pages only. 263 * **Editor preview:** List and Categories follow the page language, and Exclude hides that category. 264 265 = 2.6.2 = 266 * **Editor:** List, Categories, and Count previews load with POST, so the editor no longer shows “Error loading block: [object Object]”. 267 * **Answers:** color classes copied from dark sections (such as `has-white-50-color`) are stripped on output, so answer text uses the card color. 268 * **Settings:** Overview is four blocks — Registry, SEO, AI, Category titles. A click opens that section. Card headers are shorter, and the Connectors notice sits apart from the toggle. 269 * **Dashboard:** FAQ Status uses large figures. In two columns the third column stacks on the right instead of covering the first. The main WordPress Dashboard has a short FAQ widget with a link to this dashboard. 225 270 226 271 = 2.6.1 = … … 291 336 == Upgrade Notice == 292 337 338 = 2.6.5 = 339 WordPress.org banner/icon GIFs and screenshots; directory docs refresh. No functional change from 2.6.4. 340 341 = 2.6.4 = 342 Hub List no longer disappears when the page slug matches a FAQ category. Convert to FAQ keeps Accordion items; Unwrap restores them. Include/Exclude no longer freezes the editor. 343 344 = 2.6.3 = 345 Typography matches core, Used in stays on one line, the count matches the categories on the page, empty search has an editable message, and the dashboard follows the admin language. 346 347 = 2.6.2 = 348 Editor previews load again, FAQ answers no longer keep a forced light color, Settings opens from Overview blocks, and the FAQ Dashboard shows large figures plus a widget on the main WordPress Dashboard. 349 293 350 = 2.6.1 = 294 351 Registers the FAQ block with 4WP Drive so imported documents can map an FAQ heading to forwp/faq. https://wordpress.org/plugins/4wp-drive/
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)