Changeset 3451904
- Timestamp:
- 02/02/2026 09:40:44 AM (8 weeks ago)
- Location:
- zenpress
- Files:
-
- 10 added
- 36 edited
- 1 copied
-
tags/2.2.2 (copied) (copied from zenpress/trunk)
-
tags/2.2.2/assets/build/index-rtl.css (modified) (1 diff)
-
tags/2.2.2/assets/build/index.asset.php (modified) (1 diff)
-
tags/2.2.2/assets/build/index.css (modified) (1 diff)
-
tags/2.2.2/assets/build/index.js (modified) (1 diff)
-
tags/2.2.2/assets/src/js/hooks/useSettings.js (modified) (4 diffs)
-
tags/2.2.2/assets/src/js/pages/SettingsPage.js (modified) (4 diffs)
-
tags/2.2.2/assets/src/scss/pages/_settings.scss (modified) (1 diff)
-
tags/2.2.2/inc/admin/enqueue.php (modified) (3 diffs)
-
tags/2.2.2/inc/admin/links.php (modified) (2 diffs)
-
tags/2.2.2/inc/admin/menu.php (modified) (2 diffs)
-
tags/2.2.2/inc/classes (added)
-
tags/2.2.2/inc/classes/autoptimize.php (added)
-
tags/2.2.2/inc/classes/cache-enabler.php (added)
-
tags/2.2.2/inc/classes/integrations.php (added)
-
tags/2.2.2/inc/classes/sqlite-object-cache.php (added)
-
tags/2.2.2/inc/core/constants.php (modified) (1 diff)
-
tags/2.2.2/inc/core/metadata.php (modified) (2 diffs)
-
tags/2.2.2/inc/core/sanitize.php (modified) (1 diff)
-
tags/2.2.2/inc/settings/loader.php (modified) (2 diffs)
-
tags/2.2.2/inc/settings/options.php (modified) (2 diffs)
-
tags/2.2.2/inc/snippets/functions/protect-wp-login.php (modified) (1 diff)
-
tags/2.2.2/readme.txt (modified) (10 diffs)
-
tags/2.2.2/zenpress.php (modified) (3 diffs)
-
trunk/assets/build/index-rtl.css (modified) (1 diff)
-
trunk/assets/build/index.asset.php (modified) (1 diff)
-
trunk/assets/build/index.css (modified) (1 diff)
-
trunk/assets/build/index.js (modified) (1 diff)
-
trunk/assets/src/js/hooks/useSettings.js (modified) (4 diffs)
-
trunk/assets/src/js/pages/SettingsPage.js (modified) (4 diffs)
-
trunk/assets/src/scss/pages/_settings.scss (modified) (1 diff)
-
trunk/inc/admin/enqueue.php (modified) (3 diffs)
-
trunk/inc/admin/links.php (modified) (2 diffs)
-
trunk/inc/admin/menu.php (modified) (2 diffs)
-
trunk/inc/classes (added)
-
trunk/inc/classes/autoptimize.php (added)
-
trunk/inc/classes/cache-enabler.php (added)
-
trunk/inc/classes/integrations.php (added)
-
trunk/inc/classes/sqlite-object-cache.php (added)
-
trunk/inc/core/constants.php (modified) (1 diff)
-
trunk/inc/core/metadata.php (modified) (2 diffs)
-
trunk/inc/core/sanitize.php (modified) (1 diff)
-
trunk/inc/settings/loader.php (modified) (2 diffs)
-
trunk/inc/settings/options.php (modified) (2 diffs)
-
trunk/inc/snippets/functions/protect-wp-login.php (modified) (1 diff)
-
trunk/readme.txt (modified) (10 diffs)
-
trunk/zenpress.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
zenpress/tags/2.2.2/assets/build/index-rtl.css
r3412245 r3451904 1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-left:1px solid #d6e2ed;flex-direction:column;padding-left:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:right;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;left:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-right:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;right:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress- tabs__panel h2{font-size:1.5em;padding-right:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;right:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""}1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-left:1px solid #d6e2ed;flex-direction:column;padding-left:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:right;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;left:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-right:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;right:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress-subcategory-integrations h3:before{content:"🔌"}.zenpress-autoconfig-actions{margin-top:1em}.zenpress-autoconfig-help{font-size:.9em;margin-bottom:0;margin-top:.5em;opacity:.9}.zenpress-tabs__panel h2{font-size:1.5em;padding-right:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;right:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""} -
zenpress/tags/2.2.2/assets/build/index.asset.php
r3448585 r3451904 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => ' 253355e0f124eff32114');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => '71f7100577c2edd9e445'); -
zenpress/tags/2.2.2/assets/build/index.css
r3412245 r3451904 1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-right:1px solid #d6e2ed;flex-direction:column;padding-right:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:left;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;right:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-left:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;left:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress- tabs__panel h2{font-size:1.5em;padding-left:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;left:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""}1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-right:1px solid #d6e2ed;flex-direction:column;padding-right:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:left;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;right:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-left:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;left:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress-subcategory-integrations h3:before{content:"🔌"}.zenpress-autoconfig-actions{margin-top:1em}.zenpress-autoconfig-help{font-size:.9em;margin-bottom:0;margin-top:.5em;opacity:.9}.zenpress-tabs__panel h2{font-size:1.5em;padding-left:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;left:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""} -
zenpress/tags/2.2.2/assets/build/index.js
r3448585 r3451904 1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element, r=window.wp.i18n,a=window.wp.components,i=window.wp.apiFetch;var o=e.n(i);const c=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:r})=>{const i=(0,n.useRef)(null);return(0,n.useEffect)(()=>((e,s)=>{if(!e)return;const t=t=>{if("Enter"===t.key){const n=e.querySelector('input[type="checkbox"]'),r=e.ownerDocument||document;n&&(r.activeElement===n||e.contains(r.activeElement))&&(t.preventDefault(),t.stopPropagation(),s())}};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}})(i.current,t),[t]),(0,p.jsx)("div",{ref:i,children:(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:r,__nextHasNoMarginBottom:!0})})},u=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,r.__)("Save settings","zenpress")}),b=()=>{const{removeNotice:e}=(0,c.useDispatch)(l.store),s=(0,c.useSelect)(e=>e(l.store).getNotices(),[]);return s&&0!==s.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},h=(0,n.createContext)(),f=({selectedTabId:e,onSelect:s,orientation:t="horizontal",children:r})=>{const[a,i]=(0,n.useState)(),o=(0,n.useRef)(null),c=void 0!==e?e:a;return(0,p.jsx)(h.Provider,{value:{selectedTabId:c,onSelect:t=>{void 0===e&&i(t),s?.(t)},orientation:t,getOrderedTabIds:()=>o.current?Array.from(o.current.querySelectorAll('[role="tab"]')).map(e=>{const s=e.getAttribute("id");return s?s.replace("zenpress-tab-",""):null}).filter(Boolean):[],tabListRef:o},children:(0,p.jsx)("div",{className:`zenpress-tabs zenpress-tabs--${t}`,children:r})})};f.TabList=({children:e})=>{const{orientation:s,tabListRef:t}=(0,n.useContext)(h);return(0,p.jsx)("div",{ref:t,className:`zenpress-tabs__list zenpress-tabs__list--${s}`,role:"tablist","aria-orientation":s,children:e})},f.Tab=({tabId:e,title:s,className:t="",children:r})=>{const{selectedTabId:a,onSelect:i,orientation:o,getOrderedTabIds:c}=(0,n.useContext)(h),l=a===e,d=(0,n.useRef)(null);return(0,p.jsx)("button",{ref:d,className:`zenpress-tabs__tab ${l?"zenpress-tabs__tab--is-active":""} ${t}`.trim(),role:"tab","aria-selected":l,"aria-controls":`zenpress-tab-panel-${e}`,id:`zenpress-tab-${e}`,tabIndex:l?0:-1,onClick:()=>i(e),onKeyDown:s=>{const t=c();if(!t||0===t.length)return;const n=t.indexOf(e);if(-1===n)return;let r=n;if("vertical"===o?"ArrowDown"===s.key?(s.preventDefault(),r=n<t.length-1?n+1:0):"ArrowUp"===s.key&&(s.preventDefault(),r=n>0?n-1:t.length-1):"ArrowRight"===s.key?(s.preventDefault(),r=n<t.length-1?n+1:0):"ArrowLeft"===s.key&&(s.preventDefault(),r=n>0?n-1:t.length-1),"Home"===s.key?(s.preventDefault(),r=0):"End"===s.key&&(s.preventDefault(),r=t.length-1)," "===s.key||"Enter"===s.key)return s.preventDefault(),void i(e);if(r!==n&&r>=0&&r<t.length){const e=t[r],s=document.getElementById(`zenpress-tab-${e}`);s&&(s.focus(),i(e))}},onFocus:()=>{l||i(e)},children:s||r})},f.TabPanel=({tabId:e,children:s})=>{const{selectedTabId:t}=(0,n.useContext)(h),r=(0,n.useRef)(null),a=t===e;return(0,n.useEffect)(()=>{a&&r.current&&(0===r.current.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])').length?r.current.setAttribute("tabindex","0"):r.current.removeAttribute("tabindex"))},[a]),a?(0,p.jsx)("div",{ref:r,className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,children:s}):(0,p.jsx)("div",{className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,hidden:!0,children:s})};const x=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:i}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:i,createErrorNotice:p}=(0,c.useDispatch)(l.store);return(0,n.useEffect)(()=>{o()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n=window?.zenpressSnippetsMeta||{},r={};Object.keys(n).forEach(e=>{r[e]={...n[e],"enable-snippet":t.includes(e)}}),s(r)}).catch(()=>{p((0,r.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:async()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]);try{await o()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}),i((0,r.__)("Settings saved.","zenpress"))}catch{p((0,r.__)("Failed to save settings.","zenpress"))}finally{a(!1)}},isSaving:t}})(),[h,x]=(0,n.useState)(),_=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const r=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":r}}),t})},m=e=>e?e.charAt(0).toUpperCase()+e.slice(1).toLowerCase():e,v=["core","gutenberg","woocommerce","ads-blocker","tools"],y={};Object.keys(e).forEach(s=>{const t=e[s],n=(t?.category||(0,r.__)("Uncategorized","zenpress")).toLowerCase(),a=(t?.subcategory||(0,r.__)("uncategorized","zenpress")).toLowerCase();y[n]||(y[n]={}),y[n][a]||(y[n][a]=[]),y[n][a].push({name:s,data:t})});const z=Object.keys(y).sort((e,s)=>{const t=v.indexOf(e.toLowerCase()),n=v.indexOf(s.toLowerCase());return-1!==t&&-1!==n?t-n:-1!==t?-1:-1!==n?1:e.localeCompare(s,void 0,{sensitivity:"base"})});return(0,n.useEffect)(()=>{!h&&z.length>0&&x(z[0])},[h,z]),(0,n.useEffect)(()=>{const e=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),i||t())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[t,i]),(0,p.jsxs)("article",{className:"zenpress-row",children:[(0,p.jsxs)("section",{className:"zenpress-main",children:[(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(b,{})}),(0,p.jsxs)("div",{className:"zenpress-panel",children:[(0,p.jsxs)(f,{orientation:"vertical",selectedTabId:h,onSelect:e=>{x(e),x(e)},children:[(0,p.jsx)(f.TabList,{children:z.map(e=>{const s=`zenpress-tabs__tab--category-${e.toLowerCase().replace(/\s+/g,"-")}`;return(0,p.jsx)(f.Tab,{tabId:e,title:m(e),className:s,children:m(e)},e)})}),z.map(e=>{const t=Object.keys(y[e]).sort();return(0,p.jsxs)(f.TabPanel,{tabId:e,children:[(0,p.jsx)("h2",{children:m(e)}),t.map(t=>(0,p.jsxs)("div",{className:`zenpress-subcategory zenpress-subcategory-${t.toLowerCase().replace(/\s+/g,"-")}`,children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:m(t)}),y[e][t].map(({name:e,data:t})=>(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""},e))]},t))]},e)})]}),(0,p.jsxs)("div",{className:"zenpress-actions",children:[(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"tertiary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s})},__next40pxDefaultSize:!0,children:(0,r.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:!0,onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,r.__)("Disable all actions","zenpress")})]}),(0,p.jsx)(u,{onClick:t,isBusy:i})]})]})]}),(0,p.jsx)("aside",{className:"zenpress-sidebar",children:(0,p.jsx)("div",{className:"zenpress-presets",children:(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("h2",{children:(0,r.__)("Pick configuration preset","zenpress")}),(0,p.jsx)("p",{children:(0,r.__)("Don't know which features to enable? Quickly configure ZenPress by selecting a preset that matches your site type. Each preset enables optimized features for your specific use case.","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🖼️ ",(0,r.__)("Corporate website","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Optimized for business sites and portfolios. Focuses on security, performance, and removing unnecessary features like RSS feeds and author archives.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("corporate-website"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:[" 📰 ",(0,r.__)("Blog","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Tailored for content-focused blogs. Includes performance and security optimizations while preserving essential blog features like RSS feeds.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("blog"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🛒 ",(0,r.__)("E-commerce","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Designed for WooCommerce stores. Includes all performance and security features plus WooCommerce-specific optimizations for faster checkout.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("ecommerce"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")})]})})})]})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(x,{}))})})();1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,a=window.wp.i18n,r=window.wp.components,i=window.wp.data,c=window.wp.notices,o=window.wp.apiFetch;var l=e.n(o);const p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:a})=>{const i=(0,n.useRef)(null);return(0,n.useEffect)(()=>((e,s)=>{if(!e)return;const t=t=>{if("Enter"===t.key){const n=e.querySelector('input[type="checkbox"]'),a=e.ownerDocument||document;n&&(a.activeElement===n||e.contains(a.activeElement))&&(t.preventDefault(),t.stopPropagation(),s())}};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}})(i.current,t),[t]),(0,p.jsx)("div",{ref:i,children:(0,p.jsx)(r.ToggleControl,{label:e,checked:s,onChange:t,help:a,__nextHasNoMarginBottom:!0})})},u=({onClick:e,isBusy:s})=>(0,p.jsx)(r.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,a.__)("Save settings","zenpress")}),b=()=>{const{removeNotice:e}=(0,i.useDispatch)(c.store),s=(0,i.useSelect)(e=>e(c.store).getNotices(),[]);return s&&0!==s.length?(0,p.jsx)(r.NoticeList,{notices:s,onRemove:e}):null},h=(0,n.createContext)(),_=({selectedTabId:e,onSelect:s,orientation:t="horizontal",children:a})=>{const[r,i]=(0,n.useState)(),c=(0,n.useRef)(null),o=void 0!==e?e:r;return(0,p.jsx)(h.Provider,{value:{selectedTabId:o,onSelect:t=>{void 0===e&&i(t),s?.(t)},orientation:t,getOrderedTabIds:()=>c.current?Array.from(c.current.querySelectorAll('[role="tab"]')).map(e=>{const s=e.getAttribute("id");return s?s.replace("zenpress-tab-",""):null}).filter(Boolean):[],tabListRef:c},children:(0,p.jsx)("div",{className:`zenpress-tabs zenpress-tabs--${t}`,children:a})})};_.TabList=({children:e})=>{const{orientation:s,tabListRef:t}=(0,n.useContext)(h);return(0,p.jsx)("div",{ref:t,className:`zenpress-tabs__list zenpress-tabs__list--${s}`,role:"tablist","aria-orientation":s,children:e})},_.Tab=({tabId:e,title:s,className:t="",children:a})=>{const{selectedTabId:r,onSelect:i,orientation:c,getOrderedTabIds:o}=(0,n.useContext)(h),l=r===e,d=(0,n.useRef)(null);return(0,p.jsx)("button",{ref:d,className:`zenpress-tabs__tab ${l?"zenpress-tabs__tab--is-active":""} ${t}`.trim(),role:"tab","aria-selected":l,"aria-controls":`zenpress-tab-panel-${e}`,id:`zenpress-tab-${e}`,tabIndex:l?0:-1,onClick:()=>i(e),onKeyDown:s=>{const t=o();if(!t||0===t.length)return;const n=t.indexOf(e);if(-1===n)return;let a=n;if("vertical"===c?"ArrowDown"===s.key?(s.preventDefault(),a=n<t.length-1?n+1:0):"ArrowUp"===s.key&&(s.preventDefault(),a=n>0?n-1:t.length-1):"ArrowRight"===s.key?(s.preventDefault(),a=n<t.length-1?n+1:0):"ArrowLeft"===s.key&&(s.preventDefault(),a=n>0?n-1:t.length-1),"Home"===s.key?(s.preventDefault(),a=0):"End"===s.key&&(s.preventDefault(),a=t.length-1)," "===s.key||"Enter"===s.key)return s.preventDefault(),void i(e);if(a!==n&&a>=0&&a<t.length){const e=t[a],s=document.getElementById(`zenpress-tab-${e}`);s&&(s.focus(),i(e))}},onFocus:()=>{l||i(e)},children:s||a})},_.TabPanel=({tabId:e,children:s})=>{const{selectedTabId:t}=(0,n.useContext)(h),a=(0,n.useRef)(null),r=t===e;return(0,n.useEffect)(()=>{r&&a.current&&(0===a.current.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])').length?a.current.setAttribute("tabindex","0"):a.current.removeAttribute("tabindex"))},[r]),r?(0,p.jsx)("div",{ref:a,className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,children:s}):(0,p.jsx)("div",{className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,hidden:!0,children:s})};const z=()=>{const{snippets:e,setSnippets:s,adminBarEnabled:t,setAdminBarEnabled:o,saveSettings:h,isSaving:z}=(()=>{const[e,s]=(0,n.useState)({}),[t,r]=(0,n.useState)(!0),[o,p]=(0,n.useState)(!1),{createSuccessNotice:d,createErrorNotice:u}=(0,i.useDispatch)(c.store);return(0,n.useEffect)(()=>{l()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n=window?.zenpressSnippetsMeta||{},a={};Object.keys(n).forEach(e=>{a[e]={...n[e],"enable-snippet":t.includes(e)}}),s(a),r(!1!==e?.zenpress_admin_bar_enabled)}).catch(()=>{u((0,a.__)("Failed to load settings.","zenpress"))})},[u]),{snippets:e,setSnippets:s,adminBarEnabled:t,setAdminBarEnabled:r,saveSettings:async()=>{p(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]);try{await l()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s,zenpress_admin_bar_enabled:t}}),d((0,a.__)("Settings saved.","zenpress"))}catch{u((0,a.__)("Failed to save settings.","zenpress"))}finally{p(!1)}},isSaving:o}})(),[f,m]=(0,n.useState)(),[g,v]=(0,n.useState)(null),{createSuccessNotice:x,createErrorNotice:y}=(0,i.useDispatch)(c.store),j=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const a=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":a}}),t})},w=e=>e?e.charAt(0).toUpperCase()+e.slice(1).toLowerCase():e,S=["core","gutenberg","woocommerce","ads-blocker","tools"],k={};Object.keys(e).forEach(s=>{const t=e[s],n=(t?.category||(0,a.__)("Uncategorized","zenpress")).toLowerCase(),r=(t?.subcategory||(0,a.__)("uncategorized","zenpress")).toLowerCase();k[n]||(k[n]={}),k[n][r]||(k[n][r]=[]),k[n][r].push({name:s,data:t})});const C=Object.keys(k).sort((e,s)=>{const t=S.indexOf(e.toLowerCase()),n=S.indexOf(s.toLowerCase());return-1!==t&&-1!==n?t-n:-1!==t?-1:-1!==n?1:e.localeCompare(s,void 0,{sensitivity:"base"})});(0,n.useEffect)(()=>{!f&&C.length>0&&m(C[0])},[f,C]);const E=async(e,s,t,n)=>{v(e);try{const e=await l()({path:s,method:"POST"});x(e?.message||t)}catch{y(n)}finally{v(null)}},A=()=>E("autoptimize","/zenpress/v1/autoconfig/autoptimize",(0,a.__)("Autoptimize has been configured.","zenpress"),(0,a.__)("Autoptimize autoconfig failed. Is Autoptimize installed and active?","zenpress")),N=()=>E("cache_enabler","/zenpress/v1/autoconfig/cache-enabler",(0,a.__)("Cache Enabler has been configured.","zenpress"),(0,a.__)("Cache Enabler autoconfig failed. Is Cache Enabler installed and active?","zenpress")),O=()=>E("sqlite_object_cache","/zenpress/v1/autoconfig/sqlite-object-cache",(0,a.__)("SQLite Object Cache has been configured.","zenpress"),(0,a.__)("SQLite Object Cache autoconfig failed. Is SQLite Object Cache installed and active?","zenpress"));return(0,n.useEffect)(()=>{const e=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),z||h())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[h,z]),(0,p.jsxs)("article",{className:"zenpress-row",children:[(0,p.jsxs)("section",{className:"zenpress-main",children:[(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(b,{})}),(0,p.jsxs)("div",{className:"zenpress-panel",children:[(0,p.jsxs)(_,{orientation:"vertical",selectedTabId:f,onSelect:e=>{m(e),m(e)},children:[(0,p.jsx)(_.TabList,{children:C.map(e=>{const s=`zenpress-tabs__tab--category-${e.toLowerCase().replace(/\s+/g,"-")}`;return(0,p.jsx)(_.Tab,{tabId:e,title:w(e),className:s,children:w(e)},e)})}),C.map(e=>{const n=Object.keys(k[e]).sort();return(0,p.jsxs)(_.TabPanel,{tabId:e,children:[(0,p.jsx)("h2",{children:w(e)}),n.map(t=>(0,p.jsxs)("div",{className:`zenpress-subcategory zenpress-subcategory-${t.toLowerCase().replace(/\s+/g,"-")}`,children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:w(t)}),k[e][t].map(({name:e,data:t})=>(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""},e))]},t)),"tools"===e&&Object.values(window?.zenpressIntegrationsActive||{}).some(Boolean)&&(0,p.jsxs)("div",{className:"zenpress-subcategory zenpress-subcategory-integrations",children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:(0,a.__)("Integrations","zenpress")}),(0,p.jsx)(d,{label:(0,a.__)("Show ZenPress admin bar button","zenpress"),value:t,onChange:()=>o(!t),help:(0,a.__)('Show a "ZenPress" item in the admin bar with "Clear caches". When enabled, integration buttons (e.g. Autoptimize) are hidden.',"zenpress")}),window?.zenpressIntegrationsActive?.autoptimize&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:A,disabled:null!==g,__next40pxDefaultSize:!0,children:"autoptimize"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig Autoptimize","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended Autoptimize settings (optimize JS/CSS, aggregate CSS, static files, 404 fallbacks; disable defer, HTML optimize, optimize for logged-in, per post/page). Only works if Autoptimize is active.","zenpress")})]}),window?.zenpressIntegrationsActive?.cache_enabler&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:N,disabled:null!==g,__next40pxDefaultSize:!0,children:"cache_enabler"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig Cache Enabler","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended Cache Enabler settings. Only works if Cache Enabler is active.","zenpress")})]}),window?.zenpressIntegrationsActive?.sqlite_object_cache&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:O,disabled:null!==g,__next40pxDefaultSize:!0,children:"sqlite_object_cache"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig SQLite Object Cache","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended SQLite Object Cache settings. Only works if SQLite Object Cache is active.","zenpress")})]})]})]},e)})]}),(0,p.jsxs)("div",{className:"zenpress-actions",children:[(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(r.Button,{variant:"tertiary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s})},__next40pxDefaultSize:!0,children:(0,a.__)("Enable all actions","zenpress")}),(0,p.jsx)(r.Button,{isDestructive:!0,onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,a.__)("Disable all actions","zenpress")})]}),(0,p.jsx)(u,{onClick:h,isBusy:z})]})]})]}),(0,p.jsx)("aside",{className:"zenpress-sidebar",children:(0,p.jsx)("div",{className:"zenpress-presets",children:(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("h2",{children:(0,a.__)("Pick configuration preset","zenpress")}),(0,p.jsx)("p",{children:(0,a.__)("Don't know which features to enable? Quickly configure ZenPress by selecting a preset that matches your site type. Each preset enables optimized features for your specific use case.","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🖼️ ",(0,a.__)("Corporate website","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Optimized for business sites and portfolios. Focuses on security, performance, and removing unnecessary features like RSS feeds and author archives.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("corporate-website"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:[" 📰 ",(0,a.__)("Blog","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Tailored for content-focused blogs. Includes performance and security optimizations while preserving essential blog features like RSS feeds.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("blog"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🛒 ",(0,a.__)("E-commerce","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Designed for WooCommerce stores. Includes all performance and security features plus WooCommerce-specific optimizations for faster checkout.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("ecommerce"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")})]})})})]})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(z,{}))})})(); -
zenpress/tags/2.2.2/assets/src/js/hooks/useSettings.js
r3448585 r3451904 9 9 * 10 10 * @return {Object} Settings state and actions. 11 * @property {Object} snippets - Current snippets with metadata. 12 * @property {Function} setSnippets - Setter to update snippets state. 13 * @property {Function} saveSettings - Function to persist settings to REST API. 14 * @property {boolean} isSaving - Whether settings are currently being saved. 11 * @property {Object} snippets - Current snippets with metadata. 12 * @property {Function} setSnippets - Setter to update snippets state. 13 * @property {boolean} adminBarEnabled - Whether the ZenPress admin bar is enabled. 14 * @property {Function} setAdminBarEnabled - Setter for admin bar enabled. 15 * @property {Function} saveSettings - Function to persist settings to REST API. 16 * @property {boolean} isSaving - Whether settings are currently being saved. 15 17 */ 16 18 export const useSettings = () => { 17 19 const [snippets, setSnippets] = useState({}); 20 const [adminBarEnabled, setAdminBarEnabled] = useState(true); 18 21 const [isSaving, setIsSaving] = useState(false); 19 22 const { createSuccessNotice, createErrorNotice } = … … 38 41 39 42 setSnippets(snippetsData); 43 setAdminBarEnabled( 44 settings?.zenpress_admin_bar_enabled !== false 45 ); 40 46 }) 41 47 .catch(() => { … … 55 61 path: '/wp/v2/settings', 56 62 method: 'POST', 57 data: { zenpress_active_snippets: active }, 63 data: { 64 zenpress_active_snippets: active, 65 zenpress_admin_bar_enabled: adminBarEnabled, 66 }, 58 67 }); 59 68 createSuccessNotice(__('Settings saved.', 'zenpress')); … … 65 74 }; 66 75 67 return { snippets, setSnippets, saveSettings, isSaving }; 76 return { 77 snippets, 78 setSnippets, 79 adminBarEnabled, 80 setAdminBarEnabled, 81 saveSettings, 82 isSaving, 83 }; 68 84 }; -
zenpress/tags/2.2.2/assets/src/js/pages/SettingsPage.js
r3448585 r3451904 2 2 import { __ } from '@wordpress/i18n'; 3 3 import { Button } from '@wordpress/components'; 4 import { useDispatch } from '@wordpress/data'; 5 import { store as noticesStore } from '@wordpress/notices'; 6 import apiFetch from '@wordpress/api-fetch'; 4 7 import { useSettings } from '../hooks/useSettings'; 5 8 import { SnippetToggleControl } from '../components/SnippetToggleControl'; … … 14 17 */ 15 18 export const SettingsPage = () => { 16 const { snippets, setSnippets, saveSettings, isSaving } = useSettings(); 19 const { 20 snippets, 21 setSnippets, 22 adminBarEnabled, 23 setAdminBarEnabled, 24 saveSettings, 25 isSaving, 26 } = useSettings(); 17 27 const [selectedTabId, setSelectedTabId] = useState(); 28 const [autoconfigBusy, setAutoconfigBusy] = useState(null); 29 const { createSuccessNotice, createErrorNotice } = 30 useDispatch(noticesStore); 18 31 19 32 const handleToggleChange = (snippetName) => { … … 133 146 setSelectedTabId(tabName); 134 147 }; 148 149 const runAutoconfig = async ( 150 integrationKey, 151 path, 152 successMessage, 153 errorMessage 154 ) => { 155 setAutoconfigBusy(integrationKey); 156 try { 157 const response = await apiFetch({ 158 path, 159 method: 'POST', 160 }); 161 createSuccessNotice(response?.message || successMessage); 162 } catch { 163 createErrorNotice(errorMessage); 164 } finally { 165 setAutoconfigBusy(null); 166 } 167 }; 168 169 const handleAutoconfigAutoptimize = () => 170 runAutoconfig( 171 'autoptimize', 172 '/zenpress/v1/autoconfig/autoptimize', 173 __('Autoptimize has been configured.', 'zenpress'), 174 __( 175 'Autoptimize autoconfig failed. Is Autoptimize installed and active?', 176 'zenpress' 177 ) 178 ); 179 180 const handleAutoconfigCacheEnabler = () => 181 runAutoconfig( 182 'cache_enabler', 183 '/zenpress/v1/autoconfig/cache-enabler', 184 __('Cache Enabler has been configured.', 'zenpress'), 185 __( 186 'Cache Enabler autoconfig failed. Is Cache Enabler installed and active?', 187 'zenpress' 188 ) 189 ); 190 191 const handleAutoconfigSqliteObjectCache = () => 192 runAutoconfig( 193 'sqlite_object_cache', 194 '/zenpress/v1/autoconfig/sqlite-object-cache', 195 __('SQLite Object Cache has been configured.', 'zenpress'), 196 __( 197 'SQLite Object Cache autoconfig failed. Is SQLite Object Cache installed and active?', 198 'zenpress' 199 ) 200 ); 135 201 136 202 // Add keyboard shortcuts and ensure toggles are keyboard accessible … … 221 287 </div> 222 288 ))} 289 {category === 'tools' && 290 Object.values( 291 window?.zenpressIntegrationsActive || 292 {} 293 ).some(Boolean) && ( 294 <div className="zenpress-subcategory zenpress-subcategory-integrations"> 295 <hr /> 296 <h3> 297 {__( 298 'Integrations', 299 'zenpress' 300 )} 301 </h3> 302 <SnippetToggleControl 303 label={__( 304 'Show ZenPress admin bar button', 305 'zenpress' 306 )} 307 value={adminBarEnabled} 308 onChange={() => 309 setAdminBarEnabled( 310 !adminBarEnabled 311 ) 312 } 313 help={__( 314 'Show a "ZenPress" item in the admin bar with "Clear caches". When enabled, integration buttons (e.g. Autoptimize) are hidden.', 315 'zenpress' 316 )} 317 /> 318 {window 319 ?.zenpressIntegrationsActive 320 ?.autoptimize && ( 321 <div className="zenpress-autoconfig-actions"> 322 <Button 323 variant="secondary" 324 onClick={ 325 handleAutoconfigAutoptimize 326 } 327 disabled={ 328 autoconfigBusy !== 329 null 330 } 331 __next40pxDefaultSize 332 > 333 {autoconfigBusy === 334 'autoptimize' 335 ? __( 336 'Applying…', 337 'zenpress' 338 ) 339 : __( 340 'One-click autoconfig Autoptimize', 341 'zenpress' 342 )} 343 </Button> 344 <p className="zenpress-autoconfig-help"> 345 {__( 346 'Apply recommended Autoptimize settings (optimize JS/CSS, aggregate CSS, static files, 404 fallbacks; disable defer, HTML optimize, optimize for logged-in, per post/page). Only works if Autoptimize is active.', 347 'zenpress' 348 )} 349 </p> 350 </div> 351 )} 352 {window 353 ?.zenpressIntegrationsActive 354 ?.cache_enabler && ( 355 <div className="zenpress-autoconfig-actions"> 356 <Button 357 variant="secondary" 358 onClick={ 359 handleAutoconfigCacheEnabler 360 } 361 disabled={ 362 autoconfigBusy !== 363 null 364 } 365 __next40pxDefaultSize 366 > 367 {autoconfigBusy === 368 'cache_enabler' 369 ? __( 370 'Applying…', 371 'zenpress' 372 ) 373 : __( 374 'One-click autoconfig Cache Enabler', 375 'zenpress' 376 )} 377 </Button> 378 <p className="zenpress-autoconfig-help"> 379 {__( 380 'Apply recommended Cache Enabler settings. Only works if Cache Enabler is active.', 381 'zenpress' 382 )} 383 </p> 384 </div> 385 )} 386 {window 387 ?.zenpressIntegrationsActive 388 ?.sqlite_object_cache && ( 389 <div className="zenpress-autoconfig-actions"> 390 <Button 391 variant="secondary" 392 onClick={ 393 handleAutoconfigSqliteObjectCache 394 } 395 disabled={ 396 autoconfigBusy !== 397 null 398 } 399 __next40pxDefaultSize 400 > 401 {autoconfigBusy === 402 'sqlite_object_cache' 403 ? __( 404 'Applying…', 405 'zenpress' 406 ) 407 : __( 408 'One-click autoconfig SQLite Object Cache', 409 'zenpress' 410 )} 411 </Button> 412 <p className="zenpress-autoconfig-help"> 413 {__( 414 'Apply recommended SQLite Object Cache settings. Only works if SQLite Object Cache is active.', 415 'zenpress' 416 )} 417 </p> 418 </div> 419 )} 420 </div> 421 )} 223 422 </Tabs.TabPanel> 224 423 ); -
zenpress/tags/2.2.2/assets/src/scss/pages/_settings.scss
r3412245 r3451904 197 197 } 198 198 } 199 200 &-integrations { 201 h3::before { 202 content: '🔌'; 203 } 204 } 205 } 206 207 &-autoconfig-actions { 208 margin-top: 1em; 209 } 210 211 &-autoconfig-help { 212 margin-top: 0.5em; 213 margin-bottom: 0; 214 font-size: 0.9em; 215 opacity: 0.9; 199 216 } 200 217 } -
zenpress/tags/2.2.2/inc/admin/enqueue.php
r3448585 r3451904 6 6 7 7 /** 8 * Enqueue scripts and styles used by the plugin in admin area. 9 * 10 * @param string $admin_page Current admin page hook. 11 * @return void 8 * Enqueues script and style on ZenPress settings page only. 12 9 */ 13 10 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); … … 49 46 50 47 /** 51 * Localize translated snippet metadata for use in JavaScript. 52 * 53 * @param string $admin_page Current admin page hook. 54 * @return void 48 * Localizes zenpressSnippetsMeta and zenpressIntegrationsActive on ZenPress settings page. 55 49 */ 56 50 add_action('admin_enqueue_scripts', 'zenpress_localize_snippets_meta'); … … 73 67 74 68 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets); 69 wp_localize_script('zenpress-scripts', 'zenpressIntegrationsActive', ZenPress_Integrations::get_active_integrations_for_ui()); 75 70 } -
zenpress/tags/2.2.2/inc/admin/links.php
r3372200 r3451904 6 6 7 7 /** 8 * Add a settings link on the plugins list page. 9 * 10 * @param array $links Existing plugin action links. 11 * @return array Modified plugin action links. 8 * Adds "Settings" to plugin action links on Plugins screen. 12 9 */ 13 10 add_filter('plugin_action_links_' . plugin_basename(ZENPRESS_PLUGIN_FILE), 'zenpress_add_settings_link'); … … 25 22 26 23 /** 27 * Add extra links under the plugin description on the plugins page. 28 * 29 * @param array $links Existing row meta links. 30 * @param string $file Current plugin file. 31 * @return array Modified row meta links. 24 * Adds Changelog, Docs, Support to plugin row meta for ZenPress. 32 25 */ 33 26 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2); -
zenpress/tags/2.2.2/inc/admin/menu.php
r3412245 r3451904 6 6 7 7 /** 8 * Register ZenPress options page under the Settings menu. 9 * 10 * @return void 8 * Adds ZenPress under Settings. 11 9 */ 12 10 add_action('admin_menu', 'zenpress_add_option_page'); … … 22 20 23 21 /** 24 * Render ZenPress options page content. 25 * 26 * @return void 22 * Outputs ZenPress settings page (shell; React app mounts in #zenpress-settings). 27 23 */ 28 24 function zenpress_options_page(): void { -
zenpress/tags/2.2.2/inc/core/constants.php
r3448604 r3451904 1 1 <?php 2 2 /** 3 * ZenPress constants 3 * Plugin path constants. 4 * 4 5 * @package zenpress 5 6 */ -
zenpress/tags/2.2.2/inc/core/metadata.php
r3448585 r3451904 6 6 7 7 /** 8 * Extract snippet metadata from its meta file.8 * Loads and sanitizes snippet metadata from inc/snippets/meta/{$snippet_name}.meta.php. 9 9 * 10 * @param string $snippet_name Snippet base name ( withoutextension).11 * @return array<string, mixed> Sanitized metadata (title, description, category, weight, preset).10 * @param string $snippet_name Snippet base name (no extension). 11 * @return array<string, mixed> title, description, category, subcategory, weight, preset. 12 12 */ 13 13 function zenpress_extract_snippet_metadata(string $snippet_name): array { … … 22 22 23 23 $file = ZENPRESS_PLUGIN_DIR . 'inc/snippets/meta/' . sanitize_file_name($snippet_name) . '.meta.php'; 24 $data = is_file($file) ? include $file : []; 24 $data = []; 25 if (is_file($file)) { 26 try { 27 $data = include $file; 28 } catch (\Throwable $e) { 29 $data = []; 30 } 31 } 25 32 $metadata = array_merge($defaults, is_array($data) ? $data : []); 26 33 -
zenpress/tags/2.2.2/inc/core/sanitize.php
r3448585 r3451904 6 6 7 7 /** 8 * Sanitize the list of active snippets.8 * Sanitizes zenpress_active_snippets option to an array of file-safe base names. 9 9 * 10 * @param mixed $value Option value.11 * @return array<string> Sanitized base names.10 * @param mixed $value Raw option value. 11 * @return array<string> 12 12 */ 13 13 function zenpress_sanitize_snippets_option(mixed $value): array { -
zenpress/tags/2.2.2/inc/settings/loader.php
r3448585 r3451904 6 6 7 7 /** 8 * Load all activesnippets.8 * Includes active snippet files from the given folder. Skips path traversal and disabled-by-constant snippets. 9 9 * 10 * @param string $folder Relative folder path for snippets.10 * @param string $folder Relative path under plugin dir (default: inc/snippets/functions/). 11 11 * @return array<string> Loaded snippet base names. 12 12 */ … … 30 30 $constant = 'ZENPRESS_' . strtoupper(str_replace(['-', '_'], '_', $name)); 31 31 if (is_file($file) && (!defined($constant) || constant($constant) !== false)) { 32 include_once $file; 33 $loaded[] = $name; 32 try { 33 include_once $file; 34 $loaded[] = $name; 35 } catch (\Throwable $e) { 36 continue; 37 } 34 38 } 35 39 } -
zenpress/tags/2.2.2/inc/settings/options.php
r3448585 r3451904 6 6 7 7 /** 8 * Register option to store active snippets.8 * Registers zenpress_active_snippets and zenpress_admin_bar_enabled (REST + sanitize). 9 9 */ 10 10 add_action('init', 'zenpress_register_snippet_settings'); … … 25 25 ] 26 26 ); 27 28 register_setting( 29 'options', 30 'zenpress_admin_bar_enabled', 31 [ 32 'type' => 'boolean', 33 'default' => true, 34 'sanitize_callback' => 'zenpress_sanitize_admin_bar_enabled', 35 'show_in_rest' => [ 36 'schema' => ['type' => 'boolean'], 37 ], 38 ] 39 ); 27 40 } 41 42 /** 43 * Sanitizes zenpress_admin_bar_enabled to bool. 44 */ 45 function zenpress_sanitize_admin_bar_enabled(mixed $value): bool { 46 return (bool) $value; 47 } -
zenpress/tags/2.2.2/inc/snippets/functions/protect-wp-login.php
r3448585 r3451904 10 10 }); 11 11 12 // Limit login attempts 12 // Limit login attempts (only when a valid IP is available to avoid site-wide lockout) 13 13 add_filter('authenticate', static function (mixed $user, string $username, string $password): mixed { 14 $MAX_LOGIN_ATTEMPTS = 5;15 $BLOCK_DURATION = 300; // 5 minutes16 17 14 $ipAddress = filter_var( 18 15 wp_unslash($_SERVER['REMOTE_ADDR'] ?? ''), 19 16 FILTER_VALIDATE_IP 20 ) ?: 'unknown'; 17 ); 18 if ($ipAddress === false) { 19 return $user; 20 } 21 21 22 $MAX_LOGIN_ATTEMPTS = 5; 23 $BLOCK_DURATION = 300; // 5 minutes 22 24 $blockKey = 'zenpress_login_block_' . $ipAddress; 23 25 $attemptKey = 'zenpress_login_attempts_' . $ipAddress; -
zenpress/tags/2.2.2/readme.txt
r3448604 r3451904 5 5 Requires at least: 6.0 6 6 Tested up to: 6.9 7 Stable tag: 2.2. 18 Requires PHP: 8. 37 Stable tag: 2.2.3 8 Requires PHP: 8.1 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html/ … … 41 41 * Native WordPress interface, benefits from Gutenberg's new features and the site editor. 42 42 43 = Core - Performance=43 = Core = 44 44 45 45 * Disable adjacent posts link tags. … … 59 59 * Disable Password Strength Meter. 60 60 * Disable WordPress default lazy loading. 61 62 = Core - Security =63 64 61 * Block user enumeration. 65 62 * Disable application passwords. … … 69 66 * Disable XML-RPC and remove RSD link. 70 67 * Hide WordPress version. 71 72 = Core - User Interface =73 74 68 * Clean up the WordPress admin bar. 75 69 * Disable the login language selector. … … 78 72 * Remove "Thanks for using WordPress" in footer. 79 73 80 = WooCommerce - Performance=74 = WooCommerce = 81 75 * Disable WooCommerce cart fragments script. 82 76 * Disable WooCommerce scripts and styles on non-WooCommerce pages. … … 84 78 * Disable WooCommerce widgets. 85 79 * Remove WooCommerce default block patterns. 86 87 = WooCommerce - Security =88 80 * Hide WooCommerce version. 89 81 90 = Gutenberg - Performance=82 = Gutenberg = 91 83 * Remove WordPress default remote block patterns. 92 84 * Separate loading of core block styles. 93 94 = Gutenberg - User Interface =95 85 * Disable default pattern categories in site editor. 96 86 97 = Ads-blocker - User Interface=87 = Ads-blocker = 98 88 * Clean up the WordPress Dashboard. 99 89 100 = Tools - Security=90 = Tools = 101 91 * Protect the wp-login form from brute force attacks. 92 * Toggle "Show ZenPress admin bar button" (clear caches from the admin bar when at least one integration is active). 93 94 = Integrations = 95 96 ZenPress integrates with Cache Enabler, Autoptimize, and SQLite Object Cache. When any of these plugins is active, the Tools tab shows integration status and one-click autoconfig actions. 97 98 * Admin bar: One "Clear all caches" button (dashicon) in the admin bar, with sub-items to clear page cache (Cache Enabler), static assets (Autoptimize), or object cache (SQLite Object Cache) separately. The ZenPress button replaces the third-party cache buttons when the ZenPress admin bar is enabled. You can hide it via Settings > ZenPress > Tools. 99 * Autoptimize: One-click autoconfig enables recommended options (JS/CSS/aggregate/nogzip/fallback on; defer/HTML/logged-in/meta off) and clears the Autoptimize cache. 100 * Cache Enabler: One-click autoconfig enables clear site cache on post or plugin changes, WebP support, Gzip compression, and minify HTML (excluding inline CSS/JS), then clears the page cache. 101 * SQLite Object Cache: One-click autoconfig enables the "Use APCu" option in the plugin settings when the APCu extension is available (no wp-config editing; the plugin may write its constant when its own settings are saved). 102 102 103 103 = Presets = … … 115 115 == Roadmap == 116 116 117 = Global =118 117 * Additional presets for specific use cases. 119 118 * Documentation pages with detailed guides. 120 121 = Security =122 119 * Manage Heartbeat API (frontend + backend + admin whitelist). 123 124 = User Interface =125 120 * Remove "site health" page. 126 121 * Remove "Privacy tools". 127 128 = WooCommerce =129 122 * Disable WooCommerce tracking. 130 123 * Disable marketing hub. … … 133 126 * Disable WooCommerce blocks. 134 127 * Disable WooCommerce promo emails. 135 136 = Plugins =137 128 * Disable CF7 CSS & JS. 138 129 * Disable Elementor bloat. … … 204 195 Nice ! If you can't find anything in the roadmap, feel free to submit your suggestion on the support page! If you know how to code, you can even contribute on GitHub. 205 196 197 == Hooks & filters == 198 199 For developers: ZenPress exposes the following action and filters for extending or bypassing behavior. 200 201 = Action = 202 * `zenpress_caches_clear` – Fired when the user clears caches from the ZenPress admin bar. Integrations (e.g. Autoptimize) hook into this to clear their own caches. You can add custom cache clear logic with `add_action('zenpress_caches_clear', 'your_callback');`. 203 204 = Filters (Disable REST API snippet) = 205 * `zenpress_disable_wp_rest_api_post_var` – Allow unauthenticated REST access when a specific POST key is present (e.g. for webhooks). Return a string or array of key names. Use non-guessable values only. 206 * `zenpress_disable_wp_rest_api_server_var` – Allow unauthenticated REST access when `REQUEST_URI` matches a specific value. Return a string or array. Use non-guessable values only. 207 206 208 == Changelog == 209 210 = 2.2.3 = 211 - Integrations: Cache Enabler one-click autoconfig (clear on post/plugin, WebP, Gzip, minify HTML excl. inline CSS/JS). 212 - Integrations: SQLite Object Cache one-click autoconfig (enable "Use APCu" option when APCu available; no wp-config editing by ZenPress). 213 - Integrations: Admin bar "Clear all caches" button now uses dashicons-trash icon. 214 - Defensive: REST and AJAX handlers wrap integration calls in try/catch; failed autoconfig or cache clear returns 500 with message instead of fatal. 215 - Defensive: get_active_integrations_for_ui() wraps ReflectionClass in try/catch so one missing integration does not break the settings UI. 216 - Defensive: Cache Enabler autoconfig ensures option value is array before merge (corrupted option no longer triggers warning). 217 - Defensive: Metadata and snippet loader wrap include in try/catch so a single bad meta file or snippet does not fatal the site. 218 - Defensive: Protect wp-login skips rate limiting when REMOTE_ADDR is missing or invalid to avoid site-wide lockout (e.g. CLI or proxy). 219 - Defensive: Autoptimize clear_cache and autoconfig check method_exists before calling third-party API. 220 - Docblocks: Reviewed and tightened docblocks across inc/ (file headers, classes, methods) for coherence, readability, and conciseness; removed redundant @param/@return where type is obvious. 221 - Lint: PHPStan and PHP CS Fixer fixes (autoptimize method_exists ignore, protect-wp-login strict comparison). 222 223 = 2.2.2 = 224 - Integrations: Admin bar and one-click autoconfig (e.g. Autoptimize) in Tools tab; visible only when at least one integration is active. 225 - Documentation: Added Hooks & filters section in readme; Integrations section in workflow.md; config comments for PHPStan and PHP CS Fixer. 226 - Version alignment: Stable tag and plugin header set to 2.2.2. 207 227 208 228 = 2.2.1 = … … 338 358 == Upgrade Notice == 339 359 360 = 2.2.3 = 361 - Integrations: Cache Enabler and SQLite Object Cache one-click autoconfig; admin bar trash icon; defensive fixes and docblock cleanup. 362 363 = 2.2.2 = 364 - Integrations: ZenPress admin bar and one-click autoconfig in Tools tab (Autoptimize). Documentation updates. 365 340 366 = 2.2.1 = 341 367 - Security and code quality improvements. Recommended update. 342 368 343 369 = 2.2.0 = 344 - Breaking: PHP 8. 3is now required (PHP 7.4 support dropped). Major code modernization with improved type safety and performance.370 - Breaking: PHP 8.1 is now required (PHP 7.4 support dropped). Major code modernization with improved type safety and performance. 345 371 - Security: HTTP 403 on login block, path traversal guard in snippet loader, and in-code docs for REST API bypass filters. 346 372 -
zenpress/tags/2.2.2/zenpress.php
r3448604 r3451904 12 12 * Plugin Name: ZenPress - Optimize & Secure 13 13 * Description: Easily speed up and strengthen your WordPress site by cleaning out unnecessary features and protecting weak points. 14 * Version: 2.2. 114 * Version: 2.2.2 15 15 * Plugin URI: https://wordpress.org/plugins/zenpress/ 16 16 * Author: Quentin Le Duff … … 20 20 * Requires at least: 6.0 21 21 * Tested up to: 6.9 22 * Requires PHP: 8. 322 * Requires PHP: 8.1 23 23 * License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html/ 24 24 * License: GPL v2 or later … … 47 47 require_once __DIR__ . '/inc/core/sanitize.php'; 48 48 49 // Integrations (one file per plugin: handlers + autoconfig) 50 require_once __DIR__ . '/inc/classes/autoptimize.php'; 51 require_once __DIR__ . '/inc/classes/cache-enabler.php'; 52 require_once __DIR__ . '/inc/classes/sqlite-object-cache.php'; 53 require_once __DIR__ . '/inc/classes/integrations.php'; 54 49 55 // Admin UI 50 56 require_once __DIR__ . '/inc/admin/enqueue.php'; -
zenpress/trunk/assets/build/index-rtl.css
r3412245 r3451904 1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-left:1px solid #d6e2ed;flex-direction:column;padding-left:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:right;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;left:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-right:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;right:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress- tabs__panel h2{font-size:1.5em;padding-right:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;right:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""}1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-left:1px solid #d6e2ed;flex-direction:column;padding-left:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:right;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;left:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-right:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;right:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress-subcategory-integrations h3:before{content:"🔌"}.zenpress-autoconfig-actions{margin-top:1em}.zenpress-autoconfig-help{font-size:.9em;margin-bottom:0;margin-top:.5em;opacity:.9}.zenpress-tabs__panel h2{font-size:1.5em;padding-right:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;right:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""} -
zenpress/trunk/assets/build/index.asset.php
r3448585 r3451904 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => ' 253355e0f124eff32114');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => '71f7100577c2edd9e445'); -
zenpress/trunk/assets/build/index.css
r3412245 r3451904 1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-right:1px solid #d6e2ed;flex-direction:column;padding-right:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:left;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;right:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-left:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;left:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress- tabs__panel h2{font-size:1.5em;padding-left:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;left:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""}1 .components-button{gap:4px}.components-notice-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;width:100%}.zenpress-tabs{display:grid;gap:0;width:100%}.zenpress-tabs--vertical{grid-template-columns:200px 1fr}@media screen and (max-width:768px){.zenpress-tabs--vertical{grid-template-columns:1fr}}.zenpress-tabs__list{display:flex;list-style:none;margin:0}.zenpress-tabs__list--vertical{border-right:1px solid #d6e2ed;flex-direction:column;padding-right:0}.zenpress-tabs__tab{align-items:center;background:transparent;border:none;border-radius:0;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:flex;font-size:13px;font-weight:400;gap:8px;line-height:1.2;margin:0;min-height:40px;padding:16px;position:relative;text-align:left;transition:all .1s ease}.zenpress-tabs__tab:before{display:inline-block;font-family:dashicons;font-size:20px;height:20px;line-height:1;text-align:center;width:20px}.zenpress-tabs__tab:hover{background:#f0f0f1;color:#1e1e1e}.zenpress-tabs__tab:focus,.zenpress-tabs__tab:hover{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__tab--is-active{background:transparent;background-color:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),transparent 96%);color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));fill:currentcolor;font-weight:400}.zenpress-tabs__tab--is-active:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))));bottom:0;content:"";position:absolute;right:0;top:0;width:3px}.zenpress-tabs__tab--category-core:before{content:""}.zenpress-tabs__tab--category-gutenberg:before{content:""}.zenpress-tabs__tab--category-woocommerce:before{content:""}.zenpress-tabs__tab--category-tools:before{content:""}.zenpress-tabs__tab--category-ads-blocker:before{content:""}.zenpress-tabs__list--vertical .zenpress-tabs__tab{justify-content:flex-start;width:100%}.zenpress-tabs__panel{flex:1;height:65vh;max-height:65vh;min-width:0;overflow:auto;padding:16px 16px 0;position:relative}@media screen and (max-width:1281px){.zenpress-tabs__panel{height:600px;max-height:600px}}@media screen and (max-width:960px){.zenpress-tabs__panel{height:unset;max-height:unset}}.zenpress-tabs__panel:focus{box-shadow:inset 0 0 0 2px #1e1e1e!important;outline:2px solid transparent}.zenpress-tabs__panel[hidden]{display:none}.components-toggle-control{margin:1em 0}.components-toggle-control__help{font-size:1.1em}.zenpress-dashboard-wrap *{box-sizing:border-box}.zenpress-dashboard-wrap a:not(.components-button){color:var(--wp-components-color-accent,var(--wp-admin-theme-color,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))))}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]{gap:4px;position:relative}.zenpress-dashboard-wrap a:not(.components-button)[target=_blank]:after{content:" ↗"}.zenpress-footer,.zenpress-header,.zenpress-loading,.zenpress-row,.zenpress-settings{margin:0 auto;max-width:1440px;width:100%}.zenpress-header{background:#fff;border:1px solid #e0e0e0;border-radius:4px;gap:40px;overflow-x:auto;padding:16px}.zenpress-header,.zenpress-header-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-header-navigation{gap:16px}.zenpress-header h1,.zenpress-header p{margin:0;padding:0}.zenpress-footer{border-top:1px solid #e0e0e0;gap:32px;overflow-x:auto;padding:32px 16px 16px}.zenpress-footer,.zenpress-footer-navigation{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.zenpress-footer-navigation{gap:16px}.zenpress-footer p{margin:0;padding:0}.zenpress-settings{border-radius:4px;margin-bottom:32px;margin-top:32px}@media screen and (max-width:1281px){.zenpress-settings{margin-bottom:16px;margin-top:16px}}.zenpress-row{display:grid;gap:32px;grid-template-columns:3fr 1fr}@media screen and (max-width:1281px){.zenpress-row{gap:16px}}@media screen and (max-width:960px){.zenpress-row{grid-template-columns:1fr}}.zenpress-panel{background:#fff;border:1px solid #e0e0e0;border-radius:4px}.zenpress-main,.zenpress-notices,.zenpress-panel{max-width:100%;width:100%}.zenpress-actions{border-top:1px solid #e0e0e0;gap:16px;justify-content:space-between;padding:16px}.zenpress-actions,.zenpress-actions-bulk{align-items:center;display:flex;flex-wrap:wrap}.zenpress-actions-bulk{gap:8px;justify-content:flex-start}.zenpress-sidebar{align-items:stretch;display:flex;flex-direction:column;gap:16px;justify-content:flex-start}.zenpress-sidebar hr{margin-top:2em}.zenpress-presets{background:#fff;border:1px solid #e0e0e0;border-radius:4px;max-width:100%;padding:16px;width:100%}.zenpress-subcategory h3{margin-bottom:1.5em;padding-left:32px;position:relative}.zenpress-subcategory h3:before{display:inline-block;font-size:20px;height:20px;left:0;line-height:1;position:absolute;top:50%;transform:translateY(-50%);width:20px}.zenpress-subcategory-performance h3:before{content:"🚀"}.zenpress-subcategory-security h3:before{content:"🛡️"}.zenpress-subcategory-user-interface h3:before{content:"💻️"}.zenpress-subcategory-integrations h3:before{content:"🔌"}.zenpress-autoconfig-actions{margin-top:1em}.zenpress-autoconfig-help{font-size:.9em;margin-bottom:0;margin-top:.5em;opacity:.9}.zenpress-tabs__panel h2{font-size:1.5em;padding-left:36px;position:relative}.zenpress-tabs__panel h2:before{content:"";display:inline-block;font-family:dashicons;font-size:28px;height:28px;left:0;line-height:28px;position:absolute;text-align:center;top:50%;transform:translateY(-50%);width:28px}#zenpress-tab-panel-core h2:before{content:""}#zenpress-tab-panel-gutenberg h2:before{content:""}#zenpress-tab-panel-woocommerce h2:before{content:""}#zenpress-tab-panel-tools h2:before{content:""}#zenpress-tab-panel-ads-blocker h2:before{content:""} -
zenpress/trunk/assets/build/index.js
r3448585 r3451904 1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element, r=window.wp.i18n,a=window.wp.components,i=window.wp.apiFetch;var o=e.n(i);const c=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:r})=>{const i=(0,n.useRef)(null);return(0,n.useEffect)(()=>((e,s)=>{if(!e)return;const t=t=>{if("Enter"===t.key){const n=e.querySelector('input[type="checkbox"]'),r=e.ownerDocument||document;n&&(r.activeElement===n||e.contains(r.activeElement))&&(t.preventDefault(),t.stopPropagation(),s())}};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}})(i.current,t),[t]),(0,p.jsx)("div",{ref:i,children:(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:r,__nextHasNoMarginBottom:!0})})},u=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,r.__)("Save settings","zenpress")}),b=()=>{const{removeNotice:e}=(0,c.useDispatch)(l.store),s=(0,c.useSelect)(e=>e(l.store).getNotices(),[]);return s&&0!==s.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},h=(0,n.createContext)(),f=({selectedTabId:e,onSelect:s,orientation:t="horizontal",children:r})=>{const[a,i]=(0,n.useState)(),o=(0,n.useRef)(null),c=void 0!==e?e:a;return(0,p.jsx)(h.Provider,{value:{selectedTabId:c,onSelect:t=>{void 0===e&&i(t),s?.(t)},orientation:t,getOrderedTabIds:()=>o.current?Array.from(o.current.querySelectorAll('[role="tab"]')).map(e=>{const s=e.getAttribute("id");return s?s.replace("zenpress-tab-",""):null}).filter(Boolean):[],tabListRef:o},children:(0,p.jsx)("div",{className:`zenpress-tabs zenpress-tabs--${t}`,children:r})})};f.TabList=({children:e})=>{const{orientation:s,tabListRef:t}=(0,n.useContext)(h);return(0,p.jsx)("div",{ref:t,className:`zenpress-tabs__list zenpress-tabs__list--${s}`,role:"tablist","aria-orientation":s,children:e})},f.Tab=({tabId:e,title:s,className:t="",children:r})=>{const{selectedTabId:a,onSelect:i,orientation:o,getOrderedTabIds:c}=(0,n.useContext)(h),l=a===e,d=(0,n.useRef)(null);return(0,p.jsx)("button",{ref:d,className:`zenpress-tabs__tab ${l?"zenpress-tabs__tab--is-active":""} ${t}`.trim(),role:"tab","aria-selected":l,"aria-controls":`zenpress-tab-panel-${e}`,id:`zenpress-tab-${e}`,tabIndex:l?0:-1,onClick:()=>i(e),onKeyDown:s=>{const t=c();if(!t||0===t.length)return;const n=t.indexOf(e);if(-1===n)return;let r=n;if("vertical"===o?"ArrowDown"===s.key?(s.preventDefault(),r=n<t.length-1?n+1:0):"ArrowUp"===s.key&&(s.preventDefault(),r=n>0?n-1:t.length-1):"ArrowRight"===s.key?(s.preventDefault(),r=n<t.length-1?n+1:0):"ArrowLeft"===s.key&&(s.preventDefault(),r=n>0?n-1:t.length-1),"Home"===s.key?(s.preventDefault(),r=0):"End"===s.key&&(s.preventDefault(),r=t.length-1)," "===s.key||"Enter"===s.key)return s.preventDefault(),void i(e);if(r!==n&&r>=0&&r<t.length){const e=t[r],s=document.getElementById(`zenpress-tab-${e}`);s&&(s.focus(),i(e))}},onFocus:()=>{l||i(e)},children:s||r})},f.TabPanel=({tabId:e,children:s})=>{const{selectedTabId:t}=(0,n.useContext)(h),r=(0,n.useRef)(null),a=t===e;return(0,n.useEffect)(()=>{a&&r.current&&(0===r.current.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])').length?r.current.setAttribute("tabindex","0"):r.current.removeAttribute("tabindex"))},[a]),a?(0,p.jsx)("div",{ref:r,className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,children:s}):(0,p.jsx)("div",{className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,hidden:!0,children:s})};const x=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:i}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:i,createErrorNotice:p}=(0,c.useDispatch)(l.store);return(0,n.useEffect)(()=>{o()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n=window?.zenpressSnippetsMeta||{},r={};Object.keys(n).forEach(e=>{r[e]={...n[e],"enable-snippet":t.includes(e)}}),s(r)}).catch(()=>{p((0,r.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:async()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]);try{await o()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}),i((0,r.__)("Settings saved.","zenpress"))}catch{p((0,r.__)("Failed to save settings.","zenpress"))}finally{a(!1)}},isSaving:t}})(),[h,x]=(0,n.useState)(),_=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const r=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":r}}),t})},m=e=>e?e.charAt(0).toUpperCase()+e.slice(1).toLowerCase():e,v=["core","gutenberg","woocommerce","ads-blocker","tools"],y={};Object.keys(e).forEach(s=>{const t=e[s],n=(t?.category||(0,r.__)("Uncategorized","zenpress")).toLowerCase(),a=(t?.subcategory||(0,r.__)("uncategorized","zenpress")).toLowerCase();y[n]||(y[n]={}),y[n][a]||(y[n][a]=[]),y[n][a].push({name:s,data:t})});const z=Object.keys(y).sort((e,s)=>{const t=v.indexOf(e.toLowerCase()),n=v.indexOf(s.toLowerCase());return-1!==t&&-1!==n?t-n:-1!==t?-1:-1!==n?1:e.localeCompare(s,void 0,{sensitivity:"base"})});return(0,n.useEffect)(()=>{!h&&z.length>0&&x(z[0])},[h,z]),(0,n.useEffect)(()=>{const e=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),i||t())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[t,i]),(0,p.jsxs)("article",{className:"zenpress-row",children:[(0,p.jsxs)("section",{className:"zenpress-main",children:[(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(b,{})}),(0,p.jsxs)("div",{className:"zenpress-panel",children:[(0,p.jsxs)(f,{orientation:"vertical",selectedTabId:h,onSelect:e=>{x(e),x(e)},children:[(0,p.jsx)(f.TabList,{children:z.map(e=>{const s=`zenpress-tabs__tab--category-${e.toLowerCase().replace(/\s+/g,"-")}`;return(0,p.jsx)(f.Tab,{tabId:e,title:m(e),className:s,children:m(e)},e)})}),z.map(e=>{const t=Object.keys(y[e]).sort();return(0,p.jsxs)(f.TabPanel,{tabId:e,children:[(0,p.jsx)("h2",{children:m(e)}),t.map(t=>(0,p.jsxs)("div",{className:`zenpress-subcategory zenpress-subcategory-${t.toLowerCase().replace(/\s+/g,"-")}`,children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:m(t)}),y[e][t].map(({name:e,data:t})=>(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""},e))]},t))]},e)})]}),(0,p.jsxs)("div",{className:"zenpress-actions",children:[(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"tertiary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s})},__next40pxDefaultSize:!0,children:(0,r.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:!0,onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,r.__)("Disable all actions","zenpress")})]}),(0,p.jsx)(u,{onClick:t,isBusy:i})]})]})]}),(0,p.jsx)("aside",{className:"zenpress-sidebar",children:(0,p.jsx)("div",{className:"zenpress-presets",children:(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("h2",{children:(0,r.__)("Pick configuration preset","zenpress")}),(0,p.jsx)("p",{children:(0,r.__)("Don't know which features to enable? Quickly configure ZenPress by selecting a preset that matches your site type. Each preset enables optimized features for your specific use case.","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🖼️ ",(0,r.__)("Corporate website","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Optimized for business sites and portfolios. Focuses on security, performance, and removing unnecessary features like RSS feeds and author archives.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("corporate-website"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:[" 📰 ",(0,r.__)("Blog","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Tailored for content-focused blogs. Includes performance and security optimizations while preserving essential blog features like RSS feeds.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("blog"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🛒 ",(0,r.__)("E-commerce","zenpress")]}),(0,p.jsx)("p",{children:(0,r.__)("Designed for WooCommerce stores. Includes all performance and security features plus WooCommerce-specific optimizations for faster checkout.","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>_("ecommerce"),__next40pxDefaultSize:!0,children:(0,r.__)("Enable","zenpress")})]})})})]})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(x,{}))})})();1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,a=window.wp.i18n,r=window.wp.components,i=window.wp.data,c=window.wp.notices,o=window.wp.apiFetch;var l=e.n(o);const p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:a})=>{const i=(0,n.useRef)(null);return(0,n.useEffect)(()=>((e,s)=>{if(!e)return;const t=t=>{if("Enter"===t.key){const n=e.querySelector('input[type="checkbox"]'),a=e.ownerDocument||document;n&&(a.activeElement===n||e.contains(a.activeElement))&&(t.preventDefault(),t.stopPropagation(),s())}};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}})(i.current,t),[t]),(0,p.jsx)("div",{ref:i,children:(0,p.jsx)(r.ToggleControl,{label:e,checked:s,onChange:t,help:a,__nextHasNoMarginBottom:!0})})},u=({onClick:e,isBusy:s})=>(0,p.jsx)(r.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,a.__)("Save settings","zenpress")}),b=()=>{const{removeNotice:e}=(0,i.useDispatch)(c.store),s=(0,i.useSelect)(e=>e(c.store).getNotices(),[]);return s&&0!==s.length?(0,p.jsx)(r.NoticeList,{notices:s,onRemove:e}):null},h=(0,n.createContext)(),_=({selectedTabId:e,onSelect:s,orientation:t="horizontal",children:a})=>{const[r,i]=(0,n.useState)(),c=(0,n.useRef)(null),o=void 0!==e?e:r;return(0,p.jsx)(h.Provider,{value:{selectedTabId:o,onSelect:t=>{void 0===e&&i(t),s?.(t)},orientation:t,getOrderedTabIds:()=>c.current?Array.from(c.current.querySelectorAll('[role="tab"]')).map(e=>{const s=e.getAttribute("id");return s?s.replace("zenpress-tab-",""):null}).filter(Boolean):[],tabListRef:c},children:(0,p.jsx)("div",{className:`zenpress-tabs zenpress-tabs--${t}`,children:a})})};_.TabList=({children:e})=>{const{orientation:s,tabListRef:t}=(0,n.useContext)(h);return(0,p.jsx)("div",{ref:t,className:`zenpress-tabs__list zenpress-tabs__list--${s}`,role:"tablist","aria-orientation":s,children:e})},_.Tab=({tabId:e,title:s,className:t="",children:a})=>{const{selectedTabId:r,onSelect:i,orientation:c,getOrderedTabIds:o}=(0,n.useContext)(h),l=r===e,d=(0,n.useRef)(null);return(0,p.jsx)("button",{ref:d,className:`zenpress-tabs__tab ${l?"zenpress-tabs__tab--is-active":""} ${t}`.trim(),role:"tab","aria-selected":l,"aria-controls":`zenpress-tab-panel-${e}`,id:`zenpress-tab-${e}`,tabIndex:l?0:-1,onClick:()=>i(e),onKeyDown:s=>{const t=o();if(!t||0===t.length)return;const n=t.indexOf(e);if(-1===n)return;let a=n;if("vertical"===c?"ArrowDown"===s.key?(s.preventDefault(),a=n<t.length-1?n+1:0):"ArrowUp"===s.key&&(s.preventDefault(),a=n>0?n-1:t.length-1):"ArrowRight"===s.key?(s.preventDefault(),a=n<t.length-1?n+1:0):"ArrowLeft"===s.key&&(s.preventDefault(),a=n>0?n-1:t.length-1),"Home"===s.key?(s.preventDefault(),a=0):"End"===s.key&&(s.preventDefault(),a=t.length-1)," "===s.key||"Enter"===s.key)return s.preventDefault(),void i(e);if(a!==n&&a>=0&&a<t.length){const e=t[a],s=document.getElementById(`zenpress-tab-${e}`);s&&(s.focus(),i(e))}},onFocus:()=>{l||i(e)},children:s||a})},_.TabPanel=({tabId:e,children:s})=>{const{selectedTabId:t}=(0,n.useContext)(h),a=(0,n.useRef)(null),r=t===e;return(0,n.useEffect)(()=>{r&&a.current&&(0===a.current.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])').length?a.current.setAttribute("tabindex","0"):a.current.removeAttribute("tabindex"))},[r]),r?(0,p.jsx)("div",{ref:a,className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,children:s}):(0,p.jsx)("div",{className:"zenpress-tabs__panel",role:"tabpanel",id:`zenpress-tab-panel-${e}`,"aria-labelledby":`zenpress-tab-${e}`,hidden:!0,children:s})};const z=()=>{const{snippets:e,setSnippets:s,adminBarEnabled:t,setAdminBarEnabled:o,saveSettings:h,isSaving:z}=(()=>{const[e,s]=(0,n.useState)({}),[t,r]=(0,n.useState)(!0),[o,p]=(0,n.useState)(!1),{createSuccessNotice:d,createErrorNotice:u}=(0,i.useDispatch)(c.store);return(0,n.useEffect)(()=>{l()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n=window?.zenpressSnippetsMeta||{},a={};Object.keys(n).forEach(e=>{a[e]={...n[e],"enable-snippet":t.includes(e)}}),s(a),r(!1!==e?.zenpress_admin_bar_enabled)}).catch(()=>{u((0,a.__)("Failed to load settings.","zenpress"))})},[u]),{snippets:e,setSnippets:s,adminBarEnabled:t,setAdminBarEnabled:r,saveSettings:async()=>{p(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]);try{await l()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s,zenpress_admin_bar_enabled:t}}),d((0,a.__)("Settings saved.","zenpress"))}catch{u((0,a.__)("Failed to save settings.","zenpress"))}finally{p(!1)}},isSaving:o}})(),[f,m]=(0,n.useState)(),[g,v]=(0,n.useState)(null),{createSuccessNotice:x,createErrorNotice:y}=(0,i.useDispatch)(c.store),j=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const a=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":a}}),t})},w=e=>e?e.charAt(0).toUpperCase()+e.slice(1).toLowerCase():e,S=["core","gutenberg","woocommerce","ads-blocker","tools"],k={};Object.keys(e).forEach(s=>{const t=e[s],n=(t?.category||(0,a.__)("Uncategorized","zenpress")).toLowerCase(),r=(t?.subcategory||(0,a.__)("uncategorized","zenpress")).toLowerCase();k[n]||(k[n]={}),k[n][r]||(k[n][r]=[]),k[n][r].push({name:s,data:t})});const C=Object.keys(k).sort((e,s)=>{const t=S.indexOf(e.toLowerCase()),n=S.indexOf(s.toLowerCase());return-1!==t&&-1!==n?t-n:-1!==t?-1:-1!==n?1:e.localeCompare(s,void 0,{sensitivity:"base"})});(0,n.useEffect)(()=>{!f&&C.length>0&&m(C[0])},[f,C]);const E=async(e,s,t,n)=>{v(e);try{const e=await l()({path:s,method:"POST"});x(e?.message||t)}catch{y(n)}finally{v(null)}},A=()=>E("autoptimize","/zenpress/v1/autoconfig/autoptimize",(0,a.__)("Autoptimize has been configured.","zenpress"),(0,a.__)("Autoptimize autoconfig failed. Is Autoptimize installed and active?","zenpress")),N=()=>E("cache_enabler","/zenpress/v1/autoconfig/cache-enabler",(0,a.__)("Cache Enabler has been configured.","zenpress"),(0,a.__)("Cache Enabler autoconfig failed. Is Cache Enabler installed and active?","zenpress")),O=()=>E("sqlite_object_cache","/zenpress/v1/autoconfig/sqlite-object-cache",(0,a.__)("SQLite Object Cache has been configured.","zenpress"),(0,a.__)("SQLite Object Cache autoconfig failed. Is SQLite Object Cache installed and active?","zenpress"));return(0,n.useEffect)(()=>{const e=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),z||h())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[h,z]),(0,p.jsxs)("article",{className:"zenpress-row",children:[(0,p.jsxs)("section",{className:"zenpress-main",children:[(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(b,{})}),(0,p.jsxs)("div",{className:"zenpress-panel",children:[(0,p.jsxs)(_,{orientation:"vertical",selectedTabId:f,onSelect:e=>{m(e),m(e)},children:[(0,p.jsx)(_.TabList,{children:C.map(e=>{const s=`zenpress-tabs__tab--category-${e.toLowerCase().replace(/\s+/g,"-")}`;return(0,p.jsx)(_.Tab,{tabId:e,title:w(e),className:s,children:w(e)},e)})}),C.map(e=>{const n=Object.keys(k[e]).sort();return(0,p.jsxs)(_.TabPanel,{tabId:e,children:[(0,p.jsx)("h2",{children:w(e)}),n.map(t=>(0,p.jsxs)("div",{className:`zenpress-subcategory zenpress-subcategory-${t.toLowerCase().replace(/\s+/g,"-")}`,children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:w(t)}),k[e][t].map(({name:e,data:t})=>(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""},e))]},t)),"tools"===e&&Object.values(window?.zenpressIntegrationsActive||{}).some(Boolean)&&(0,p.jsxs)("div",{className:"zenpress-subcategory zenpress-subcategory-integrations",children:[(0,p.jsx)("hr",{}),(0,p.jsx)("h3",{children:(0,a.__)("Integrations","zenpress")}),(0,p.jsx)(d,{label:(0,a.__)("Show ZenPress admin bar button","zenpress"),value:t,onChange:()=>o(!t),help:(0,a.__)('Show a "ZenPress" item in the admin bar with "Clear caches". When enabled, integration buttons (e.g. Autoptimize) are hidden.',"zenpress")}),window?.zenpressIntegrationsActive?.autoptimize&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:A,disabled:null!==g,__next40pxDefaultSize:!0,children:"autoptimize"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig Autoptimize","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended Autoptimize settings (optimize JS/CSS, aggregate CSS, static files, 404 fallbacks; disable defer, HTML optimize, optimize for logged-in, per post/page). Only works if Autoptimize is active.","zenpress")})]}),window?.zenpressIntegrationsActive?.cache_enabler&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:N,disabled:null!==g,__next40pxDefaultSize:!0,children:"cache_enabler"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig Cache Enabler","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended Cache Enabler settings. Only works if Cache Enabler is active.","zenpress")})]}),window?.zenpressIntegrationsActive?.sqlite_object_cache&&(0,p.jsxs)("div",{className:"zenpress-autoconfig-actions",children:[(0,p.jsx)(r.Button,{variant:"secondary",onClick:O,disabled:null!==g,__next40pxDefaultSize:!0,children:"sqlite_object_cache"===g?(0,a.__)("Applying…","zenpress"):(0,a.__)("One-click autoconfig SQLite Object Cache","zenpress")}),(0,p.jsx)("p",{className:"zenpress-autoconfig-help",children:(0,a.__)("Apply recommended SQLite Object Cache settings. Only works if SQLite Object Cache is active.","zenpress")})]})]})]},e)})]}),(0,p.jsxs)("div",{className:"zenpress-actions",children:[(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(r.Button,{variant:"tertiary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s})},__next40pxDefaultSize:!0,children:(0,a.__)("Enable all actions","zenpress")}),(0,p.jsx)(r.Button,{isDestructive:!0,onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,a.__)("Disable all actions","zenpress")})]}),(0,p.jsx)(u,{onClick:h,isBusy:z})]})]})]}),(0,p.jsx)("aside",{className:"zenpress-sidebar",children:(0,p.jsx)("div",{className:"zenpress-presets",children:(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("h2",{children:(0,a.__)("Pick configuration preset","zenpress")}),(0,p.jsx)("p",{children:(0,a.__)("Don't know which features to enable? Quickly configure ZenPress by selecting a preset that matches your site type. Each preset enables optimized features for your specific use case.","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🖼️ ",(0,a.__)("Corporate website","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Optimized for business sites and portfolios. Focuses on security, performance, and removing unnecessary features like RSS feeds and author archives.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("corporate-website"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:[" 📰 ",(0,a.__)("Blog","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Tailored for content-focused blogs. Includes performance and security optimizations while preserving essential blog features like RSS feeds.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("blog"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")}),(0,p.jsx)("hr",{}),(0,p.jsxs)("h3",{children:["🛒 ",(0,a.__)("E-commerce","zenpress")]}),(0,p.jsx)("p",{children:(0,a.__)("Designed for WooCommerce stores. Includes all performance and security features plus WooCommerce-specific optimizations for faster checkout.","zenpress")}),(0,p.jsx)(r.Button,{variant:"secondary",onClick:()=>j("ecommerce"),__next40pxDefaultSize:!0,children:(0,a.__)("Enable","zenpress")})]})})})]})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(z,{}))})})(); -
zenpress/trunk/assets/src/js/hooks/useSettings.js
r3448585 r3451904 9 9 * 10 10 * @return {Object} Settings state and actions. 11 * @property {Object} snippets - Current snippets with metadata. 12 * @property {Function} setSnippets - Setter to update snippets state. 13 * @property {Function} saveSettings - Function to persist settings to REST API. 14 * @property {boolean} isSaving - Whether settings are currently being saved. 11 * @property {Object} snippets - Current snippets with metadata. 12 * @property {Function} setSnippets - Setter to update snippets state. 13 * @property {boolean} adminBarEnabled - Whether the ZenPress admin bar is enabled. 14 * @property {Function} setAdminBarEnabled - Setter for admin bar enabled. 15 * @property {Function} saveSettings - Function to persist settings to REST API. 16 * @property {boolean} isSaving - Whether settings are currently being saved. 15 17 */ 16 18 export const useSettings = () => { 17 19 const [snippets, setSnippets] = useState({}); 20 const [adminBarEnabled, setAdminBarEnabled] = useState(true); 18 21 const [isSaving, setIsSaving] = useState(false); 19 22 const { createSuccessNotice, createErrorNotice } = … … 38 41 39 42 setSnippets(snippetsData); 43 setAdminBarEnabled( 44 settings?.zenpress_admin_bar_enabled !== false 45 ); 40 46 }) 41 47 .catch(() => { … … 55 61 path: '/wp/v2/settings', 56 62 method: 'POST', 57 data: { zenpress_active_snippets: active }, 63 data: { 64 zenpress_active_snippets: active, 65 zenpress_admin_bar_enabled: adminBarEnabled, 66 }, 58 67 }); 59 68 createSuccessNotice(__('Settings saved.', 'zenpress')); … … 65 74 }; 66 75 67 return { snippets, setSnippets, saveSettings, isSaving }; 76 return { 77 snippets, 78 setSnippets, 79 adminBarEnabled, 80 setAdminBarEnabled, 81 saveSettings, 82 isSaving, 83 }; 68 84 }; -
zenpress/trunk/assets/src/js/pages/SettingsPage.js
r3448585 r3451904 2 2 import { __ } from '@wordpress/i18n'; 3 3 import { Button } from '@wordpress/components'; 4 import { useDispatch } from '@wordpress/data'; 5 import { store as noticesStore } from '@wordpress/notices'; 6 import apiFetch from '@wordpress/api-fetch'; 4 7 import { useSettings } from '../hooks/useSettings'; 5 8 import { SnippetToggleControl } from '../components/SnippetToggleControl'; … … 14 17 */ 15 18 export const SettingsPage = () => { 16 const { snippets, setSnippets, saveSettings, isSaving } = useSettings(); 19 const { 20 snippets, 21 setSnippets, 22 adminBarEnabled, 23 setAdminBarEnabled, 24 saveSettings, 25 isSaving, 26 } = useSettings(); 17 27 const [selectedTabId, setSelectedTabId] = useState(); 28 const [autoconfigBusy, setAutoconfigBusy] = useState(null); 29 const { createSuccessNotice, createErrorNotice } = 30 useDispatch(noticesStore); 18 31 19 32 const handleToggleChange = (snippetName) => { … … 133 146 setSelectedTabId(tabName); 134 147 }; 148 149 const runAutoconfig = async ( 150 integrationKey, 151 path, 152 successMessage, 153 errorMessage 154 ) => { 155 setAutoconfigBusy(integrationKey); 156 try { 157 const response = await apiFetch({ 158 path, 159 method: 'POST', 160 }); 161 createSuccessNotice(response?.message || successMessage); 162 } catch { 163 createErrorNotice(errorMessage); 164 } finally { 165 setAutoconfigBusy(null); 166 } 167 }; 168 169 const handleAutoconfigAutoptimize = () => 170 runAutoconfig( 171 'autoptimize', 172 '/zenpress/v1/autoconfig/autoptimize', 173 __('Autoptimize has been configured.', 'zenpress'), 174 __( 175 'Autoptimize autoconfig failed. Is Autoptimize installed and active?', 176 'zenpress' 177 ) 178 ); 179 180 const handleAutoconfigCacheEnabler = () => 181 runAutoconfig( 182 'cache_enabler', 183 '/zenpress/v1/autoconfig/cache-enabler', 184 __('Cache Enabler has been configured.', 'zenpress'), 185 __( 186 'Cache Enabler autoconfig failed. Is Cache Enabler installed and active?', 187 'zenpress' 188 ) 189 ); 190 191 const handleAutoconfigSqliteObjectCache = () => 192 runAutoconfig( 193 'sqlite_object_cache', 194 '/zenpress/v1/autoconfig/sqlite-object-cache', 195 __('SQLite Object Cache has been configured.', 'zenpress'), 196 __( 197 'SQLite Object Cache autoconfig failed. Is SQLite Object Cache installed and active?', 198 'zenpress' 199 ) 200 ); 135 201 136 202 // Add keyboard shortcuts and ensure toggles are keyboard accessible … … 221 287 </div> 222 288 ))} 289 {category === 'tools' && 290 Object.values( 291 window?.zenpressIntegrationsActive || 292 {} 293 ).some(Boolean) && ( 294 <div className="zenpress-subcategory zenpress-subcategory-integrations"> 295 <hr /> 296 <h3> 297 {__( 298 'Integrations', 299 'zenpress' 300 )} 301 </h3> 302 <SnippetToggleControl 303 label={__( 304 'Show ZenPress admin bar button', 305 'zenpress' 306 )} 307 value={adminBarEnabled} 308 onChange={() => 309 setAdminBarEnabled( 310 !adminBarEnabled 311 ) 312 } 313 help={__( 314 'Show a "ZenPress" item in the admin bar with "Clear caches". When enabled, integration buttons (e.g. Autoptimize) are hidden.', 315 'zenpress' 316 )} 317 /> 318 {window 319 ?.zenpressIntegrationsActive 320 ?.autoptimize && ( 321 <div className="zenpress-autoconfig-actions"> 322 <Button 323 variant="secondary" 324 onClick={ 325 handleAutoconfigAutoptimize 326 } 327 disabled={ 328 autoconfigBusy !== 329 null 330 } 331 __next40pxDefaultSize 332 > 333 {autoconfigBusy === 334 'autoptimize' 335 ? __( 336 'Applying…', 337 'zenpress' 338 ) 339 : __( 340 'One-click autoconfig Autoptimize', 341 'zenpress' 342 )} 343 </Button> 344 <p className="zenpress-autoconfig-help"> 345 {__( 346 'Apply recommended Autoptimize settings (optimize JS/CSS, aggregate CSS, static files, 404 fallbacks; disable defer, HTML optimize, optimize for logged-in, per post/page). Only works if Autoptimize is active.', 347 'zenpress' 348 )} 349 </p> 350 </div> 351 )} 352 {window 353 ?.zenpressIntegrationsActive 354 ?.cache_enabler && ( 355 <div className="zenpress-autoconfig-actions"> 356 <Button 357 variant="secondary" 358 onClick={ 359 handleAutoconfigCacheEnabler 360 } 361 disabled={ 362 autoconfigBusy !== 363 null 364 } 365 __next40pxDefaultSize 366 > 367 {autoconfigBusy === 368 'cache_enabler' 369 ? __( 370 'Applying…', 371 'zenpress' 372 ) 373 : __( 374 'One-click autoconfig Cache Enabler', 375 'zenpress' 376 )} 377 </Button> 378 <p className="zenpress-autoconfig-help"> 379 {__( 380 'Apply recommended Cache Enabler settings. Only works if Cache Enabler is active.', 381 'zenpress' 382 )} 383 </p> 384 </div> 385 )} 386 {window 387 ?.zenpressIntegrationsActive 388 ?.sqlite_object_cache && ( 389 <div className="zenpress-autoconfig-actions"> 390 <Button 391 variant="secondary" 392 onClick={ 393 handleAutoconfigSqliteObjectCache 394 } 395 disabled={ 396 autoconfigBusy !== 397 null 398 } 399 __next40pxDefaultSize 400 > 401 {autoconfigBusy === 402 'sqlite_object_cache' 403 ? __( 404 'Applying…', 405 'zenpress' 406 ) 407 : __( 408 'One-click autoconfig SQLite Object Cache', 409 'zenpress' 410 )} 411 </Button> 412 <p className="zenpress-autoconfig-help"> 413 {__( 414 'Apply recommended SQLite Object Cache settings. Only works if SQLite Object Cache is active.', 415 'zenpress' 416 )} 417 </p> 418 </div> 419 )} 420 </div> 421 )} 223 422 </Tabs.TabPanel> 224 423 ); -
zenpress/trunk/assets/src/scss/pages/_settings.scss
r3412245 r3451904 197 197 } 198 198 } 199 200 &-integrations { 201 h3::before { 202 content: '🔌'; 203 } 204 } 205 } 206 207 &-autoconfig-actions { 208 margin-top: 1em; 209 } 210 211 &-autoconfig-help { 212 margin-top: 0.5em; 213 margin-bottom: 0; 214 font-size: 0.9em; 215 opacity: 0.9; 199 216 } 200 217 } -
zenpress/trunk/inc/admin/enqueue.php
r3448585 r3451904 6 6 7 7 /** 8 * Enqueue scripts and styles used by the plugin in admin area. 9 * 10 * @param string $admin_page Current admin page hook. 11 * @return void 8 * Enqueues script and style on ZenPress settings page only. 12 9 */ 13 10 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); … … 49 46 50 47 /** 51 * Localize translated snippet metadata for use in JavaScript. 52 * 53 * @param string $admin_page Current admin page hook. 54 * @return void 48 * Localizes zenpressSnippetsMeta and zenpressIntegrationsActive on ZenPress settings page. 55 49 */ 56 50 add_action('admin_enqueue_scripts', 'zenpress_localize_snippets_meta'); … … 73 67 74 68 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets); 69 wp_localize_script('zenpress-scripts', 'zenpressIntegrationsActive', ZenPress_Integrations::get_active_integrations_for_ui()); 75 70 } -
zenpress/trunk/inc/admin/links.php
r3372200 r3451904 6 6 7 7 /** 8 * Add a settings link on the plugins list page. 9 * 10 * @param array $links Existing plugin action links. 11 * @return array Modified plugin action links. 8 * Adds "Settings" to plugin action links on Plugins screen. 12 9 */ 13 10 add_filter('plugin_action_links_' . plugin_basename(ZENPRESS_PLUGIN_FILE), 'zenpress_add_settings_link'); … … 25 22 26 23 /** 27 * Add extra links under the plugin description on the plugins page. 28 * 29 * @param array $links Existing row meta links. 30 * @param string $file Current plugin file. 31 * @return array Modified row meta links. 24 * Adds Changelog, Docs, Support to plugin row meta for ZenPress. 32 25 */ 33 26 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2); -
zenpress/trunk/inc/admin/menu.php
r3412245 r3451904 6 6 7 7 /** 8 * Register ZenPress options page under the Settings menu. 9 * 10 * @return void 8 * Adds ZenPress under Settings. 11 9 */ 12 10 add_action('admin_menu', 'zenpress_add_option_page'); … … 22 20 23 21 /** 24 * Render ZenPress options page content. 25 * 26 * @return void 22 * Outputs ZenPress settings page (shell; React app mounts in #zenpress-settings). 27 23 */ 28 24 function zenpress_options_page(): void { -
zenpress/trunk/inc/core/constants.php
r3448604 r3451904 1 1 <?php 2 2 /** 3 * ZenPress constants 3 * Plugin path constants. 4 * 4 5 * @package zenpress 5 6 */ -
zenpress/trunk/inc/core/metadata.php
r3448585 r3451904 6 6 7 7 /** 8 * Extract snippet metadata from its meta file.8 * Loads and sanitizes snippet metadata from inc/snippets/meta/{$snippet_name}.meta.php. 9 9 * 10 * @param string $snippet_name Snippet base name ( withoutextension).11 * @return array<string, mixed> Sanitized metadata (title, description, category, weight, preset).10 * @param string $snippet_name Snippet base name (no extension). 11 * @return array<string, mixed> title, description, category, subcategory, weight, preset. 12 12 */ 13 13 function zenpress_extract_snippet_metadata(string $snippet_name): array { … … 22 22 23 23 $file = ZENPRESS_PLUGIN_DIR . 'inc/snippets/meta/' . sanitize_file_name($snippet_name) . '.meta.php'; 24 $data = is_file($file) ? include $file : []; 24 $data = []; 25 if (is_file($file)) { 26 try { 27 $data = include $file; 28 } catch (\Throwable $e) { 29 $data = []; 30 } 31 } 25 32 $metadata = array_merge($defaults, is_array($data) ? $data : []); 26 33 -
zenpress/trunk/inc/core/sanitize.php
r3448585 r3451904 6 6 7 7 /** 8 * Sanitize the list of active snippets.8 * Sanitizes zenpress_active_snippets option to an array of file-safe base names. 9 9 * 10 * @param mixed $value Option value.11 * @return array<string> Sanitized base names.10 * @param mixed $value Raw option value. 11 * @return array<string> 12 12 */ 13 13 function zenpress_sanitize_snippets_option(mixed $value): array { -
zenpress/trunk/inc/settings/loader.php
r3448585 r3451904 6 6 7 7 /** 8 * Load all activesnippets.8 * Includes active snippet files from the given folder. Skips path traversal and disabled-by-constant snippets. 9 9 * 10 * @param string $folder Relative folder path for snippets.10 * @param string $folder Relative path under plugin dir (default: inc/snippets/functions/). 11 11 * @return array<string> Loaded snippet base names. 12 12 */ … … 30 30 $constant = 'ZENPRESS_' . strtoupper(str_replace(['-', '_'], '_', $name)); 31 31 if (is_file($file) && (!defined($constant) || constant($constant) !== false)) { 32 include_once $file; 33 $loaded[] = $name; 32 try { 33 include_once $file; 34 $loaded[] = $name; 35 } catch (\Throwable $e) { 36 continue; 37 } 34 38 } 35 39 } -
zenpress/trunk/inc/settings/options.php
r3448585 r3451904 6 6 7 7 /** 8 * Register option to store active snippets.8 * Registers zenpress_active_snippets and zenpress_admin_bar_enabled (REST + sanitize). 9 9 */ 10 10 add_action('init', 'zenpress_register_snippet_settings'); … … 25 25 ] 26 26 ); 27 28 register_setting( 29 'options', 30 'zenpress_admin_bar_enabled', 31 [ 32 'type' => 'boolean', 33 'default' => true, 34 'sanitize_callback' => 'zenpress_sanitize_admin_bar_enabled', 35 'show_in_rest' => [ 36 'schema' => ['type' => 'boolean'], 37 ], 38 ] 39 ); 27 40 } 41 42 /** 43 * Sanitizes zenpress_admin_bar_enabled to bool. 44 */ 45 function zenpress_sanitize_admin_bar_enabled(mixed $value): bool { 46 return (bool) $value; 47 } -
zenpress/trunk/inc/snippets/functions/protect-wp-login.php
r3448585 r3451904 10 10 }); 11 11 12 // Limit login attempts 12 // Limit login attempts (only when a valid IP is available to avoid site-wide lockout) 13 13 add_filter('authenticate', static function (mixed $user, string $username, string $password): mixed { 14 $MAX_LOGIN_ATTEMPTS = 5;15 $BLOCK_DURATION = 300; // 5 minutes16 17 14 $ipAddress = filter_var( 18 15 wp_unslash($_SERVER['REMOTE_ADDR'] ?? ''), 19 16 FILTER_VALIDATE_IP 20 ) ?: 'unknown'; 17 ); 18 if ($ipAddress === false) { 19 return $user; 20 } 21 21 22 $MAX_LOGIN_ATTEMPTS = 5; 23 $BLOCK_DURATION = 300; // 5 minutes 22 24 $blockKey = 'zenpress_login_block_' . $ipAddress; 23 25 $attemptKey = 'zenpress_login_attempts_' . $ipAddress; -
zenpress/trunk/readme.txt
r3448604 r3451904 5 5 Requires at least: 6.0 6 6 Tested up to: 6.9 7 Stable tag: 2.2. 18 Requires PHP: 8. 37 Stable tag: 2.2.3 8 Requires PHP: 8.1 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html/ … … 41 41 * Native WordPress interface, benefits from Gutenberg's new features and the site editor. 42 42 43 = Core - Performance=43 = Core = 44 44 45 45 * Disable adjacent posts link tags. … … 59 59 * Disable Password Strength Meter. 60 60 * Disable WordPress default lazy loading. 61 62 = Core - Security =63 64 61 * Block user enumeration. 65 62 * Disable application passwords. … … 69 66 * Disable XML-RPC and remove RSD link. 70 67 * Hide WordPress version. 71 72 = Core - User Interface =73 74 68 * Clean up the WordPress admin bar. 75 69 * Disable the login language selector. … … 78 72 * Remove "Thanks for using WordPress" in footer. 79 73 80 = WooCommerce - Performance=74 = WooCommerce = 81 75 * Disable WooCommerce cart fragments script. 82 76 * Disable WooCommerce scripts and styles on non-WooCommerce pages. … … 84 78 * Disable WooCommerce widgets. 85 79 * Remove WooCommerce default block patterns. 86 87 = WooCommerce - Security =88 80 * Hide WooCommerce version. 89 81 90 = Gutenberg - Performance=82 = Gutenberg = 91 83 * Remove WordPress default remote block patterns. 92 84 * Separate loading of core block styles. 93 94 = Gutenberg - User Interface =95 85 * Disable default pattern categories in site editor. 96 86 97 = Ads-blocker - User Interface=87 = Ads-blocker = 98 88 * Clean up the WordPress Dashboard. 99 89 100 = Tools - Security=90 = Tools = 101 91 * Protect the wp-login form from brute force attacks. 92 * Toggle "Show ZenPress admin bar button" (clear caches from the admin bar when at least one integration is active). 93 94 = Integrations = 95 96 ZenPress integrates with Cache Enabler, Autoptimize, and SQLite Object Cache. When any of these plugins is active, the Tools tab shows integration status and one-click autoconfig actions. 97 98 * Admin bar: One "Clear all caches" button (dashicon) in the admin bar, with sub-items to clear page cache (Cache Enabler), static assets (Autoptimize), or object cache (SQLite Object Cache) separately. The ZenPress button replaces the third-party cache buttons when the ZenPress admin bar is enabled. You can hide it via Settings > ZenPress > Tools. 99 * Autoptimize: One-click autoconfig enables recommended options (JS/CSS/aggregate/nogzip/fallback on; defer/HTML/logged-in/meta off) and clears the Autoptimize cache. 100 * Cache Enabler: One-click autoconfig enables clear site cache on post or plugin changes, WebP support, Gzip compression, and minify HTML (excluding inline CSS/JS), then clears the page cache. 101 * SQLite Object Cache: One-click autoconfig enables the "Use APCu" option in the plugin settings when the APCu extension is available (no wp-config editing; the plugin may write its constant when its own settings are saved). 102 102 103 103 = Presets = … … 115 115 == Roadmap == 116 116 117 = Global =118 117 * Additional presets for specific use cases. 119 118 * Documentation pages with detailed guides. 120 121 = Security =122 119 * Manage Heartbeat API (frontend + backend + admin whitelist). 123 124 = User Interface =125 120 * Remove "site health" page. 126 121 * Remove "Privacy tools". 127 128 = WooCommerce =129 122 * Disable WooCommerce tracking. 130 123 * Disable marketing hub. … … 133 126 * Disable WooCommerce blocks. 134 127 * Disable WooCommerce promo emails. 135 136 = Plugins =137 128 * Disable CF7 CSS & JS. 138 129 * Disable Elementor bloat. … … 204 195 Nice ! If you can't find anything in the roadmap, feel free to submit your suggestion on the support page! If you know how to code, you can even contribute on GitHub. 205 196 197 == Hooks & filters == 198 199 For developers: ZenPress exposes the following action and filters for extending or bypassing behavior. 200 201 = Action = 202 * `zenpress_caches_clear` – Fired when the user clears caches from the ZenPress admin bar. Integrations (e.g. Autoptimize) hook into this to clear their own caches. You can add custom cache clear logic with `add_action('zenpress_caches_clear', 'your_callback');`. 203 204 = Filters (Disable REST API snippet) = 205 * `zenpress_disable_wp_rest_api_post_var` – Allow unauthenticated REST access when a specific POST key is present (e.g. for webhooks). Return a string or array of key names. Use non-guessable values only. 206 * `zenpress_disable_wp_rest_api_server_var` – Allow unauthenticated REST access when `REQUEST_URI` matches a specific value. Return a string or array. Use non-guessable values only. 207 206 208 == Changelog == 209 210 = 2.2.3 = 211 - Integrations: Cache Enabler one-click autoconfig (clear on post/plugin, WebP, Gzip, minify HTML excl. inline CSS/JS). 212 - Integrations: SQLite Object Cache one-click autoconfig (enable "Use APCu" option when APCu available; no wp-config editing by ZenPress). 213 - Integrations: Admin bar "Clear all caches" button now uses dashicons-trash icon. 214 - Defensive: REST and AJAX handlers wrap integration calls in try/catch; failed autoconfig or cache clear returns 500 with message instead of fatal. 215 - Defensive: get_active_integrations_for_ui() wraps ReflectionClass in try/catch so one missing integration does not break the settings UI. 216 - Defensive: Cache Enabler autoconfig ensures option value is array before merge (corrupted option no longer triggers warning). 217 - Defensive: Metadata and snippet loader wrap include in try/catch so a single bad meta file or snippet does not fatal the site. 218 - Defensive: Protect wp-login skips rate limiting when REMOTE_ADDR is missing or invalid to avoid site-wide lockout (e.g. CLI or proxy). 219 - Defensive: Autoptimize clear_cache and autoconfig check method_exists before calling third-party API. 220 - Docblocks: Reviewed and tightened docblocks across inc/ (file headers, classes, methods) for coherence, readability, and conciseness; removed redundant @param/@return where type is obvious. 221 - Lint: PHPStan and PHP CS Fixer fixes (autoptimize method_exists ignore, protect-wp-login strict comparison). 222 223 = 2.2.2 = 224 - Integrations: Admin bar and one-click autoconfig (e.g. Autoptimize) in Tools tab; visible only when at least one integration is active. 225 - Documentation: Added Hooks & filters section in readme; Integrations section in workflow.md; config comments for PHPStan and PHP CS Fixer. 226 - Version alignment: Stable tag and plugin header set to 2.2.2. 207 227 208 228 = 2.2.1 = … … 338 358 == Upgrade Notice == 339 359 360 = 2.2.3 = 361 - Integrations: Cache Enabler and SQLite Object Cache one-click autoconfig; admin bar trash icon; defensive fixes and docblock cleanup. 362 363 = 2.2.2 = 364 - Integrations: ZenPress admin bar and one-click autoconfig in Tools tab (Autoptimize). Documentation updates. 365 340 366 = 2.2.1 = 341 367 - Security and code quality improvements. Recommended update. 342 368 343 369 = 2.2.0 = 344 - Breaking: PHP 8. 3is now required (PHP 7.4 support dropped). Major code modernization with improved type safety and performance.370 - Breaking: PHP 8.1 is now required (PHP 7.4 support dropped). Major code modernization with improved type safety and performance. 345 371 - Security: HTTP 403 on login block, path traversal guard in snippet loader, and in-code docs for REST API bypass filters. 346 372 -
zenpress/trunk/zenpress.php
r3448604 r3451904 12 12 * Plugin Name: ZenPress - Optimize & Secure 13 13 * Description: Easily speed up and strengthen your WordPress site by cleaning out unnecessary features and protecting weak points. 14 * Version: 2.2. 114 * Version: 2.2.2 15 15 * Plugin URI: https://wordpress.org/plugins/zenpress/ 16 16 * Author: Quentin Le Duff … … 20 20 * Requires at least: 6.0 21 21 * Tested up to: 6.9 22 * Requires PHP: 8. 322 * Requires PHP: 8.1 23 23 * License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html/ 24 24 * License: GPL v2 or later … … 47 47 require_once __DIR__ . '/inc/core/sanitize.php'; 48 48 49 // Integrations (one file per plugin: handlers + autoconfig) 50 require_once __DIR__ . '/inc/classes/autoptimize.php'; 51 require_once __DIR__ . '/inc/classes/cache-enabler.php'; 52 require_once __DIR__ . '/inc/classes/sqlite-object-cache.php'; 53 require_once __DIR__ . '/inc/classes/integrations.php'; 54 49 55 // Admin UI 50 56 require_once __DIR__ . '/inc/admin/enqueue.php';
Note: See TracChangeset
for help on using the changeset viewer.