Plugin Directory

Changeset 3429798


Ignore:
Timestamp:
12/30/2025 08:16:21 PM (7 weeks ago)
Author:
sethta
Message:

Update to version 1.4.5

Location:
easy-critical-css
Files:
301 added
1 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • easy-critical-css/trunk/assets/admin.js

    r3402049 r3429798  
    5656    var mode = document.querySelector('input[name="easy_cc_critical_css_mode"]:checked')?.value
    5757    var container = document.getElementById('exclude-css-files-container')
    58     console.log(mode, container)
    5958    if (!container) return
     59
    6060    var row = container.closest('tr')
    6161    var labelEl = null
    62     console.log(row)
    6362    if (row) {
    6463      labelEl = row.querySelector('th')
    6564    }
    6665    var descEl = container.querySelector('.description')
    67     console.log(labelEl, descEl)
    6866    if (!labelEl || !descEl) return
    6967
     
    308306  toggleAutoModeStatus()
    309307  updateExcludeCssLabel()
     308
     309  // Subscription notification actions
     310  document.addEventListener('click', function (e) {
     311    // Handle dismiss button
     312    if (e.target.closest('.ecc-subscription-notice .notice-dismiss')) {
     313      e.preventDefault()
     314
     315      fetch(`${eccSubscriptionNotice.restUrl}dismiss-notification`, {
     316        method: 'POST',
     317        headers: {
     318          'Content-Type': 'application/json',
     319          'X-WP-Nonce': eccSubscriptionNotice.nonce
     320        }
     321      })
     322      .then(response => {
     323        if (!response.ok) {
     324          throw new Error('HTTP ' + response.status + ': ' + response.statusText)
     325        }
     326        return response.json()
     327      })
     328      .catch(error => {
     329        console.log('Notification dismiss via REST failed:', error)
     330      })
     331      return
     332    }
     333
     334    // Handle activate button
     335    if (e.target.closest('#ecc-activate-auto-generation')) {
     336      e.preventDefault()
     337      const activateBtn = e.target.closest('#ecc-activate-auto-generation')
     338      const autoRadio = document.querySelector('input[name="easy_cc_critical_css_mode"][value="auto"]')
     339
     340      if (autoRadio) {
     341        // We're on the settings page: click the radio button
     342        autoRadio.click()
     343        activateBtn.classList.add('disabled')
     344        activateBtn.textContent = 'Activated'
     345      } else {
     346        activateBtn.classList.add('disabled')
     347        activateBtn.textContent = 'Activating...'
     348
     349        fetch(`${eccSubscriptionNotice.restUrl}activate-auto`, {
     350          method: 'POST',
     351          headers: {
     352            'Content-Type': 'application/json',
     353            'X-WP-Nonce': eccSubscriptionNotice.nonce
     354          },
     355          body: JSON.stringify({})
     356        })
     357        .then(response => response.json())
     358        .then(data => {
     359          if (data && !data.code) {
     360            const notice = activateBtn.closest('.ecc-subscription-notice')
     361            if (notice) notice.innerHTML = '<p style="font-weight:600;">Success</p><p>Auto-generation has been activated.</p>'
     362          } else {
     363            throw new Error(data.message || 'Failed')
     364          }
     365        })
     366        .catch(error => {
     367          console.error('Activation via REST failed:', error)
     368          activateBtn.classList.remove('disabled')
     369          activateBtn.textContent = 'Activate Auto Generation'
     370        })
     371      }
     372    }
     373  })
    310374})
  • easy-critical-css/trunk/build/index.asset.php

    r3327873 r3429798  
    1 <?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '8b825f7979662931e8de');
     1<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '810715d88c2d38a09eb6');
  • easy-critical-css/trunk/build/index.js

    r3327873 r3429798  
    1 (()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};window.React;const t=window.wp.plugins,s=window.wp.editor,i=window.wp.data,a=window.wp.components,c=window.wp.i18n,n=window.ReactJSXRuntime,r={completed:(0,c.__)("Completed","easy-critical-css"),expired:(0,c.__)("Expired","easy-critical-css"),excluded:(0,c.__)("Excluded","easy-critical-css"),failed:(0,c.__)("Failed","easy-critical-css"),invalid:(0,c.__)("Invalid API","easy-critical-css"),paused:(0,c.__)("Paused","easy-critical-css"),unavailable:(0,c.__)("Unavailable","easy-critical-css"),unprocessed:(0,c.__)("Unprocessed","easy-critical-css"),unreachable:(0,c.__)("Unreachable","easy-critical-css"),pending:(0,c.__)("Pending","easy-critical-css"),error:(0,c.__)("Error","easy-critical-css")},o={completed:"#1e7e34",expired:"#995a00",excluded:"#6c757d",failed:"#b12331",invalid:"#b12331",paused:"#6c757d",unavailable:"#6c757d",unprocessed:"#6c757d",unreachable:"#b12331",pending:"#007cba",error:"#000"},l=({status:e,loading:t,fetchStatus:s})=>(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,n.jsx)("span",{children:(0,c.__)("Status:","easy-critical-css")}),(0,n.jsx)("span",{style:{display:"inline-block",padding:"3px 8px",borderRadius:"12px",background:o[e||"error"],color:"#fff",fontWeight:"500"},children:r[e||"error"]})]}),(0,n.jsx)(a.Button,{onClick:s,variant:"secondary","aria-label":(0,c.__)("Refresh Status","easy-critical-css"),children:t?(0,n.jsx)(a.Spinner,{}):(0,c.__)("Refresh","easy-critical-css")})]}),d=window.wp.element,p=window.wp.apiFetch;var u=e.n(p);const g=({postId:e,fetchStatus:t,status:s,activate_critical_css:i})=>{const[r,o]=(0,d.useState)(!1),[l,p]=(0,d.useState)(null),[g,h]=(0,d.useState)(null);return"paused"!==s&&i?(0,n.jsxs)("div",{style:{marginTop:"10px"},children:[g&&(0,n.jsx)("div",{style:{marginBottom:"10px"},children:(0,n.jsx)(a.Notice,{status:"error",isDismissible:!0,onRemove:()=>h(null),children:g})}),l&&(0,n.jsx)("div",{style:{marginBottom:"10px"},children:(0,n.jsx)(a.Notice,{status:"success",isDismissible:!0,onRemove:()=>p(null),children:l})}),(0,n.jsx)(a.Button,{onClick:async()=>{o(!0),h(null),p(null);try{const s=await u()({path:"/easy-critical-css/v1/generate",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:e})});if(!s||s.code)throw new Error(s.message||(0,c.__)("An error occurred.","easy-critical-css"));p((0,c.__)("Critical CSS generation started successfully.","easy-critical-css")),t()}catch(e){console.error(e),h(e&&"object"==typeof e&&"message"in e?e.message:(0,c.__)("An unknown error occurred.","easy-critical-css"))}o(!1)},variant:"primary",style:{width:"100%",justifyContent:"center"},children:r?(0,n.jsx)(a.Spinner,{}):"completed"===s||"expired"===s?(0,c.__)("Re-Generate Critical CSS","easy-critical-css"):(0,c.__)("Generate Critical CSS","easy-critical-css")})]}):null},h=({keyName:e,setting:t,settings:s,effectiveMode:i,effectiveSecondaryBehavior:c,handleSettingsChange:r})=>{var o;const l=void 0!==s[e]?s[e]:t.default,d="boolean"==typeof i?String(i):i,p="checkbox"!==t.type,u="object"==typeof t.label?t.label[d]||t.label.auto:t.label,g="object"==typeof t.desc?t.desc[d]||t.desc.auto:t.desc,h={marginRight:"10px",maxWidth:"245px",whiteSpace:"normal",wordWrap:"break-word",textAlign:"left"};return(0,n.jsxs)("div",{children:[p&&(0,n.jsxs)("label",{htmlFor:e,style:{display:"flex",alignItems:"center",fontWeight:"500",marginBottom:"5px"},children:[u,g&&(0,n.jsx)(a.Tooltip,{text:g,style:h,children:(0,n.jsx)("span",{style:{marginLeft:"5px",cursor:"help",color:"#999"},children:(0,n.jsx)(a.Icon,{icon:"editor-help"})})})]}),"checkbox"===t.type&&(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[(0,n.jsx)(a.CheckboxControl,{label:u,checked:!!l,onChange:t=>r(e,t)},e),g&&(0,n.jsx)(a.Tooltip,{text:g,style:h,children:(0,n.jsx)("span",{style:{marginBottom:"8px",marginLeft:"5px",cursor:"help",color:"#999"},children:(0,n.jsx)(a.Icon,{icon:"editor-help"})})})]}),"select"===t.type&&(0,n.jsx)("select",{id:e,value:String(l),onChange:t=>r(e,t.target.value),style:{width:"100%",padding:"5px"},children:Object.entries(null!==(o=t.options)&&void 0!==o?o:{}).map((([e,t])=>(0,n.jsx)("option",{value:e,children:t},e)))}),"textarea"===t.type&&(0,n.jsx)("textarea",{id:e,value:"string"==typeof l?l:"",onChange:t=>r(e,t.target.value),rows:5,style:{width:"100%",padding:"5px"}}),"text"===t.type&&(0,n.jsx)("input",{id:e,type:"text",value:"string"==typeof l?l:"",onChange:t=>r(e,t.target.value),style:{width:"100%",padding:"5px"}})]},e)},y=({settingsSchema:e,settings:t,effectiveMode:s,effectiveSecondaryBehavior:i,settingsVisible:r,setSettingsVisible:o,handleSettingsChange:l})=>{const d=Object.entries(e).filter((([e,a])=>((e,t,s,i,a)=>{if(!t.visible)return!0;for(const[e,c]of Object.entries(t.visible)){const t=s[e];if("critical_css_mode"===e&&("default"===t?i!==c:t!==c)||"secondary_css_behavior"===e&&("default"===t?a!==c:t!==c)||"critical_css_mode"!==e&&"secondary_css_behavior"!==e&&t!==c)return!1}return!0})(0,a,t,s,i)));return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(a.Button,{type:"button","aria-expanded":r,className:"components-button components-panel__body-toggle",style:{padding:"10px",background:"#f8f8f8",cursor:"pointer",userSelect:"none",marginTop:"15px"},onClick:()=>o(!r),children:[(0,c.__)("Settings","easy-critical-css"),(0,n.jsx)("span",{"aria-hidden":"true",children:(0,n.jsx)("svg",{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",className:"components-panel__arrow","aria-hidden":"true",focusable:"false",children:r?(0,n.jsx)("path",{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"}):(0,n.jsx)("path",{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})})})]}),r&&(0,n.jsx)("div",{style:{marginTop:"10px"},children:d.map((([e,a],c,r)=>{const o=c===r.length-1;return(0,n.jsx)("div",{style:{marginBottom:o?"0px":"15px"},children:(0,n.jsx)(h,{keyName:e,setting:a,settings:t,effectiveMode:s,effectiveSecondaryBehavior:i,handleSettingsChange:l})},e)}))})]})},{settingsSchema:f,settings:x,mode:v,secondaryBehavior:_}=eccSettings;(0,t.registerPlugin)("critical-css-sidebar",{render:()=>{const e=(0,i.useSelect)((e=>e("core/editor").getCurrentPostId()),[]),{settings:t,updateSetting:a}=((e,t,s)=>{const[a,c]=(0,d.useState)((()=>({...Object.fromEntries(Object.entries(e).map((([e,t])=>[e,t.default]))),...t}))),{editPost:n}=(0,i.useDispatch)("core/editor");return(0,d.useEffect)((()=>{s&&(async()=>{try{const e=await u()({path:`/easy-critical-css/v1/get-settings/${s}`});c((t=>({...t,...e})))}catch(e){console.error("Error fetching Easy Critical CSS settings:",e)}})()}),[s]),{settings:a,updateSetting:(e,t)=>{c((s=>({...s,[e]:t}))),u()({path:`/easy-critical-css/v1/update-settings/${s}`,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({[e]:t})}).catch((t=>console.error(`Error updating ${e}:`,t))),n({meta:{[e]:t}})}}})(f,x,e),{status:c,loading:r,fetchStatus:o}=((e,t)=>{const[s,i]=(0,d.useState)(null),[a,c]=(0,d.useState)(!1),n=async()=>{if(e){c(!0),console.log("Fetching Critical CSS for Post ID:",e);try{const s=await u()({path:`/easy-critical-css/v1/status/${e}`});i(t?s.status:"paused")}catch(e){const t=e;"invalid_post_id"===t?.code?i("unavailable"):(console.error("Error fetching Critical CSS status:",e),i("error"))}c(!1)}};return(0,d.useEffect)((()=>{n()}),[e,t]),{status:s,loading:a,fetchStatus:n}})(e,t.activate_critical_css);((e,t)=>{const s=(0,i.useSelect)((e=>({isSaving:e("core/editor").isSavingPost()})),[]);(0,d.useEffect)((()=>{s&&(console.log("Saving settings on post save:",t),u()({path:`/easy-critical-css/v1/update-settings/${e}`,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).then((()=>console.log("Easy Critical CSS Settings saved with post update"))).catch((e=>console.error("Error saving settings with post update:",e))))}),[s])})(e,t);const{effectiveMode:p,effectiveSecondaryBehavior:h}=((e,t,s)=>({effectiveMode:e.critical_css_mode&&"default"!==e.critical_css_mode?e.critical_css_mode:t,effectiveSecondaryBehavior:e.secondary_css_behavior&&"default"!==e.secondary_css_behavior?e.secondary_css_behavior:s}))(t,v,_),{settingsVisible:S,setSettingsVisible:m}=(e=>{const[t,s]=(0,d.useState)(!1);return(0,d.useEffect)((()=>{s("manual"===e)}),[]),{settingsVisible:t,setSettingsVisible:s}})(p);return(0,n.jsxs)(s.PluginDocumentSettingPanel,{name:"easy-critical-css-sidebar",title:"Easy Critical CSS",className:"easy-critical-css-panel",children:["manual"!==p&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(l,{status:c,loading:r,fetchStatus:o}),(0,n.jsx)(g,{postId:e,fetchStatus:o,status:c,activate_critical_css:t.activate_critical_css})]}),(0,n.jsx)(y,{settingsSchema:f,settings:t,effectiveMode:p,effectiveSecondaryBehavior:h,settingsVisible:S,setSettingsVisible:m,handleSettingsChange:a})]})}})})();
     1(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};window.React;const t=window.wp.plugins,s=window.wp.editor,i=window.wp.data,a=window.wp.components,c=window.wp.i18n,n=window.ReactJSXRuntime,r={completed:(0,c.__)("Completed","easy-critical-css"),expired:(0,c.__)("Expired","easy-critical-css"),excluded:(0,c.__)("Excluded","easy-critical-css"),failed:(0,c.__)("Failed","easy-critical-css"),invalid:(0,c.__)("Invalid API","easy-critical-css"),paused:(0,c.__)("Paused","easy-critical-css"),unavailable:(0,c.__)("Unavailable","easy-critical-css"),unprocessed:(0,c.__)("Unprocessed","easy-critical-css"),unreachable:(0,c.__)("Unreachable","easy-critical-css"),pending:(0,c.__)("Pending","easy-critical-css"),error:(0,c.__)("Error","easy-critical-css")},o={completed:"#1e7e34",expired:"#995a00",excluded:"#6c757d",failed:"#b12331",invalid:"#b12331",paused:"#6c757d",unavailable:"#6c757d",unprocessed:"#6c757d",unreachable:"#b12331",pending:"#007cba",error:"#000"},l=({status:e,loading:t,fetchStatus:s})=>(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,n.jsx)("span",{children:(0,c.__)("Status:","easy-critical-css")}),(0,n.jsx)("span",{style:{display:"inline-block",padding:"3px 8px",borderRadius:"12px",background:o[e||"error"],color:"#fff",fontWeight:"500"},children:r[e||"error"]})]}),(0,n.jsx)(a.Button,{onClick:s,variant:"secondary","aria-label":(0,c.__)("Refresh Status","easy-critical-css"),children:t?(0,n.jsx)(a.Spinner,{}):(0,c.__)("Refresh","easy-critical-css")})]}),d=window.wp.element,p=window.wp.apiFetch;var h=e.n(p);const u=({postId:e,fetchStatus:t,status:s,activate_critical_css:i})=>{const[r,o]=(0,d.useState)(!1),[l,p]=(0,d.useState)(null),[u,g]=(0,d.useState)(null);return"paused"!==s&&i?(0,n.jsxs)("div",{style:{marginTop:"10px"},children:[u&&(0,n.jsx)("div",{style:{marginBottom:"10px"},children:(0,n.jsx)(a.Notice,{status:"error",isDismissible:!0,onRemove:()=>g(null),children:u})}),l&&(0,n.jsx)("div",{style:{marginBottom:"10px"},children:(0,n.jsx)(a.Notice,{status:"success",isDismissible:!0,onRemove:()=>p(null),children:l})}),(0,n.jsx)(a.Button,{onClick:async()=>{o(!0),g(null),p(null);try{const s=await h()({path:"/easy-critical-css/v1/generate",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:e})});if(!s||s.code)throw new Error(s.message||(0,c.__)("An error occurred.","easy-critical-css"));p((0,c.__)("Critical CSS generation started successfully.","easy-critical-css")),t()}catch(e){console.error(e),g(e&&"object"==typeof e&&"message"in e?e.message:(0,c.__)("An unknown error occurred.","easy-critical-css"))}o(!1)},variant:"primary",style:{width:"100%",justifyContent:"center"},children:r?(0,n.jsx)(a.Spinner,{}):"completed"===s||"expired"===s?(0,c.__)("Re-Generate Critical CSS","easy-critical-css"):(0,c.__)("Generate Critical CSS","easy-critical-css")})]}):null},g=({keyName:e,setting:t,settings:s,effectiveMode:i,effectiveSecondaryBehavior:r,handleSettingsChange:o})=>{var l;const d=void 0!==s[e]?s[e]:t.default,p="boolean"==typeof i?String(i):i,h="checkbox"!==t.type,u="object"==typeof t.label?t.label[p]||t.label.auto:t.label,g="object"==typeof t.desc?t.desc[p]||t.desc.auto:t.desc,y={marginRight:"10px",maxWidth:"245px",whiteSpace:"normal",wordWrap:"break-word",textAlign:"left"};return(0,n.jsxs)("div",{children:[h&&(0,n.jsxs)("label",{htmlFor:e,style:{display:"flex",alignItems:"center",fontWeight:"500",marginBottom:"5px"},children:[u,g&&(0,n.jsx)(a.Tooltip,{text:g,style:y,children:(0,n.jsx)("span",{style:{marginLeft:"5px",cursor:"help",color:"#999"},children:(0,n.jsx)(a.Icon,{icon:"editor-help"})})})]}),"checkbox"===t.type&&(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[(0,n.jsx)(a.CheckboxControl,{label:u,checked:!!d,onChange:t=>o(e,t)},e),g&&(0,n.jsx)(a.Tooltip,{text:g,style:y,children:(0,n.jsx)("span",{style:{marginBottom:"8px",marginLeft:"5px",cursor:"help",color:"#999"},children:(0,n.jsx)(a.Icon,{icon:"editor-help"})})})]}),"select"===t.type&&(0,n.jsx)("select",{id:e,value:String(d),onChange:t=>o(e,t.target.value),style:{width:"100%",padding:"5px"},children:Object.entries(null!==(l=t.options)&&void 0!==l?l:{}).map((([e,t])=>(0,n.jsx)("option",{value:e,children:t},e)))}),"textarea"===t.type&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("textarea",{id:e,value:"string"==typeof d?d:"",onChange:t=>o(e,t.target.value),rows:5,style:{width:"100%",padding:"5px"}}),("critical_css"===e||"manual_secondary_css"===e)&&"string"==typeof d&&(()=>{const e=d.replace(/^\s+/,"").slice(0,10);return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("/")&&!e.startsWith("/*")?(0,n.jsxs)("div",{style:{marginTop:"8px",padding:"8px",background:"#fff3cd",border:"1px solid #ffeeba",borderRadius:"4px"},children:[(0,n.jsx)("div",{style:{fontWeight:600,marginBottom:"6px"},children:(0,c.__)("It looks like you pasted a URL.","easy-critical-css")}),(0,n.jsx)("div",{style:{marginBottom:"6px"},children:(0,c.__)("Open that URL, copy the stylesheet contents, and paste the CSS here. Do not paste the URL itself. Pasting a URL can break your site when used as CSS.","easy-critical-css")}),(0,n.jsx)("div",{style:{marginBottom:"6px"},children:(0,n.jsx)("a",{href:"https://criticalcss.net/docs/",target:"_blank",rel:"noopener noreferrer",children:(0,c.__)("View help docs","easy-critical-css")})})]}):null})()]}),"text"===t.type&&(0,n.jsx)("input",{id:e,type:"text",value:"string"==typeof d?d:"",onChange:t=>o(e,t.target.value),style:{width:"100%",padding:"5px"}})]},e)},y=({settingsSchema:e,settings:t,effectiveMode:s,effectiveSecondaryBehavior:i,settingsVisible:r,setSettingsVisible:o,handleSettingsChange:l})=>{const d=Object.entries(e).filter((([e,a])=>((e,t,s,i,a)=>{if(!t.visible)return!0;for(const[e,c]of Object.entries(t.visible)){const t=s[e];if("critical_css_mode"===e&&("default"===t?i!==c:t!==c)||"secondary_css_behavior"===e&&("default"===t?a!==c:t!==c)||"critical_css_mode"!==e&&"secondary_css_behavior"!==e&&t!==c)return!1}return!0})(0,a,t,s,i)));return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(a.Button,{type:"button","aria-expanded":r,className:"components-button components-panel__body-toggle",style:{padding:"10px",background:"#f8f8f8",cursor:"pointer",userSelect:"none",marginTop:"15px"},onClick:()=>o(!r),children:[(0,c.__)("Settings","easy-critical-css"),(0,n.jsx)("span",{"aria-hidden":"true",children:(0,n.jsx)("svg",{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",className:"components-panel__arrow","aria-hidden":"true",focusable:"false",children:r?(0,n.jsx)("path",{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"}):(0,n.jsx)("path",{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})})})]}),r&&(0,n.jsx)("div",{style:{marginTop:"10px"},children:d.map((([e,a],c,r)=>{const o=c===r.length-1;return(0,n.jsx)("div",{style:{marginBottom:o?"0px":"15px"},children:(0,n.jsx)(g,{keyName:e,setting:a,settings:t,effectiveMode:s,effectiveSecondaryBehavior:i,handleSettingsChange:l})},e)}))})]})},{settingsSchema:f,settings:x,mode:_,secondaryBehavior:v}=eccSettings;(0,t.registerPlugin)("critical-css-sidebar",{render:()=>{const e=(0,i.useSelect)((e=>e("core/editor").getCurrentPostId()),[]),{settings:t,updateSetting:a}=((e,t,s)=>{const[a,c]=(0,d.useState)((()=>({...Object.fromEntries(Object.entries(e).map((([e,t])=>[e,t.default]))),...t}))),{editPost:n}=(0,i.useDispatch)("core/editor");return(0,d.useEffect)((()=>{s&&(async()=>{try{const e=await h()({path:`/easy-critical-css/v1/get-settings/${s}`});c((t=>({...t,...e})))}catch(e){console.error("Error fetching Easy Critical CSS settings:",e)}})()}),[s]),{settings:a,updateSetting:(e,t)=>{c((s=>({...s,[e]:t}))),h()({path:`/easy-critical-css/v1/update-settings/${s}`,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({[e]:t})}).catch((t=>console.error(`Error updating ${e}:`,t))),n({meta:{[e]:t}})}}})(f,x,e),{status:c,loading:r,fetchStatus:o}=((e,t)=>{const[s,i]=(0,d.useState)(null),[a,c]=(0,d.useState)(!1),n=async()=>{if(e){c(!0),console.log("Fetching Critical CSS for Post ID:",e);try{const s=await h()({path:`/easy-critical-css/v1/status/${e}`});i(t?s.status:"paused")}catch(e){const t=e;"invalid_post_id"===t?.code?i("unavailable"):(console.error("Error fetching Critical CSS status:",e),i("error"))}c(!1)}};return(0,d.useEffect)((()=>{n()}),[e,t]),{status:s,loading:a,fetchStatus:n}})(e,t.activate_critical_css);((e,t)=>{const s=(0,i.useSelect)((e=>({isSaving:e("core/editor").isSavingPost()})),[]);(0,d.useEffect)((()=>{s&&(console.log("Saving settings on post save:",t),h()({path:`/easy-critical-css/v1/update-settings/${e}`,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).then((()=>console.log("Easy Critical CSS Settings saved with post update"))).catch((e=>console.error("Error saving settings with post update:",e))))}),[s])})(e,t);const{effectiveMode:p,effectiveSecondaryBehavior:g}=((e,t,s)=>({effectiveMode:e.critical_css_mode&&"default"!==e.critical_css_mode?e.critical_css_mode:t,effectiveSecondaryBehavior:e.secondary_css_behavior&&"default"!==e.secondary_css_behavior?e.secondary_css_behavior:s}))(t,_,v),{settingsVisible:m,setSettingsVisible:S}=(e=>{const[t,s]=(0,d.useState)(!1);return(0,d.useEffect)((()=>{s("manual"===e)}),[]),{settingsVisible:t,setSettingsVisible:s}})(p);return(0,n.jsxs)(s.PluginDocumentSettingPanel,{name:"easy-critical-css-sidebar",title:"Easy Critical CSS",className:"easy-critical-css-panel",children:["manual"!==p&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(l,{status:c,loading:r,fetchStatus:o}),(0,n.jsx)(u,{postId:e,fetchStatus:o,status:c,activate_critical_css:t.activate_critical_css})]}),(0,n.jsx)(y,{settingsSchema:f,settings:t,effectiveMode:p,effectiveSecondaryBehavior:g,settingsVisible:m,setSettingsVisible:S,handleSettingsChange:a})]})}})})();
  • easy-critical-css/trunk/easy-critical-css.php

    r3402049 r3429798  
    33 * Plugin Name:       Easy Critical CSS
    44 * Description:       Easily inject Critical CSS and Secondary CSS (with unused styles removed) to improve site speed and performance.
    5  * Version:           1.4.4
     5 * Version:           1.4.5
    66 * Requires at least: 6.2
    77 * Tested up to:      6.8
  • easy-critical-css/trunk/inc/class-api-request-handler.php

    r3401089 r3429798  
    5050                    return new WP_Error(
    5151                        'cooldown_active',
     52                        // translators: %d is the remaining waiting time.
    5253                        sprintf( __( 'Critical CSS was recently generated. Please try again in %d minute(s).', 'easy-critical-css' ), $minutes )
    5354                    );
     
    6667        // Atomically claim non-pending existing row by updating it.
    6768        $update_sql = $wpdb->prepare(
     69            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    6870            "UPDATE {$table_name}
    6971             SET handshake = %s, page_url = %s, processing_status = 'pending', requested_time = %s
     
    7678        );
    7779
     80        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Atomic claim-or-insert operation for race condition prevention requires direct database query without caching. Prepared above.
    7881        $wpdb->query( $update_sql );
    7982        if ( $wpdb->rows_affected <= 0 ) {
     
    8992                    return new WP_Error(
    9093                        'already_pending',
     94                        // translators: %d is the remaining waiting time.
    9195                        sprintf( __( 'Critical CSS is already being generated. Please try again in %d minutes.', 'easy-critical-css' ), $remaining )
    9296                    );
     
    9599
    96100            // No non-stale pending row to block us, so insert a new row.
    97             $insert_result = $wpdb->insert(
     101            $insert_result = $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Atomic claim-or-insert operation for race condition prevention requires direct database query.
    98102                $table_name,
    99103                [
  • easy-critical-css/trunk/inc/class-api-service.php

    r3402049 r3429798  
    139139                        'critical_css_pending',
    140140                        sprintf(
    141                             // translators: %d is the remianing waiting time.
     141                            // translators: %d is the remaining waiting time.
    142142                            __( 'Critical CSS is currently being generated. Please try again in %d minutes if it is still pending.', 'easy-critical-css' ),
    143143                            $remaining_time
     
    157157                        'critical_css_invalid',
    158158                        sprintf(
    159                             // translators: %d is the remianing waiting time.
     159                            // translators: %d is the remaining waiting time.
    160160                            __( 'Invalid API error. Please try again in %d minutes.', 'easy-critical-css' ),
    161161                            $remaining_time
  • easy-critical-css/trunk/inc/class-critical-css-injector.php

    r3388125 r3429798  
    100100
    101101        // Don't output anything if we are manual and have no secondary.
    102         if ( $is_manual_mode && empty( Settings::get_individual_manual_secondary_css( $url_hash ) ) ) {
     102        // Use Critical_CSS::get_secondary_css so any URL-detection/acknowledge logic applies.
     103        if ( $is_manual_mode && empty( Critical_CSS::get_secondary_css( $url_hash ) ) ) {
    103104            return;
    104105        }
  • easy-critical-css/trunk/inc/class-critical-css.php

    r3401089 r3429798  
    191191        $mode = Settings::get_individual_mode( $identifier );
    192192        if ( Settings::get_individual_mode( $identifier ) === 'manual' ) {
    193             return Settings::get_individual_default_critical_css( $identifier );
     193            $css = Settings::get_individual_default_critical_css( $identifier );
     194            if ( Helpers::css_looks_like_url( $css ) ) {
     195                return '';
     196            }
     197            return $css;
    194198        }
    195199
     
    202206        // Use generated if exists, falling back to default.
    203207        $generated = self::get_generated_css( $identifier );
     208
    204209        return ! empty( $generated['critical_css'] )
    205210            ? $generated['critical_css']
     
    227232        $mode = Settings::get_individual_mode( $identifier );
    228233        if ( $mode === 'manual' ) {
    229             return Settings::get_individual_manual_secondary_css( $identifier );
     234            $css = Settings::get_individual_manual_secondary_css( $identifier );
     235            if ( Helpers::css_looks_like_url( $css ) ) {
     236                return '';
     237            }
     238            return $css;
    230239        }
    231240
  • easy-critical-css/trunk/inc/class-database.php

    r3401089 r3429798  
    171171        );
    172172
     173        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Prepared above.
    173174        $row = $wpdb->get_row( $sql, ARRAY_A );
    174175
     
    376377
    377378        $rows = $wpdb->get_results(
     379            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    378380            $wpdb->prepare( "SELECT * FROM {$table_name} WHERE post_id = %d", (int) $post_id ),
    379381            ARRAY_A
  • easy-critical-css/trunk/inc/class-helpers.php

    r3402049 r3429798  
    311311        // Trim and normalize whitespace
    312312        return trim( $css );
     313    }
     314
     315    public static function css_looks_like_url( $css ) {
     316        if ( ! is_string( $css ) ) {
     317            return false;
     318        }
     319
     320        // Trim whitespace.
     321        $trimmed = ltrim( $css );
     322        if ( $trimmed === '' ) {
     323            return false;
     324        }
     325
     326        // Pull first 10 characters.
     327        $first10 = substr( $trimmed, 0, 10 );
     328
     329        // Quick check for http(s).
     330        if ( stripos( $first10, 'http://' ) === 0 || stripos( $first10, 'https://' ) === 0 ) {
     331            return true;
     332        }
     333
     334        // Check leading slash but not start-of-comment (/*)
     335        if ( $first10[0] === '/' && ( ! isset( $first10[1] ) || $first10[1] !== '*' ) ) {
     336            return true;
     337        }
     338
     339        return false;
    313340    }
    314341
  • easy-critical-css/trunk/inc/class-plugin.php

    r3402049 r3429798  
    1010    private static $instance = null;
    1111
    12     private static $plugin_version = '1.4.4';
     12    private static $plugin_version = '1.4.5';
    1313
    1414    private static $db_version = '2';
     
    8686        Gutenberg::init();
    8787        Delete_Handler::init();
     88        Notification::init();
    8889        Reset_Handler::init();
    8990        REST_API::init();
  • easy-critical-css/trunk/inc/class-rest-api.php

    r3402049 r3429798  
    219219            ]
    220220        );
     221
     222        register_rest_route(
     223            self::$route_namespace,
     224            '/dismiss-notification',
     225            [
     226                'methods'             => 'POST',
     227                'callback'            => [ __CLASS__, 'dismiss_notification' ],
     228                'permission_callback' => function () {
     229                    return current_user_can( 'manage_options' );
     230                },
     231            ]
     232        );
     233
     234        // Activate auto generation via REST (called from admin JS)
     235        register_rest_route(
     236            self::$route_namespace,
     237            '/activate-auto',
     238            [
     239                'methods'             => 'POST',
     240                'callback'            => [ __CLASS__, 'activate_auto_generation' ],
     241                'permission_callback' => function () {
     242                    return current_user_can( 'manage_options' );
     243                },
     244            ]
     245        );
    221246    }
    222247
     
    550575            global $wpdb;
    551576            $table = esc_sql( Database::get_table_name() );
     577            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Required SQL for deduplication, specific context makes caching unnecessary.
    552578            $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE post_id = %d", $resolved_post_id ) );
    553579
     
    850876        return rest_ensure_response( $status );
    851877    }
     878
     879    public static function dismiss_notification( WP_REST_Request $request ) {
     880        $nonce = $request->get_header( 'X-WP-Nonce' ) ?: $request->get_param( '_wpnonce' );
     881        if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
     882            return new WP_Error(
     883                'invalid_nonce',
     884                __( 'Invalid security token.', 'easy-critical-css' ),
     885                [ 'status' => 403 ]
     886            );
     887        }
     888
     889        // Dismiss for a year to avoid nagging.
     890        TimedOption::set( 'auto_mode_setup_notif', time(), YEAR_IN_SECONDS );
     891
     892        return rest_ensure_response( [ 'success' => true ] );
     893    }
     894
     895    public static function activate_auto_generation( WP_REST_Request $request ) {
     896        $nonce = $request->get_header( 'X-WP-Nonce' ) ?: $request->get_param( '_wpnonce' );
     897        if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
     898            return new WP_Error(
     899                'invalid_nonce',
     900                __( 'Invalid security token.', 'easy-critical-css' ),
     901                [ 'status' => 403 ]
     902            );
     903        }
     904
     905        update_option( 'easy_cc_critical_css_mode', 'auto' );
     906
     907        // Dismiss notification for a day to avoid immediate nagging.
     908        TimedOption::set( 'auto_mode_setup_notif', time(), DAY_IN_SECONDS );
     909
     910        return rest_ensure_response( [ 'success' => true ] );
     911    }
    852912}
  • easy-critical-css/trunk/inc/class-uninstall-handler.php

    r3395875 r3429798  
    2626        global $wpdb;
    2727        $table_name = $wpdb->prefix . 'easy_critical_css';
    28         $wpdb->query( "DROP TABLE IF EXISTS $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Dropping a table with no input: safe to ignore the PHPCS rules.
     28        $wpdb->query( "DROP TABLE IF EXISTS " . esc_sql( $table_name ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Dropping plugin table during uninstall requires direct database query.
    2929
    3030        // Delete any static files.
  • easy-critical-css/trunk/readme.txt

    r3402049 r3429798  
    44Tags: critical css, unused css, performance, optimization, lighthouse
    55Requires at least: 6.2
    6 Tested up to:      6.8
     6Tested up to:      6.9
    77Requires PHP:      7.4
    8 Stable tag:        1.4.4
     8Stable tag:        1.4.5
    99License:           GPLv2 or later
    1010License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     
    102102== Changelog ==
    103103
     104= 1.4.5 =
     105- OPTIMIZATION: Adds dismissible notification prompting users with active licenses to activate auto-generation
     106- FIX: Prevents manual CSS input fields from accepting URLs instead of CSS styles
     107- FIX: Removes unnecessary console logging
     108
    104109= 1.4.4 =
    105110- FIX: Addresses an issue where transients clear too quickly on some server configurations.
     
    186191== Upgrade Notice ==
    187192
     193= 1.4.5 =
     194* This update includes bug fixes and improves code quality.
     195
    188196= 1.4.4 =
    189197* This update provides bug fixes.
  • easy-critical-css/trunk/src/components/settingsField.tsx

    r3284313 r3429798  
    8888
    8989      {setting.type === 'textarea' && (
    90         <textarea
    91           id={keyName}
    92           value={typeof value === 'string' ? value : ""}
    93           onChange={(e) => handleSettingsChange(keyName, e.target.value)}
    94           rows={5}
    95           style={{ width: '100%', padding: '5px' }}
    96         />
     90        <>
     91          <textarea
     92            id={keyName}
     93            value={typeof value === 'string' ? value : ""}
     94            onChange={(e) => handleSettingsChange(keyName, e.target.value)}
     95            rows={5}
     96            style={{ width: '100%', padding: '5px' }}
     97          />
     98
     99          {/* Show warning if the textarea contents look like a URL */}
     100          {(keyName === 'critical_css' || keyName === 'manual_secondary_css') && typeof value === 'string' && (() => {
     101            const raw = value as string
     102            // Minimal check: left-trim, take first 10 chars, and test for prefixes.
     103            const firstTen = raw.replace(/^\s+/, '').slice(0, 10)
     104            const looksLikeUrl = (firstTen.startsWith('http://') || firstTen.startsWith('https://') || (firstTen.startsWith('/') && !firstTen.startsWith('/*')))
     105            return looksLikeUrl ? (
     106              <div style={{ marginTop: '8px', padding: '8px', background: '#fff3cd', border: '1px solid #ffeeba', borderRadius: '4px' }}>
     107                <div style={{ fontWeight: 600, marginBottom: '6px' }}>{__('It looks like you pasted a URL.', 'easy-critical-css')}</div>
     108                <div style={{ marginBottom: '6px' }}>{__('Open that URL, copy the stylesheet contents, and paste the CSS here. Do not paste the URL itself. Pasting a URL can break your site when used as CSS.', 'easy-critical-css')}</div>
     109                <div style={{ marginBottom: '6px' }}>
     110                  <a href="https://criticalcss.net/docs/" target="_blank" rel="noopener noreferrer">{__('View help docs', 'easy-critical-css')}</a>
     111                </div>
     112              </div>
     113            ) : null
     114          })()}
     115        </>
    97116      )}
    98117
  • easy-critical-css/trunk/vendor/composer/autoload_classmap.php

    r3402049 r3429798  
    2929    'EasyCriticalCSS\\Helpers' => $baseDir . '/inc/class-helpers.php',
    3030    'EasyCriticalCSS\\Individual_Settings' => $baseDir . '/inc/class-individual-settings.php',
     31    'EasyCriticalCSS\\Notification' => $baseDir . '/inc/class-notification.php',
    3132    'EasyCriticalCSS\\Plugin' => $baseDir . '/inc/class-plugin.php',
    3233    'EasyCriticalCSS\\REST_API' => $baseDir . '/inc/class-rest-api.php',
    3334    'EasyCriticalCSS\\Reset_Handler' => $baseDir . '/inc/class-reset-handler.php',
    3435    'EasyCriticalCSS\\Settings' => $baseDir . '/inc/class-settings.php',
    35     'EasyCriticalCSS\\TimedOption' => $baseDir . '/inc/class-timed_option.php',
     36    'EasyCriticalCSS\\TimedOption' => $baseDir . '/inc/class-timed-option.php',
    3637    'EasyCriticalCSS\\Uninstall_Handler' => $baseDir . '/inc/class-uninstall-handler.php',
    3738);
  • easy-critical-css/trunk/vendor/composer/autoload_static.php

    r3402049 r3429798  
    3434        'EasyCriticalCSS\\Helpers' => __DIR__ . '/../..' . '/inc/class-helpers.php',
    3535        'EasyCriticalCSS\\Individual_Settings' => __DIR__ . '/../..' . '/inc/class-individual-settings.php',
     36        'EasyCriticalCSS\\Notification' => __DIR__ . '/../..' . '/inc/class-notification.php',
    3637        'EasyCriticalCSS\\Plugin' => __DIR__ . '/../..' . '/inc/class-plugin.php',
    3738        'EasyCriticalCSS\\REST_API' => __DIR__ . '/../..' . '/inc/class-rest-api.php',
    3839        'EasyCriticalCSS\\Reset_Handler' => __DIR__ . '/../..' . '/inc/class-reset-handler.php',
    3940        'EasyCriticalCSS\\Settings' => __DIR__ . '/../..' . '/inc/class-settings.php',
    40         'EasyCriticalCSS\\TimedOption' => __DIR__ . '/../..' . '/inc/class-timed_option.php',
     41        'EasyCriticalCSS\\TimedOption' => __DIR__ . '/../..' . '/inc/class-timed-option.php',
    4142        'EasyCriticalCSS\\Uninstall_Handler' => __DIR__ . '/../..' . '/inc/class-uninstall-handler.php',
    4243    );
  • easy-critical-css/trunk/vendor/composer/installed.php

    r3402049 r3429798  
    44        'pretty_version' => 'dev-main',
    55        'version' => 'dev-main',
    6         'reference' => 'ea2ebe9b5d6c7882882c5dcd835bd2d76e8d97c2',
     6        'reference' => 'c8ce21f4f3bcf284c9a6b55f62219e608f3888e9',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
     
    2323            'pretty_version' => 'dev-main',
    2424            'version' => 'dev-main',
    25             'reference' => 'ea2ebe9b5d6c7882882c5dcd835bd2d76e8d97c2',
     25            'reference' => 'c8ce21f4f3bcf284c9a6b55f62219e608f3888e9',
    2626            'type' => 'wordpress-plugin',
    2727            'install_path' => __DIR__ . '/../../',
Note: See TracChangeset for help on using the changeset viewer.