Changeset 3789556
- Timestamp:
- 11/07/2026 12:41:29 PM (less than one hour ago)
- Location:
- marqueeflow
- Files:
-
- 14 edited
- 1 copied
-
tags/1.0.3 (copied) (copied from marqueeflow/trunk )
-
tags/1.0.3/blocks/marqueeflow/editor.css (modified) (1 diff)
-
tags/1.0.3/build/index.asset.php (modified) (1 diff)
-
tags/1.0.3/build/index.js (modified) (1 diff)
-
tags/1.0.3/includes/class-mf-block-marqueeflow.php (modified) (1 diff)
-
tags/1.0.3/marqueeflow.php (modified) (4 diffs)
-
tags/1.0.3/readme.txt (modified) (4 diffs)
-
tags/1.0.3/src/blocks/marqueeflow/edit.js (modified) (2 diffs)
-
trunk/blocks/marqueeflow/editor.css (modified) (1 diff)
-
trunk/build/index.asset.php (modified) (1 diff)
-
trunk/build/index.js (modified) (1 diff)
-
trunk/includes/class-mf-block-marqueeflow.php (modified) (1 diff)
-
trunk/marqueeflow.php (modified) (4 diffs)
-
trunk/readme.txt (modified) (4 diffs)
-
trunk/src/blocks/marqueeflow/edit.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
marqueeflow/tags/1.0.3/blocks/marqueeflow/editor.css
r3788849 r3789556 123 123 } 124 124 125 /* Pro upgrade panel in the Inspector sidebar */ 126 .mf-pro-panel .components-panel__body-toggle { 127 display: none; 128 } 129 130 .mf-pro-panel__inner { 131 padding: 4px 0; 132 } 133 134 .mf-pro-panel__title { 135 margin: 0 0 6px; 136 font-size: 0.8rem; 137 font-weight: 600; 138 text-transform: uppercase; 139 letter-spacing: 0.06em; 140 color: #1e1e1e; 141 } 142 143 .mf-pro-panel__features { 144 margin: 0 0 10px; 145 font-size: 0.8rem; 146 color: #757575; 125 /* Compact, optional promotion above the block's settings. */ 126 .mf-upgrade-panel p { 127 margin-top: 0; 128 font-size: 13px; 147 129 line-height: 1.5; 148 130 } 149 131 150 .mf-pro-panel__code { 151 display: inline-block; 152 font-family: monospace; 153 font-size: 0.62rem; 154 background: #f0f0f0; 155 border: 1px solid #ddd; 156 border-radius: 3px; 157 padding: 1px 5px; 158 letter-spacing: 0.04em; 159 color: #1e1e1e; 132 .mf-upgrade-panel .components-button { 133 white-space: normal; 134 height: auto; 135 min-height: 36px; 160 136 } 161 137 162 .mf-pro-panel__list { 163 list-style: disc; 164 margin: 0 0 12px; 165 padding: 0 0 0 14px; 166 font-size: 0.8rem; 167 color: #757575; 168 line-height: 1.2; 169 } 170 171 .mf-pro-panel__list li { 172 margin: 0; 173 margin-bottom: 6px; 174 } 175 176 .mf-pro-panel .components-button { 177 width: 100%; 178 justify-content: center; 179 margin: 8px 0; 180 } 181 182 .mf-pro-panel .components-button:last-child { 183 margin-bottom: 0; 184 } 185 186 .mf-pro-panel__disclaimer { 187 margin: 8px 0 0; 188 font-size: 0.72rem; 189 color: #949494; 190 text-align: center; 138 .mf-upgrade-panel .dashicons-external { 139 font-size: 16px; 140 width: 16px; 141 height: 16px; 142 margin-left: 6px; 143 flex-shrink: 0; 191 144 } 192 145 -
marqueeflow/tags/1.0.3/build/index.asset.php
r3788849 r3789556 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => ' 46ea4f9afb782e9b1411');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'a1a805e7731bf7bed9f7'); -
marqueeflow/tags/1.0.3/build/index.js
r3788849 r3789556 1 (()=>{"use strict";const e=window.wp.hooks,t=window.wp.blocks, l=window.React,a=window.wp.i18n,r=window.wp.blockEditor,o=window.wp.components,n=window.wp.element,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"marqueeflow/marqueeflow","title":"MarqueeFlow","description":"A lightweight marquee-style slider for continuously scrolling images","category":"media","icon":"format-gallery","keywords":["marquee","slider","carousel","image","scrolling","banner"],"supports":{"html":false,"align":["wide","full"]},"attributes":{"images":{"type":"array","default":[],"items":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"alt":{"type":"string"},"link":{"type":"string"}}}},"speed":{"type":"string","default":"normal","enum":["slow","normal","fast"]},"imageHeight":{"type":"string","default":"medium","enum":["small","medium","large","custom"]},"gap":{"type":"string","default":"normal","enum":["normal","spacious","custom"]},"pauseOnHover":{"type":"boolean","default":false},"direction":{"type":"string","default":"ltr","enum":["ltr","rtl"]},"customHeight":{"type":"number","default":80},"customGap":{"type":"number","default":64},"borderRadius":{"type":"number","default":0},"opacity":{"type":"number","default":100},"fadeEdges":{"type":"boolean","default":false},"grayscale":{"type":"boolean","default":false},"invertGrayscale":{"type":"boolean","default":false},"maxWidth":{"type":"string","default":"normal","enum":["narrow","normal","medium","wide","none"]}},"example":{"attributes":{"images":[{"id":1,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 1"},{"id":2,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 2"},{"id":3,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 3"},{"id":4,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 4"},{"id":5,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 5"},{"id":6,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 6"}],"speed":"normal","imageHeight":"medium"}},"textdomain":"marqueeflow","editorStyle":"file:./editor.css","style":"marqueeflow-style"}');(0,t.registerBlockType)(i.name,{...i,edit:function(t){const{attributes:i,setAttributes:m}=t,u={...t,apiVersion:1},{images:s,speed:d,imageHeight:g,gap:c,pauseOnHover:f,direction:w,maxWidth:p}=i,[h,_]=(0,n.useState)(!1),[q,y]=(0,n.useState)(""),[v,b]=(0,n.useState)(0),[x,E]=(0,n.useState)("mouse"),C=(0,r.useBlockProps)(),N=(0,n.useRef)({active:!1,index:null}),[S,I]=(0,n.useState)(null),k=(0,n.useRef)(null),A=(0,n.useRef)(null),F=e=>{_(!0);const t=function(e,t){const l=new Set,a=e=>{if("number"!=typeof e.id&&("string"!=typeof e.id||!/^\d+$/.test(e.id)))return null;const t=Number(e.id);return Number.isSafeInteger(t)&&t>0?t:null};return e.map(e=>{const r=a(e),o=t.findIndex((t,o)=>{if(l.has(o)||!t||"object"!=typeof t)return!1;const n=a(t);return null!==r?n===r:null===n&&Boolean(e.url)&&t.url===e.url});return-1!==o&&l.add(o),{...-1===o?{}:t[o],id:e.id,url:e.url,alt:e.alt||""}})}(e,s);m({images:t}),b(0),_(!1)};(0,n.useEffect)(()=>{0!==s.length?v>s.length-1&&b(s.length-1):b(0)},[s.length,v]),(0,n.useEffect)(()=>{if(null===A.current)return;const e=A.current;A.current=null,0!==s.length&&P(e)},[s.length]);const $=(e,t)=>{if(t<0||t>=s.length||e===t)return!1;const l=[...s],[a]=l.splice(e,1);return l.splice(t,0,a),m({images:l}),!0},H=(0,n.useCallback)((e,t)=>{e.target.closest(".marqueeflow-editor__remove, [data-marqueeflow-extension-controls]")||(e.stopPropagation(),E("mouse"),b(t),N.current={active:!0,index:t},I(t),e.currentTarget.setPointerCapture(e.pointerId))},[]),R=(0,n.useCallback)(e=>{if(!N.current.active)return;const t=((e,t)=>{if(!k.current)return null;const l=k.current.querySelectorAll(".marqueeflow-editor__thumb");for(let a=0;a<l.length;a++){const r=l[a].getBoundingClientRect();if(e>=r.left&&e<=r.right&&t>=r.top&&t<=r.bottom)return a}return null})(e.clientX,e.clientY),l=N.current.index;null!==t&&t!==l&&$(l,t)&&(N.current.index=t,I(t))},[s]),M=(0,n.useCallback)(()=>{N.current={active:!1,index:null},I(null)},[]),P=e=>{requestAnimationFrame(()=>{const t=k.current?.querySelector(`[data-thumb-index="${e}"]`);t&&t.focus()})},D=e=>{"Tab"!==e.key||e.shiftKey||(e.preventDefault(),E("keyboard"),P(v))},z=function(e){return{imageHeight:["small","medium","large"].includes(e.imageHeight)?e.imageHeight:"medium",gap:["normal","spacious"].includes(e.gap)?e.gap:"normal"}}(i),B={small:40,medium:60,large:80}[z.imageHeight]||60,L=Number.isFinite(i.borderRadius)?Math.trunc(Math.min(100,Math.max(0,i.borderRadius))):0,O={className:(()=>{const e=["marqueeflow",`marqueeflow--${d}`];return e.push(`marqueeflow--height-${z.imageHeight}`),e.push(`marqueeflow--gap-${z.gap}`),"rtl"===w&&e.push("marqueeflow--rtl"),f&&e.push("marqueeflow--pause-hover"),e.push(`marqueeflow--max-width-${p}`),e.join(" ")})(),style:{"--marqueeflow-total-images":s.length,"--marqueeflow-height":`${B}px`,...L>0?{"--marqueeflow-radius":`${L}px`}:{}}},U=(0,e.applyFilters)("marqueeflow.editor.preview",O,u),j="string"==typeof U?.className?U.className:O.className,T=U?.style&&"object"==typeof U.style&&!Array.isArray(U.style)?U.style:O.style;return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(r.InspectorControls,null,(0,l.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,a.__)("Images","marqueeflow"),initialOpen:!0},(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Image Height","marqueeflow"),value:g,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===g?[{label:(0,a.__)("Saved setting (using Medium)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,a.__)("Small (40px)","marqueeflow"),value:"small"},{label:(0,a.__)("Medium (60px)","marqueeflow"),value:"medium"},{label:(0,a.__)("Large (80px)","marqueeflow"),value:"large"}],"imageHeight",u),onChange:e=>m({imageHeight:e}),help:(0,a.__)("Images scale proportionally to the set height","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"imageHeight",u),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Max Image Width","marqueeflow"),value:p,options:[{label:(0,a.__)("Narrow (3× height)","marqueeflow"),value:"narrow"},{label:(0,a.__)("Normal (4× height)","marqueeflow"),value:"normal"},{label:(0,a.__)("Medium (5× height)","marqueeflow"),value:"medium"},{label:(0,a.__)("Wide (6× height)","marqueeflow"),value:"wide"},{label:(0,a.__)("None (no limit)","marqueeflow"),value:"none"}],onChange:e=>m({maxWidth:e}),help:(0,a.__)("Limits how wide a single image can grow. Prevents long horizontal images from dominating the strip.","marqueeflow")}),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Gap Between Images","marqueeflow"),value:c,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===c?[{label:(0,a.__)("Saved setting (using Normal)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,a.__)("Normal","marqueeflow"),value:"normal"},{label:(0,a.__)("Spacious","marqueeflow"),value:"spacious"}],"gap",u),onChange:e=>m({gap:e})}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"gap",u),(0,l.createElement)(o.RangeControl,{label:(0,a.__)("Corner radius (px)","marqueeflow"),value:L,min:0,max:100,onChange:e=>m({borderRadius:null!=e?e:0})}),(0,e.applyFilters)("marqueeflow.editor.appearance",null,u)),(0,l.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,a.__)("Animation","marqueeflow"),initialOpen:!1},(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Speed","marqueeflow"),value:d,options:[{label:(0,a.__)("Slow","marqueeflow"),value:"slow"},{label:(0,a.__)("Normal","marqueeflow"),value:"normal"},{label:(0,a.__)("Fast","marqueeflow"),value:"fast"}],onChange:e=>m({speed:e})}),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Direction","marqueeflow"),value:w,options:[{label:(0,a.__)("Left to Right","marqueeflow"),value:"ltr"},{label:(0,a.__)("Right to Left","marqueeflow"),value:"rtl"}],onChange:e=>m({direction:e})}),(0,l.createElement)(o.ToggleControl,{label:(0,a.__)("Pause on Hover","marqueeflow"),checked:f,onChange:e=>m({pauseOnHover:e}),help:(0,a.__)("Stop animation when user hovers over the slider","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.animation",null,u)),(0,e.applyFilters)("marqueeflow.editor.inspector",null,u)),(0,l.createElement)("div",{...C},s.length>0&&(0,l.createElement)("div",{className:"marqueeflow-editor__preview"},(0,l.createElement)("span",{className:"marqueeflow-editor__preview-label"},(0,a.__)("Preview","marqueeflow")),(0,l.createElement)("div",{className:j,style:T},["a","b","c"].map((t,a)=>(0,l.createElement)("ul",{key:t,className:"marqueeflow__set","aria-hidden":a>0||void 0,inert:a>0?"":void 0},s.map((r,o)=>(0,l.createElement)("li",{key:`${t}-${o}`,className:"marqueeflow__item"},(0,e.applyFilters)("marqueeflow.editor.image",(0,l.createElement)("img",{src:r.url,alt:r.alt}),r,{...u,index:o,setIndex:a,isDuplicate:a>0}))))))),0===s.length&&(0,l.createElement)(r.MediaUploadCheck,null,(0,l.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:[],render:({open:e})=>(0,l.createElement)(o.Placeholder,{icon:"format-gallery",label:(0,a.__)("MarqueeFlow","marqueeflow"),instructions:(0,a.__)("Add images to create a continuously scrolling marquee.","marqueeflow")},(0,l.createElement)(o.Button,{variant:"primary",onClick:e},(0,a.__)("Select Images","marqueeflow")))})),s.length>0&&(0,l.createElement)("div",{className:"marqueeflow-editor__management",onKeyDownCapture:()=>E("keyboard"),onPointerDownCapture:()=>E("mouse")},h&&(0,l.createElement)(o.Spinner,null),(0,l.createElement)(r.MediaUploadCheck,null,(0,l.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:s.map(e=>e.id),render:({open:e})=>(0,l.createElement)(o.Button,{onClick:e,onKeyDown:D,variant:"primary",style:{marginBottom:"12px"}},(0,a.__)("Edit Images","marqueeflow"))})),s.length<6&&(0,l.createElement)("p",{className:"marqueeflow-editor__hint"},(0,a.__)("For a smooth scrolling effect, we recommend at least 6 images.","marqueeflow")),(0,l.createElement)("p",{style:{fontSize:"0.875rem",margin:"0 0 4px"}},(0,a.__)("Selected images:","marqueeflow")," ",(0,l.createElement)("strong",null,s.length),(0,l.createElement)("span",{id:"marqueeflow-editor-keyboard-hint",style:{color:"#757575",marginLeft:"8px",fontSize:"0.8rem"}},"keyboard"===x?(0,a.__)("← → navigate, ↑ ↓ actions, Shift + ← → reorder","marqueeflow"):(0,a.__)("Drag to reorder","marqueeflow"))),(0,l.createElement)("div",{className:"marqueeflow-editor__sr-only",role:"status","aria-live":"polite"},q),(0,l.createElement)("div",{className:"marqueeflow-editor__grid",ref:k,role:"group","aria-label":(0,a.__)("Reorder images","marqueeflow"),onKeyDownCapture:e=>{const{key:t,shiftKey:l}=e;if("ArrowLeft"!==t&&"ArrowUp"!==t&&"ArrowRight"!==t&&"ArrowDown"!==t)return;if(E("keyboard"),e.target.closest('input, textarea, select, [contenteditable="true"], [data-marqueeflow-extension-controls]'))return;const r=e.target.closest(".marqueeflow-editor__thumb");if(!r)return;const o=Number(r.dataset.thumbIndex);if(Number.isNaN(o))return;const n="ArrowLeft"===t||"ArrowRight"===t,i="ArrowUp"===t||"ArrowDown"===t,m=!!e.target.closest(".marqueeflow-editor__remove");if(n){let r=o;if("ArrowLeft"===t?r=o-1:"ArrowRight"===t&&(r=o+1),e.preventDefault(),e.stopPropagation(),l)return void($(o,r)&&(b(r),y((0,a.sprintf)(/* translators: 1: new position, 2: total number of images */ /* translators: 1: new position, 2: total number of images */2 (0, a.__)("Image moved to position %1$d of %2$d.","marqueeflow"),r+1,s.length)),P(r)));if(r<0||r>=s.length)return;return b(r),void P(r)}i&&(e.preventDefault(),e.stopPropagation(),b(o),m?P(o):requestAnimationFrame(()=>{const e=k.current?.querySelector(`[data-thumb-index="${o}"] .marqueeflow-editor__remove`);e&&e.focus()}))}},s.map((t,r)=>(0,l.createElement)("div",{key:t.id||r,"data-thumb-index":r,className:"marqueeflow-editor__thumb"+(S===r?" is-dragging":""),tabIndex:r===v?0:-1,"aria-label":(0,a.sprintf)((0,a.__)("Image %1$d of %2$d","marqueeflow"),r+1,s.length),"aria-describedby":"marqueeflow-editor-keyboard-hint",onFocus:()=>b(r),onPointerDown:e=>H(e,r),onPointerMove:R,onPointerUp:M,style:{touchAction:"none"}},(0,l.createElement)("img",{src:t.url,alt:t.alt}),((t,a)=>{const r=(0,e.applyFilters)("marqueeflow.editor.imageControls",null,t,{...u,index:a});return null==r?null:(0,l.createElement)("div",{"data-marqueeflow-extension-controls":!0},r)})(t,r),(0,l.createElement)("button",{className:"marqueeflow-editor__remove",onClick:()=>(e=>{const t=s.filter((t,l)=>l!==e),l=0===t.length?null:Math.min(e,t.length-1);A.current=l,m({images:t}),null===l?(b(0),y((0,a.__)("Image removed.","marqueeflow"))):(b(l),y((0,a.sprintf)(/* translators: 1: new focused position, 2: total number of images */ /* translators: 1: new focused position, 2: total number of images */3 (0, a.__)("Image removed. Focus moved to image %1$d of %2$d.","marqueeflow"),l+1,t.length)))})(r),onFocus:()=>b(r),type:"button",tabIndex:-1,"aria-label":(0,a.__)("Remove image","marqueeflow")},"✕")))))))},save:function({attributes:e}){return null}})&&(window.marqueeflowEditorApi=Object.freeze({apiVersion:1,sharedAppearance:!0,sharedLayout:!0,sharedAnimation:!0,blockName:i.name}),(0,e.doAction)("marqueeflow.editor.ready",window.marqueeflowEditorApi))})();1 (()=>{"use strict";const e=window.wp.hooks,t=window.wp.blocks,a=window.React,l=window.wp.i18n,r=window.wp.blockEditor,o=window.wp.components,n=window.wp.element,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"marqueeflow/marqueeflow","title":"MarqueeFlow","description":"A lightweight marquee-style slider for continuously scrolling images","category":"media","icon":"format-gallery","keywords":["marquee","slider","carousel","image","scrolling","banner"],"supports":{"html":false,"align":["wide","full"]},"attributes":{"images":{"type":"array","default":[],"items":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"alt":{"type":"string"},"link":{"type":"string"}}}},"speed":{"type":"string","default":"normal","enum":["slow","normal","fast"]},"imageHeight":{"type":"string","default":"medium","enum":["small","medium","large","custom"]},"gap":{"type":"string","default":"normal","enum":["normal","spacious","custom"]},"pauseOnHover":{"type":"boolean","default":false},"direction":{"type":"string","default":"ltr","enum":["ltr","rtl"]},"customHeight":{"type":"number","default":80},"customGap":{"type":"number","default":64},"borderRadius":{"type":"number","default":0},"opacity":{"type":"number","default":100},"fadeEdges":{"type":"boolean","default":false},"grayscale":{"type":"boolean","default":false},"invertGrayscale":{"type":"boolean","default":false},"maxWidth":{"type":"string","default":"normal","enum":["narrow","normal","medium","wide","none"]}},"example":{"attributes":{"images":[{"id":1,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 1"},{"id":2,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 2"},{"id":3,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 3"},{"id":4,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 4"},{"id":5,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 5"},{"id":6,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 6"}],"speed":"normal","imageHeight":"medium"}},"textdomain":"marqueeflow","editorStyle":"file:./editor.css","style":"marqueeflow-style"}');(0,t.registerBlockType)(i.name,{...i,edit:function(t){const{attributes:i,setAttributes:m}=t,u={...t,apiVersion:1},{images:s,speed:d,imageHeight:g,gap:c,pauseOnHover:f,direction:p,maxWidth:w}=i,[h,_]=(0,n.useState)(!1),[q,y]=(0,n.useState)(""),[v,b]=(0,n.useState)(0),[x,E]=(0,n.useState)("mouse"),C=(0,r.useBlockProps)(),N=(0,n.useRef)({active:!1,index:null}),[S,k]=(0,n.useState)(null),I=(0,n.useRef)(null),A=(0,n.useRef)(null),F=e=>{_(!0);const t=function(e,t){const a=new Set,l=e=>{if("number"!=typeof e.id&&("string"!=typeof e.id||!/^\d+$/.test(e.id)))return null;const t=Number(e.id);return Number.isSafeInteger(t)&&t>0?t:null};return e.map(e=>{const r=l(e),o=t.findIndex((t,o)=>{if(a.has(o)||!t||"object"!=typeof t)return!1;const n=l(t);return null!==r?n===r:null===n&&Boolean(e.url)&&t.url===e.url});return-1!==o&&a.add(o),{...-1===o?{}:t[o],id:e.id,url:e.url,alt:e.alt||""}})}(e,s);m({images:t}),b(0),_(!1)};(0,n.useEffect)(()=>{0!==s.length?v>s.length-1&&b(s.length-1):b(0)},[s.length,v]),(0,n.useEffect)(()=>{if(null===A.current)return;const e=A.current;A.current=null,0!==s.length&&M(e)},[s.length]);const P=(e,t)=>{if(t<0||t>=s.length||e===t)return!1;const a=[...s],[l]=a.splice(e,1);return a.splice(t,0,l),m({images:a}),!0},$=(0,n.useCallback)((e,t)=>{e.target.closest(".marqueeflow-editor__remove, [data-marqueeflow-extension-controls]")||(e.stopPropagation(),E("mouse"),b(t),N.current={active:!0,index:t},k(t),e.currentTarget.setPointerCapture(e.pointerId))},[]),H=(0,n.useCallback)(e=>{if(!N.current.active)return;const t=((e,t)=>{if(!I.current)return null;const a=I.current.querySelectorAll(".marqueeflow-editor__thumb");for(let l=0;l<a.length;l++){const r=a[l].getBoundingClientRect();if(e>=r.left&&e<=r.right&&t>=r.top&&t<=r.bottom)return l}return null})(e.clientX,e.clientY),a=N.current.index;null!==t&&t!==a&&P(a,t)&&(N.current.index=t,k(t))},[s]),R=(0,n.useCallback)(()=>{N.current={active:!1,index:null},k(null)},[]),M=e=>{requestAnimationFrame(()=>{const t=I.current?.querySelector(`[data-thumb-index="${e}"]`);t&&t.focus()})},D=e=>{"Tab"!==e.key||e.shiftKey||(e.preventDefault(),E("keyboard"),M(v))},B=function(e){return{imageHeight:["small","medium","large"].includes(e.imageHeight)?e.imageHeight:"medium",gap:["normal","spacious"].includes(e.gap)?e.gap:"normal"}}(i),z={small:40,medium:60,large:80}[B.imageHeight]||60,O=globalThis?.marqueeflowUpgrade,L=!0===O?.show&&"string"==typeof O.url&&/^https:\/\//.test(O.url),U=Number.isFinite(i.borderRadius)?Math.trunc(Math.min(100,Math.max(0,i.borderRadius))):0,T={className:(()=>{const e=["marqueeflow",`marqueeflow--${d}`];return e.push(`marqueeflow--height-${B.imageHeight}`),e.push(`marqueeflow--gap-${B.gap}`),"rtl"===p&&e.push("marqueeflow--rtl"),f&&e.push("marqueeflow--pause-hover"),e.push(`marqueeflow--max-width-${w}`),e.join(" ")})(),style:{"--marqueeflow-total-images":s.length,"--marqueeflow-height":`${z}px`,...U>0?{"--marqueeflow-radius":`${U}px`}:{}}},j=(0,e.applyFilters)("marqueeflow.editor.preview",T,u),K="string"==typeof j?.className?j.className:T.className,W=j?.style&&"object"==typeof j.style&&!Array.isArray(j.style)?j.style:T.style;return(0,a.createElement)(a.Fragment,null,(0,a.createElement)(r.InspectorControls,null,L&&(0,a.createElement)(o.PanelBody,{className:"mf-upgrade-panel",title:(0,l.__)("MarqueeFlow Pro","marqueeflow"),initialOpen:!0},(0,a.createElement)("p",null,(0,l.__)("Add custom image sizing and spacing, fade edges, opacity and grayscale effects with the Pro add-on.","marqueeflow")),(0,a.createElement)(o.Button,{variant:"primary",href:O.url,target:"_blank",rel:"noopener noreferrer"},(0,l.__)("See Pro plans","marqueeflow"),(0,a.createElement)("span",{className:"dashicons dashicons-external","aria-hidden":"true"}),(0,a.createElement)("span",{className:"marqueeflow-editor__sr-only"},(0,l.__)(" (opens in a new tab)","marqueeflow")))),(0,a.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,l.__)("Images","marqueeflow"),initialOpen:!0},(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Image Height","marqueeflow"),value:g,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===g?[{label:(0,l.__)("Saved setting (using Medium)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,l.__)("Small (40px)","marqueeflow"),value:"small"},{label:(0,l.__)("Medium (60px)","marqueeflow"),value:"medium"},{label:(0,l.__)("Large (80px)","marqueeflow"),value:"large"}],"imageHeight",u),onChange:e=>m({imageHeight:e}),help:(0,l.__)("Images scale proportionally to the set height","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"imageHeight",u),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Max Image Width","marqueeflow"),value:w,options:[{label:(0,l.__)("Narrow (3× height)","marqueeflow"),value:"narrow"},{label:(0,l.__)("Normal (4× height)","marqueeflow"),value:"normal"},{label:(0,l.__)("Medium (5× height)","marqueeflow"),value:"medium"},{label:(0,l.__)("Wide (6× height)","marqueeflow"),value:"wide"},{label:(0,l.__)("None (no limit)","marqueeflow"),value:"none"}],onChange:e=>m({maxWidth:e}),help:(0,l.__)("Limits how wide a single image can grow. Prevents long horizontal images from dominating the strip.","marqueeflow")}),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Gap Between Images","marqueeflow"),value:c,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===c?[{label:(0,l.__)("Saved setting (using Normal)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,l.__)("Normal","marqueeflow"),value:"normal"},{label:(0,l.__)("Spacious","marqueeflow"),value:"spacious"}],"gap",u),onChange:e=>m({gap:e})}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"gap",u),(0,a.createElement)(o.RangeControl,{label:(0,l.__)("Corner radius (px)","marqueeflow"),value:U,min:0,max:100,onChange:e=>m({borderRadius:null!=e?e:0})}),(0,e.applyFilters)("marqueeflow.editor.appearance",null,u)),(0,a.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,l.__)("Animation","marqueeflow"),initialOpen:!1},(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Speed","marqueeflow"),value:d,options:[{label:(0,l.__)("Slow","marqueeflow"),value:"slow"},{label:(0,l.__)("Normal","marqueeflow"),value:"normal"},{label:(0,l.__)("Fast","marqueeflow"),value:"fast"}],onChange:e=>m({speed:e})}),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Direction","marqueeflow"),value:p,options:[{label:(0,l.__)("Left to Right","marqueeflow"),value:"ltr"},{label:(0,l.__)("Right to Left","marqueeflow"),value:"rtl"}],onChange:e=>m({direction:e})}),(0,a.createElement)(o.ToggleControl,{label:(0,l.__)("Pause on Hover","marqueeflow"),checked:f,onChange:e=>m({pauseOnHover:e}),help:(0,l.__)("Stop animation when user hovers over the slider","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.animation",null,u)),(0,e.applyFilters)("marqueeflow.editor.inspector",null,u)),(0,a.createElement)("div",{...C},s.length>0&&(0,a.createElement)("div",{className:"marqueeflow-editor__preview"},(0,a.createElement)("span",{className:"marqueeflow-editor__preview-label"},(0,l.__)("Preview","marqueeflow")),(0,a.createElement)("div",{className:K,style:W},["a","b","c"].map((t,l)=>(0,a.createElement)("ul",{key:t,className:"marqueeflow__set","aria-hidden":l>0||void 0,inert:l>0?"":void 0},s.map((r,o)=>(0,a.createElement)("li",{key:`${t}-${o}`,className:"marqueeflow__item"},(0,e.applyFilters)("marqueeflow.editor.image",(0,a.createElement)("img",{src:r.url,alt:r.alt}),r,{...u,index:o,setIndex:l,isDuplicate:l>0}))))))),0===s.length&&(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:[],render:({open:e})=>(0,a.createElement)(o.Placeholder,{icon:"format-gallery",label:(0,l.__)("MarqueeFlow","marqueeflow"),instructions:(0,l.__)("Add images to create a continuously scrolling marquee.","marqueeflow")},(0,a.createElement)(o.Button,{variant:"primary",onClick:e},(0,l.__)("Select Images","marqueeflow")))})),s.length>0&&(0,a.createElement)("div",{className:"marqueeflow-editor__management",onKeyDownCapture:()=>E("keyboard"),onPointerDownCapture:()=>E("mouse")},h&&(0,a.createElement)(o.Spinner,null),(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:s.map(e=>e.id),render:({open:e})=>(0,a.createElement)(o.Button,{onClick:e,onKeyDown:D,variant:"primary",style:{marginBottom:"12px"}},(0,l.__)("Edit Images","marqueeflow"))})),s.length<6&&(0,a.createElement)("p",{className:"marqueeflow-editor__hint"},(0,l.__)("For a smooth scrolling effect, we recommend at least 6 images.","marqueeflow")),(0,a.createElement)("p",{style:{fontSize:"0.875rem",margin:"0 0 4px"}},(0,l.__)("Selected images:","marqueeflow")," ",(0,a.createElement)("strong",null,s.length),(0,a.createElement)("span",{id:"marqueeflow-editor-keyboard-hint",style:{color:"#757575",marginLeft:"8px",fontSize:"0.8rem"}},"keyboard"===x?(0,l.__)("← → navigate, ↑ ↓ actions, Shift + ← → reorder","marqueeflow"):(0,l.__)("Drag to reorder","marqueeflow"))),(0,a.createElement)("div",{className:"marqueeflow-editor__sr-only",role:"status","aria-live":"polite"},q),(0,a.createElement)("div",{className:"marqueeflow-editor__grid",ref:I,role:"group","aria-label":(0,l.__)("Reorder images","marqueeflow"),onKeyDownCapture:e=>{const{key:t,shiftKey:a}=e;if("ArrowLeft"!==t&&"ArrowUp"!==t&&"ArrowRight"!==t&&"ArrowDown"!==t)return;if(E("keyboard"),e.target.closest('input, textarea, select, [contenteditable="true"], [data-marqueeflow-extension-controls]'))return;const r=e.target.closest(".marqueeflow-editor__thumb");if(!r)return;const o=Number(r.dataset.thumbIndex);if(Number.isNaN(o))return;const n="ArrowLeft"===t||"ArrowRight"===t,i="ArrowUp"===t||"ArrowDown"===t,m=!!e.target.closest(".marqueeflow-editor__remove");if(n){let r=o;if("ArrowLeft"===t?r=o-1:"ArrowRight"===t&&(r=o+1),e.preventDefault(),e.stopPropagation(),a)return void(P(o,r)&&(b(r),y((0,l.sprintf)(/* translators: 1: new position, 2: total number of images */ /* translators: 1: new position, 2: total number of images */ 2 (0,l.__)("Image moved to position %1$d of %2$d.","marqueeflow"),r+1,s.length)),M(r)));if(r<0||r>=s.length)return;return b(r),void M(r)}i&&(e.preventDefault(),e.stopPropagation(),b(o),m?M(o):requestAnimationFrame(()=>{const e=I.current?.querySelector(`[data-thumb-index="${o}"] .marqueeflow-editor__remove`);e&&e.focus()}))}},s.map((t,r)=>(0,a.createElement)("div",{key:t.id||r,"data-thumb-index":r,className:"marqueeflow-editor__thumb"+(S===r?" is-dragging":""),tabIndex:r===v?0:-1,"aria-label":(0,l.sprintf)((0,l.__)("Image %1$d of %2$d","marqueeflow"),r+1,s.length),"aria-describedby":"marqueeflow-editor-keyboard-hint",onFocus:()=>b(r),onPointerDown:e=>$(e,r),onPointerMove:H,onPointerUp:R,style:{touchAction:"none"}},(0,a.createElement)("img",{src:t.url,alt:t.alt}),((t,l)=>{const r=(0,e.applyFilters)("marqueeflow.editor.imageControls",null,t,{...u,index:l});return null==r?null:(0,a.createElement)("div",{"data-marqueeflow-extension-controls":!0},r)})(t,r),(0,a.createElement)("button",{className:"marqueeflow-editor__remove",onClick:()=>(e=>{const t=s.filter((t,a)=>a!==e),a=0===t.length?null:Math.min(e,t.length-1);A.current=a,m({images:t}),null===a?(b(0),y((0,l.__)("Image removed.","marqueeflow"))):(b(a),y((0,l.sprintf)(/* translators: 1: new focused position, 2: total number of images */ /* translators: 1: new focused position, 2: total number of images */ 3 (0,l.__)("Image removed. Focus moved to image %1$d of %2$d.","marqueeflow"),a+1,t.length)))})(r),onFocus:()=>b(r),type:"button",tabIndex:-1,"aria-label":(0,l.__)("Remove image","marqueeflow")},"✕")))))))},save:function({attributes:e}){return null}})&&(window.marqueeflowEditorApi=Object.freeze({apiVersion:1,sharedAppearance:!0,sharedLayout:!0,sharedAnimation:!0,blockName:i.name}),(0,e.doAction)("marqueeflow.editor.ready",window.marqueeflowEditorApi))})(); -
marqueeflow/tags/1.0.3/includes/class-mf-block-marqueeflow.php
r3788849 r3789556 56 56 57 57 wp_set_script_translations( 'marqueeflow-block-editor', 'marqueeflow' ); 58 wp_add_inline_script( 59 'marqueeflow-block-editor', 60 'window.marqueeflowUpgrade = ' . wp_json_encode( [ 61 'show' => ! class_exists( 'MarqueeFlow_Pro_Plugin', false ), 62 'url' => esc_url_raw( MARQUEEFLOW_PRO_URL ), 63 ] ) . ';', 64 'before' 65 ); 58 66 59 67 } -
marqueeflow/tags/1.0.3/marqueeflow.php
r3788849 r3789556 4 4 * Plugin URI: https://wordpress.org/plugins/marqueeflow/ 5 5 * Description: A lightweight marquee-style slider for continuously scrolling images. 6 * Version: 1.0. 26 * Version: 1.0.3 7 7 * Author: tupacan 8 8 * Author URI: https://profiles.wordpress.org/tupacan/ … … 110 110 private static ?MarqueeFlow_Plugin $instance = null; 111 111 112 public const VERSION = '1.0. 2';112 public const VERSION = '1.0.3'; 113 113 public const SLUG = 'marqueeflow'; 114 114 … … 129 129 130 130 add_action( 'plugins_loaded', [ $this, 'init' ] ); 131 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ $this, 'add_action_links' ] ); 131 132 } 132 133 … … 151 152 } 152 153 154 /** Promotion describes the add-on; it never enables paid behavior. */ 155 public function add_action_links( array $links ): array { 156 if ( class_exists( 'MarqueeFlow_Pro_Plugin', false ) ) { 157 return $links; 158 } 159 $links[] = '<a href="' . esc_url( MARQUEEFLOW_PRO_URL ) . '" target="_blank" rel="noopener noreferrer">' . 160 esc_html__( 'See Pro plans', 'marqueeflow' ) . '</a>'; 161 return $links; 162 } 163 153 164 public function init(): void { 154 165 MarqueeFlow_Assets::init(); -
marqueeflow/tags/1.0.3/readme.txt
r3788849 r3789556 4 4 Requires at least: 6.3 5 5 Tested up to: 7.1 6 Stable tag: 1.0. 26 Stable tag: 1.0.3 7 7 Requires PHP: 8.0 8 8 License: GPLv2 or later … … 23 23 * Max image width control to prevent wide logos from dominating 24 24 * Direction control: Left to Right or Right to Left 25 * Image corner radius 25 26 * Pause on hover 26 27 * Drag-and-drop image reordering in the editor … … 36 37 3. Adjust speed, height, and style in the sidebar 37 38 4. Publish 39 40 = MarqueeFlow Pro add-on = 41 42 For custom image height and spacing, faded edges, image opacity and grayscale effects, see [MarqueeFlow Pro plans](https://marqueeflow.pages.dev/). Pro is a separate paid add-on and requires this Free plugin to stay installed and active. An eligible activated license is required for paid controls and effects. Free works independently without a license or Freemius SDK. 38 43 39 44 == Installation == … … 68 73 == Changelog == 69 74 75 = 1.0.3 = 76 * Add a compact Pro plans panel in the block sidebar and a plugin-row pricing link. 77 * Hide Free promotion when the separate Pro add-on is active. 78 * Keep all Free controls and frontend behavior unchanged. 79 70 80 = 1.0.2 = 71 81 * Reorganized block settings into Images and Animation panels. -
marqueeflow/tags/1.0.3/src/blocks/marqueeflow/edit.js
r3788849 r3789556 263 263 }; 264 264 265 const upgrade = globalThis?.marqueeflowUpgrade; 266 const showUpgrade = upgrade?.show === true && typeof upgrade.url === 'string' && /^https:\/\//.test( upgrade.url ); 267 265 268 const radius = Number.isFinite( attributes.borderRadius ) ? Math.trunc( Math.min( 100, Math.max( 0, attributes.borderRadius ) ) ) : 0; 266 269 const basePreview = { … … 280 283 <> 281 284 <InspectorControls> 285 { showUpgrade && ( 286 <PanelBody className="mf-upgrade-panel" title={ __( 'MarqueeFlow Pro', 'marqueeflow' ) } initialOpen={ true }> 287 <p>{ __( 'Add custom image sizing and spacing, fade edges, opacity and grayscale effects with the Pro add-on.', 'marqueeflow' ) }</p> 288 <Button variant="primary" href={ upgrade.url } target="_blank" rel="noopener noreferrer"> 289 { __( 'See Pro plans', 'marqueeflow' ) } 290 <span className="dashicons dashicons-external" aria-hidden="true" /> 291 <span className="marqueeflow-editor__sr-only">{ __( ' (opens in a new tab)', 'marqueeflow' ) }</span> 292 </Button> 293 </PanelBody> 294 ) } 295 282 296 <PanelBody className="marqueeflow-inspector-panel" title={ __( 'Images', 'marqueeflow' ) } initialOpen={ true }> 283 297 <SelectControl -
marqueeflow/trunk/blocks/marqueeflow/editor.css
r3788849 r3789556 123 123 } 124 124 125 /* Pro upgrade panel in the Inspector sidebar */ 126 .mf-pro-panel .components-panel__body-toggle { 127 display: none; 128 } 129 130 .mf-pro-panel__inner { 131 padding: 4px 0; 132 } 133 134 .mf-pro-panel__title { 135 margin: 0 0 6px; 136 font-size: 0.8rem; 137 font-weight: 600; 138 text-transform: uppercase; 139 letter-spacing: 0.06em; 140 color: #1e1e1e; 141 } 142 143 .mf-pro-panel__features { 144 margin: 0 0 10px; 145 font-size: 0.8rem; 146 color: #757575; 125 /* Compact, optional promotion above the block's settings. */ 126 .mf-upgrade-panel p { 127 margin-top: 0; 128 font-size: 13px; 147 129 line-height: 1.5; 148 130 } 149 131 150 .mf-pro-panel__code { 151 display: inline-block; 152 font-family: monospace; 153 font-size: 0.62rem; 154 background: #f0f0f0; 155 border: 1px solid #ddd; 156 border-radius: 3px; 157 padding: 1px 5px; 158 letter-spacing: 0.04em; 159 color: #1e1e1e; 132 .mf-upgrade-panel .components-button { 133 white-space: normal; 134 height: auto; 135 min-height: 36px; 160 136 } 161 137 162 .mf-pro-panel__list { 163 list-style: disc; 164 margin: 0 0 12px; 165 padding: 0 0 0 14px; 166 font-size: 0.8rem; 167 color: #757575; 168 line-height: 1.2; 169 } 170 171 .mf-pro-panel__list li { 172 margin: 0; 173 margin-bottom: 6px; 174 } 175 176 .mf-pro-panel .components-button { 177 width: 100%; 178 justify-content: center; 179 margin: 8px 0; 180 } 181 182 .mf-pro-panel .components-button:last-child { 183 margin-bottom: 0; 184 } 185 186 .mf-pro-panel__disclaimer { 187 margin: 8px 0 0; 188 font-size: 0.72rem; 189 color: #949494; 190 text-align: center; 138 .mf-upgrade-panel .dashicons-external { 139 font-size: 16px; 140 width: 16px; 141 height: 16px; 142 margin-left: 6px; 143 flex-shrink: 0; 191 144 } 192 145 -
marqueeflow/trunk/build/index.asset.php
r3788849 r3789556 1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => ' 46ea4f9afb782e9b1411');1 <?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'a1a805e7731bf7bed9f7'); -
marqueeflow/trunk/build/index.js
r3788849 r3789556 1 (()=>{"use strict";const e=window.wp.hooks,t=window.wp.blocks, l=window.React,a=window.wp.i18n,r=window.wp.blockEditor,o=window.wp.components,n=window.wp.element,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"marqueeflow/marqueeflow","title":"MarqueeFlow","description":"A lightweight marquee-style slider for continuously scrolling images","category":"media","icon":"format-gallery","keywords":["marquee","slider","carousel","image","scrolling","banner"],"supports":{"html":false,"align":["wide","full"]},"attributes":{"images":{"type":"array","default":[],"items":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"alt":{"type":"string"},"link":{"type":"string"}}}},"speed":{"type":"string","default":"normal","enum":["slow","normal","fast"]},"imageHeight":{"type":"string","default":"medium","enum":["small","medium","large","custom"]},"gap":{"type":"string","default":"normal","enum":["normal","spacious","custom"]},"pauseOnHover":{"type":"boolean","default":false},"direction":{"type":"string","default":"ltr","enum":["ltr","rtl"]},"customHeight":{"type":"number","default":80},"customGap":{"type":"number","default":64},"borderRadius":{"type":"number","default":0},"opacity":{"type":"number","default":100},"fadeEdges":{"type":"boolean","default":false},"grayscale":{"type":"boolean","default":false},"invertGrayscale":{"type":"boolean","default":false},"maxWidth":{"type":"string","default":"normal","enum":["narrow","normal","medium","wide","none"]}},"example":{"attributes":{"images":[{"id":1,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 1"},{"id":2,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 2"},{"id":3,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 3"},{"id":4,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 4"},{"id":5,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 5"},{"id":6,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 6"}],"speed":"normal","imageHeight":"medium"}},"textdomain":"marqueeflow","editorStyle":"file:./editor.css","style":"marqueeflow-style"}');(0,t.registerBlockType)(i.name,{...i,edit:function(t){const{attributes:i,setAttributes:m}=t,u={...t,apiVersion:1},{images:s,speed:d,imageHeight:g,gap:c,pauseOnHover:f,direction:w,maxWidth:p}=i,[h,_]=(0,n.useState)(!1),[q,y]=(0,n.useState)(""),[v,b]=(0,n.useState)(0),[x,E]=(0,n.useState)("mouse"),C=(0,r.useBlockProps)(),N=(0,n.useRef)({active:!1,index:null}),[S,I]=(0,n.useState)(null),k=(0,n.useRef)(null),A=(0,n.useRef)(null),F=e=>{_(!0);const t=function(e,t){const l=new Set,a=e=>{if("number"!=typeof e.id&&("string"!=typeof e.id||!/^\d+$/.test(e.id)))return null;const t=Number(e.id);return Number.isSafeInteger(t)&&t>0?t:null};return e.map(e=>{const r=a(e),o=t.findIndex((t,o)=>{if(l.has(o)||!t||"object"!=typeof t)return!1;const n=a(t);return null!==r?n===r:null===n&&Boolean(e.url)&&t.url===e.url});return-1!==o&&l.add(o),{...-1===o?{}:t[o],id:e.id,url:e.url,alt:e.alt||""}})}(e,s);m({images:t}),b(0),_(!1)};(0,n.useEffect)(()=>{0!==s.length?v>s.length-1&&b(s.length-1):b(0)},[s.length,v]),(0,n.useEffect)(()=>{if(null===A.current)return;const e=A.current;A.current=null,0!==s.length&&P(e)},[s.length]);const $=(e,t)=>{if(t<0||t>=s.length||e===t)return!1;const l=[...s],[a]=l.splice(e,1);return l.splice(t,0,a),m({images:l}),!0},H=(0,n.useCallback)((e,t)=>{e.target.closest(".marqueeflow-editor__remove, [data-marqueeflow-extension-controls]")||(e.stopPropagation(),E("mouse"),b(t),N.current={active:!0,index:t},I(t),e.currentTarget.setPointerCapture(e.pointerId))},[]),R=(0,n.useCallback)(e=>{if(!N.current.active)return;const t=((e,t)=>{if(!k.current)return null;const l=k.current.querySelectorAll(".marqueeflow-editor__thumb");for(let a=0;a<l.length;a++){const r=l[a].getBoundingClientRect();if(e>=r.left&&e<=r.right&&t>=r.top&&t<=r.bottom)return a}return null})(e.clientX,e.clientY),l=N.current.index;null!==t&&t!==l&&$(l,t)&&(N.current.index=t,I(t))},[s]),M=(0,n.useCallback)(()=>{N.current={active:!1,index:null},I(null)},[]),P=e=>{requestAnimationFrame(()=>{const t=k.current?.querySelector(`[data-thumb-index="${e}"]`);t&&t.focus()})},D=e=>{"Tab"!==e.key||e.shiftKey||(e.preventDefault(),E("keyboard"),P(v))},z=function(e){return{imageHeight:["small","medium","large"].includes(e.imageHeight)?e.imageHeight:"medium",gap:["normal","spacious"].includes(e.gap)?e.gap:"normal"}}(i),B={small:40,medium:60,large:80}[z.imageHeight]||60,L=Number.isFinite(i.borderRadius)?Math.trunc(Math.min(100,Math.max(0,i.borderRadius))):0,O={className:(()=>{const e=["marqueeflow",`marqueeflow--${d}`];return e.push(`marqueeflow--height-${z.imageHeight}`),e.push(`marqueeflow--gap-${z.gap}`),"rtl"===w&&e.push("marqueeflow--rtl"),f&&e.push("marqueeflow--pause-hover"),e.push(`marqueeflow--max-width-${p}`),e.join(" ")})(),style:{"--marqueeflow-total-images":s.length,"--marqueeflow-height":`${B}px`,...L>0?{"--marqueeflow-radius":`${L}px`}:{}}},U=(0,e.applyFilters)("marqueeflow.editor.preview",O,u),j="string"==typeof U?.className?U.className:O.className,T=U?.style&&"object"==typeof U.style&&!Array.isArray(U.style)?U.style:O.style;return(0,l.createElement)(l.Fragment,null,(0,l.createElement)(r.InspectorControls,null,(0,l.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,a.__)("Images","marqueeflow"),initialOpen:!0},(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Image Height","marqueeflow"),value:g,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===g?[{label:(0,a.__)("Saved setting (using Medium)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,a.__)("Small (40px)","marqueeflow"),value:"small"},{label:(0,a.__)("Medium (60px)","marqueeflow"),value:"medium"},{label:(0,a.__)("Large (80px)","marqueeflow"),value:"large"}],"imageHeight",u),onChange:e=>m({imageHeight:e}),help:(0,a.__)("Images scale proportionally to the set height","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"imageHeight",u),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Max Image Width","marqueeflow"),value:p,options:[{label:(0,a.__)("Narrow (3× height)","marqueeflow"),value:"narrow"},{label:(0,a.__)("Normal (4× height)","marqueeflow"),value:"normal"},{label:(0,a.__)("Medium (5× height)","marqueeflow"),value:"medium"},{label:(0,a.__)("Wide (6× height)","marqueeflow"),value:"wide"},{label:(0,a.__)("None (no limit)","marqueeflow"),value:"none"}],onChange:e=>m({maxWidth:e}),help:(0,a.__)("Limits how wide a single image can grow. Prevents long horizontal images from dominating the strip.","marqueeflow")}),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Gap Between Images","marqueeflow"),value:c,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===c?[{label:(0,a.__)("Saved setting (using Normal)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,a.__)("Normal","marqueeflow"),value:"normal"},{label:(0,a.__)("Spacious","marqueeflow"),value:"spacious"}],"gap",u),onChange:e=>m({gap:e})}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"gap",u),(0,l.createElement)(o.RangeControl,{label:(0,a.__)("Corner radius (px)","marqueeflow"),value:L,min:0,max:100,onChange:e=>m({borderRadius:null!=e?e:0})}),(0,e.applyFilters)("marqueeflow.editor.appearance",null,u)),(0,l.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,a.__)("Animation","marqueeflow"),initialOpen:!1},(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Speed","marqueeflow"),value:d,options:[{label:(0,a.__)("Slow","marqueeflow"),value:"slow"},{label:(0,a.__)("Normal","marqueeflow"),value:"normal"},{label:(0,a.__)("Fast","marqueeflow"),value:"fast"}],onChange:e=>m({speed:e})}),(0,l.createElement)(o.SelectControl,{label:(0,a.__)("Direction","marqueeflow"),value:w,options:[{label:(0,a.__)("Left to Right","marqueeflow"),value:"ltr"},{label:(0,a.__)("Right to Left","marqueeflow"),value:"rtl"}],onChange:e=>m({direction:e})}),(0,l.createElement)(o.ToggleControl,{label:(0,a.__)("Pause on Hover","marqueeflow"),checked:f,onChange:e=>m({pauseOnHover:e}),help:(0,a.__)("Stop animation when user hovers over the slider","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.animation",null,u)),(0,e.applyFilters)("marqueeflow.editor.inspector",null,u)),(0,l.createElement)("div",{...C},s.length>0&&(0,l.createElement)("div",{className:"marqueeflow-editor__preview"},(0,l.createElement)("span",{className:"marqueeflow-editor__preview-label"},(0,a.__)("Preview","marqueeflow")),(0,l.createElement)("div",{className:j,style:T},["a","b","c"].map((t,a)=>(0,l.createElement)("ul",{key:t,className:"marqueeflow__set","aria-hidden":a>0||void 0,inert:a>0?"":void 0},s.map((r,o)=>(0,l.createElement)("li",{key:`${t}-${o}`,className:"marqueeflow__item"},(0,e.applyFilters)("marqueeflow.editor.image",(0,l.createElement)("img",{src:r.url,alt:r.alt}),r,{...u,index:o,setIndex:a,isDuplicate:a>0}))))))),0===s.length&&(0,l.createElement)(r.MediaUploadCheck,null,(0,l.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:[],render:({open:e})=>(0,l.createElement)(o.Placeholder,{icon:"format-gallery",label:(0,a.__)("MarqueeFlow","marqueeflow"),instructions:(0,a.__)("Add images to create a continuously scrolling marquee.","marqueeflow")},(0,l.createElement)(o.Button,{variant:"primary",onClick:e},(0,a.__)("Select Images","marqueeflow")))})),s.length>0&&(0,l.createElement)("div",{className:"marqueeflow-editor__management",onKeyDownCapture:()=>E("keyboard"),onPointerDownCapture:()=>E("mouse")},h&&(0,l.createElement)(o.Spinner,null),(0,l.createElement)(r.MediaUploadCheck,null,(0,l.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:s.map(e=>e.id),render:({open:e})=>(0,l.createElement)(o.Button,{onClick:e,onKeyDown:D,variant:"primary",style:{marginBottom:"12px"}},(0,a.__)("Edit Images","marqueeflow"))})),s.length<6&&(0,l.createElement)("p",{className:"marqueeflow-editor__hint"},(0,a.__)("For a smooth scrolling effect, we recommend at least 6 images.","marqueeflow")),(0,l.createElement)("p",{style:{fontSize:"0.875rem",margin:"0 0 4px"}},(0,a.__)("Selected images:","marqueeflow")," ",(0,l.createElement)("strong",null,s.length),(0,l.createElement)("span",{id:"marqueeflow-editor-keyboard-hint",style:{color:"#757575",marginLeft:"8px",fontSize:"0.8rem"}},"keyboard"===x?(0,a.__)("← → navigate, ↑ ↓ actions, Shift + ← → reorder","marqueeflow"):(0,a.__)("Drag to reorder","marqueeflow"))),(0,l.createElement)("div",{className:"marqueeflow-editor__sr-only",role:"status","aria-live":"polite"},q),(0,l.createElement)("div",{className:"marqueeflow-editor__grid",ref:k,role:"group","aria-label":(0,a.__)("Reorder images","marqueeflow"),onKeyDownCapture:e=>{const{key:t,shiftKey:l}=e;if("ArrowLeft"!==t&&"ArrowUp"!==t&&"ArrowRight"!==t&&"ArrowDown"!==t)return;if(E("keyboard"),e.target.closest('input, textarea, select, [contenteditable="true"], [data-marqueeflow-extension-controls]'))return;const r=e.target.closest(".marqueeflow-editor__thumb");if(!r)return;const o=Number(r.dataset.thumbIndex);if(Number.isNaN(o))return;const n="ArrowLeft"===t||"ArrowRight"===t,i="ArrowUp"===t||"ArrowDown"===t,m=!!e.target.closest(".marqueeflow-editor__remove");if(n){let r=o;if("ArrowLeft"===t?r=o-1:"ArrowRight"===t&&(r=o+1),e.preventDefault(),e.stopPropagation(),l)return void($(o,r)&&(b(r),y((0,a.sprintf)(/* translators: 1: new position, 2: total number of images */ /* translators: 1: new position, 2: total number of images */2 (0, a.__)("Image moved to position %1$d of %2$d.","marqueeflow"),r+1,s.length)),P(r)));if(r<0||r>=s.length)return;return b(r),void P(r)}i&&(e.preventDefault(),e.stopPropagation(),b(o),m?P(o):requestAnimationFrame(()=>{const e=k.current?.querySelector(`[data-thumb-index="${o}"] .marqueeflow-editor__remove`);e&&e.focus()}))}},s.map((t,r)=>(0,l.createElement)("div",{key:t.id||r,"data-thumb-index":r,className:"marqueeflow-editor__thumb"+(S===r?" is-dragging":""),tabIndex:r===v?0:-1,"aria-label":(0,a.sprintf)((0,a.__)("Image %1$d of %2$d","marqueeflow"),r+1,s.length),"aria-describedby":"marqueeflow-editor-keyboard-hint",onFocus:()=>b(r),onPointerDown:e=>H(e,r),onPointerMove:R,onPointerUp:M,style:{touchAction:"none"}},(0,l.createElement)("img",{src:t.url,alt:t.alt}),((t,a)=>{const r=(0,e.applyFilters)("marqueeflow.editor.imageControls",null,t,{...u,index:a});return null==r?null:(0,l.createElement)("div",{"data-marqueeflow-extension-controls":!0},r)})(t,r),(0,l.createElement)("button",{className:"marqueeflow-editor__remove",onClick:()=>(e=>{const t=s.filter((t,l)=>l!==e),l=0===t.length?null:Math.min(e,t.length-1);A.current=l,m({images:t}),null===l?(b(0),y((0,a.__)("Image removed.","marqueeflow"))):(b(l),y((0,a.sprintf)(/* translators: 1: new focused position, 2: total number of images */ /* translators: 1: new focused position, 2: total number of images */3 (0, a.__)("Image removed. Focus moved to image %1$d of %2$d.","marqueeflow"),l+1,t.length)))})(r),onFocus:()=>b(r),type:"button",tabIndex:-1,"aria-label":(0,a.__)("Remove image","marqueeflow")},"✕")))))))},save:function({attributes:e}){return null}})&&(window.marqueeflowEditorApi=Object.freeze({apiVersion:1,sharedAppearance:!0,sharedLayout:!0,sharedAnimation:!0,blockName:i.name}),(0,e.doAction)("marqueeflow.editor.ready",window.marqueeflowEditorApi))})();1 (()=>{"use strict";const e=window.wp.hooks,t=window.wp.blocks,a=window.React,l=window.wp.i18n,r=window.wp.blockEditor,o=window.wp.components,n=window.wp.element,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"marqueeflow/marqueeflow","title":"MarqueeFlow","description":"A lightweight marquee-style slider for continuously scrolling images","category":"media","icon":"format-gallery","keywords":["marquee","slider","carousel","image","scrolling","banner"],"supports":{"html":false,"align":["wide","full"]},"attributes":{"images":{"type":"array","default":[],"items":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string"},"alt":{"type":"string"},"link":{"type":"string"}}}},"speed":{"type":"string","default":"normal","enum":["slow","normal","fast"]},"imageHeight":{"type":"string","default":"medium","enum":["small","medium","large","custom"]},"gap":{"type":"string","default":"normal","enum":["normal","spacious","custom"]},"pauseOnHover":{"type":"boolean","default":false},"direction":{"type":"string","default":"ltr","enum":["ltr","rtl"]},"customHeight":{"type":"number","default":80},"customGap":{"type":"number","default":64},"borderRadius":{"type":"number","default":0},"opacity":{"type":"number","default":100},"fadeEdges":{"type":"boolean","default":false},"grayscale":{"type":"boolean","default":false},"invertGrayscale":{"type":"boolean","default":false},"maxWidth":{"type":"string","default":"normal","enum":["narrow","normal","medium","wide","none"]}},"example":{"attributes":{"images":[{"id":1,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 1"},{"id":2,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 2"},{"id":3,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 3"},{"id":4,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 4"},{"id":5,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 5"},{"id":6,"url":"data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'120\' height=\'80\' fill=\'%23ddd\'%3E%3Crect width=\'120\' height=\'80\' rx=\'4\'/%3E%3Ctext x=\'60\' y=\'44\' text-anchor=\'middle\' font-size=\'12\' fill=\'%23999\'%3EImage%3C/text%3E%3C/svg%3E","alt":"Image 6"}],"speed":"normal","imageHeight":"medium"}},"textdomain":"marqueeflow","editorStyle":"file:./editor.css","style":"marqueeflow-style"}');(0,t.registerBlockType)(i.name,{...i,edit:function(t){const{attributes:i,setAttributes:m}=t,u={...t,apiVersion:1},{images:s,speed:d,imageHeight:g,gap:c,pauseOnHover:f,direction:p,maxWidth:w}=i,[h,_]=(0,n.useState)(!1),[q,y]=(0,n.useState)(""),[v,b]=(0,n.useState)(0),[x,E]=(0,n.useState)("mouse"),C=(0,r.useBlockProps)(),N=(0,n.useRef)({active:!1,index:null}),[S,k]=(0,n.useState)(null),I=(0,n.useRef)(null),A=(0,n.useRef)(null),F=e=>{_(!0);const t=function(e,t){const a=new Set,l=e=>{if("number"!=typeof e.id&&("string"!=typeof e.id||!/^\d+$/.test(e.id)))return null;const t=Number(e.id);return Number.isSafeInteger(t)&&t>0?t:null};return e.map(e=>{const r=l(e),o=t.findIndex((t,o)=>{if(a.has(o)||!t||"object"!=typeof t)return!1;const n=l(t);return null!==r?n===r:null===n&&Boolean(e.url)&&t.url===e.url});return-1!==o&&a.add(o),{...-1===o?{}:t[o],id:e.id,url:e.url,alt:e.alt||""}})}(e,s);m({images:t}),b(0),_(!1)};(0,n.useEffect)(()=>{0!==s.length?v>s.length-1&&b(s.length-1):b(0)},[s.length,v]),(0,n.useEffect)(()=>{if(null===A.current)return;const e=A.current;A.current=null,0!==s.length&&M(e)},[s.length]);const P=(e,t)=>{if(t<0||t>=s.length||e===t)return!1;const a=[...s],[l]=a.splice(e,1);return a.splice(t,0,l),m({images:a}),!0},$=(0,n.useCallback)((e,t)=>{e.target.closest(".marqueeflow-editor__remove, [data-marqueeflow-extension-controls]")||(e.stopPropagation(),E("mouse"),b(t),N.current={active:!0,index:t},k(t),e.currentTarget.setPointerCapture(e.pointerId))},[]),H=(0,n.useCallback)(e=>{if(!N.current.active)return;const t=((e,t)=>{if(!I.current)return null;const a=I.current.querySelectorAll(".marqueeflow-editor__thumb");for(let l=0;l<a.length;l++){const r=a[l].getBoundingClientRect();if(e>=r.left&&e<=r.right&&t>=r.top&&t<=r.bottom)return l}return null})(e.clientX,e.clientY),a=N.current.index;null!==t&&t!==a&&P(a,t)&&(N.current.index=t,k(t))},[s]),R=(0,n.useCallback)(()=>{N.current={active:!1,index:null},k(null)},[]),M=e=>{requestAnimationFrame(()=>{const t=I.current?.querySelector(`[data-thumb-index="${e}"]`);t&&t.focus()})},D=e=>{"Tab"!==e.key||e.shiftKey||(e.preventDefault(),E("keyboard"),M(v))},B=function(e){return{imageHeight:["small","medium","large"].includes(e.imageHeight)?e.imageHeight:"medium",gap:["normal","spacious"].includes(e.gap)?e.gap:"normal"}}(i),z={small:40,medium:60,large:80}[B.imageHeight]||60,O=globalThis?.marqueeflowUpgrade,L=!0===O?.show&&"string"==typeof O.url&&/^https:\/\//.test(O.url),U=Number.isFinite(i.borderRadius)?Math.trunc(Math.min(100,Math.max(0,i.borderRadius))):0,T={className:(()=>{const e=["marqueeflow",`marqueeflow--${d}`];return e.push(`marqueeflow--height-${B.imageHeight}`),e.push(`marqueeflow--gap-${B.gap}`),"rtl"===p&&e.push("marqueeflow--rtl"),f&&e.push("marqueeflow--pause-hover"),e.push(`marqueeflow--max-width-${w}`),e.join(" ")})(),style:{"--marqueeflow-total-images":s.length,"--marqueeflow-height":`${z}px`,...U>0?{"--marqueeflow-radius":`${U}px`}:{}}},j=(0,e.applyFilters)("marqueeflow.editor.preview",T,u),K="string"==typeof j?.className?j.className:T.className,W=j?.style&&"object"==typeof j.style&&!Array.isArray(j.style)?j.style:T.style;return(0,a.createElement)(a.Fragment,null,(0,a.createElement)(r.InspectorControls,null,L&&(0,a.createElement)(o.PanelBody,{className:"mf-upgrade-panel",title:(0,l.__)("MarqueeFlow Pro","marqueeflow"),initialOpen:!0},(0,a.createElement)("p",null,(0,l.__)("Add custom image sizing and spacing, fade edges, opacity and grayscale effects with the Pro add-on.","marqueeflow")),(0,a.createElement)(o.Button,{variant:"primary",href:O.url,target:"_blank",rel:"noopener noreferrer"},(0,l.__)("See Pro plans","marqueeflow"),(0,a.createElement)("span",{className:"dashicons dashicons-external","aria-hidden":"true"}),(0,a.createElement)("span",{className:"marqueeflow-editor__sr-only"},(0,l.__)(" (opens in a new tab)","marqueeflow")))),(0,a.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,l.__)("Images","marqueeflow"),initialOpen:!0},(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Image Height","marqueeflow"),value:g,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===g?[{label:(0,l.__)("Saved setting (using Medium)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,l.__)("Small (40px)","marqueeflow"),value:"small"},{label:(0,l.__)("Medium (60px)","marqueeflow"),value:"medium"},{label:(0,l.__)("Large (80px)","marqueeflow"),value:"large"}],"imageHeight",u),onChange:e=>m({imageHeight:e}),help:(0,l.__)("Images scale proportionally to the set height","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"imageHeight",u),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Max Image Width","marqueeflow"),value:w,options:[{label:(0,l.__)("Narrow (3× height)","marqueeflow"),value:"narrow"},{label:(0,l.__)("Normal (4× height)","marqueeflow"),value:"normal"},{label:(0,l.__)("Medium (5× height)","marqueeflow"),value:"medium"},{label:(0,l.__)("Wide (6× height)","marqueeflow"),value:"wide"},{label:(0,l.__)("None (no limit)","marqueeflow"),value:"none"}],onChange:e=>m({maxWidth:e}),help:(0,l.__)("Limits how wide a single image can grow. Prevents long horizontal images from dominating the strip.","marqueeflow")}),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Gap Between Images","marqueeflow"),value:c,options:(0,e.applyFilters)("marqueeflow.editor.layoutOptions",[..."custom"===c?[{label:(0,l.__)("Saved setting (using Normal)","marqueeflow"),value:"custom",disabled:!0}]:[],{label:(0,l.__)("Normal","marqueeflow"),value:"normal"},{label:(0,l.__)("Spacious","marqueeflow"),value:"spacious"}],"gap",u),onChange:e=>m({gap:e})}),(0,e.applyFilters)("marqueeflow.editor.layoutControl",null,"gap",u),(0,a.createElement)(o.RangeControl,{label:(0,l.__)("Corner radius (px)","marqueeflow"),value:U,min:0,max:100,onChange:e=>m({borderRadius:null!=e?e:0})}),(0,e.applyFilters)("marqueeflow.editor.appearance",null,u)),(0,a.createElement)(o.PanelBody,{className:"marqueeflow-inspector-panel",title:(0,l.__)("Animation","marqueeflow"),initialOpen:!1},(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Speed","marqueeflow"),value:d,options:[{label:(0,l.__)("Slow","marqueeflow"),value:"slow"},{label:(0,l.__)("Normal","marqueeflow"),value:"normal"},{label:(0,l.__)("Fast","marqueeflow"),value:"fast"}],onChange:e=>m({speed:e})}),(0,a.createElement)(o.SelectControl,{label:(0,l.__)("Direction","marqueeflow"),value:p,options:[{label:(0,l.__)("Left to Right","marqueeflow"),value:"ltr"},{label:(0,l.__)("Right to Left","marqueeflow"),value:"rtl"}],onChange:e=>m({direction:e})}),(0,a.createElement)(o.ToggleControl,{label:(0,l.__)("Pause on Hover","marqueeflow"),checked:f,onChange:e=>m({pauseOnHover:e}),help:(0,l.__)("Stop animation when user hovers over the slider","marqueeflow")}),(0,e.applyFilters)("marqueeflow.editor.animation",null,u)),(0,e.applyFilters)("marqueeflow.editor.inspector",null,u)),(0,a.createElement)("div",{...C},s.length>0&&(0,a.createElement)("div",{className:"marqueeflow-editor__preview"},(0,a.createElement)("span",{className:"marqueeflow-editor__preview-label"},(0,l.__)("Preview","marqueeflow")),(0,a.createElement)("div",{className:K,style:W},["a","b","c"].map((t,l)=>(0,a.createElement)("ul",{key:t,className:"marqueeflow__set","aria-hidden":l>0||void 0,inert:l>0?"":void 0},s.map((r,o)=>(0,a.createElement)("li",{key:`${t}-${o}`,className:"marqueeflow__item"},(0,e.applyFilters)("marqueeflow.editor.image",(0,a.createElement)("img",{src:r.url,alt:r.alt}),r,{...u,index:o,setIndex:l,isDuplicate:l>0}))))))),0===s.length&&(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:[],render:({open:e})=>(0,a.createElement)(o.Placeholder,{icon:"format-gallery",label:(0,l.__)("MarqueeFlow","marqueeflow"),instructions:(0,l.__)("Add images to create a continuously scrolling marquee.","marqueeflow")},(0,a.createElement)(o.Button,{variant:"primary",onClick:e},(0,l.__)("Select Images","marqueeflow")))})),s.length>0&&(0,a.createElement)("div",{className:"marqueeflow-editor__management",onKeyDownCapture:()=>E("keyboard"),onPointerDownCapture:()=>E("mouse")},h&&(0,a.createElement)(o.Spinner,null),(0,a.createElement)(r.MediaUploadCheck,null,(0,a.createElement)(r.MediaUpload,{onSelect:F,allowedTypes:["image"],multiple:!0,value:s.map(e=>e.id),render:({open:e})=>(0,a.createElement)(o.Button,{onClick:e,onKeyDown:D,variant:"primary",style:{marginBottom:"12px"}},(0,l.__)("Edit Images","marqueeflow"))})),s.length<6&&(0,a.createElement)("p",{className:"marqueeflow-editor__hint"},(0,l.__)("For a smooth scrolling effect, we recommend at least 6 images.","marqueeflow")),(0,a.createElement)("p",{style:{fontSize:"0.875rem",margin:"0 0 4px"}},(0,l.__)("Selected images:","marqueeflow")," ",(0,a.createElement)("strong",null,s.length),(0,a.createElement)("span",{id:"marqueeflow-editor-keyboard-hint",style:{color:"#757575",marginLeft:"8px",fontSize:"0.8rem"}},"keyboard"===x?(0,l.__)("← → navigate, ↑ ↓ actions, Shift + ← → reorder","marqueeflow"):(0,l.__)("Drag to reorder","marqueeflow"))),(0,a.createElement)("div",{className:"marqueeflow-editor__sr-only",role:"status","aria-live":"polite"},q),(0,a.createElement)("div",{className:"marqueeflow-editor__grid",ref:I,role:"group","aria-label":(0,l.__)("Reorder images","marqueeflow"),onKeyDownCapture:e=>{const{key:t,shiftKey:a}=e;if("ArrowLeft"!==t&&"ArrowUp"!==t&&"ArrowRight"!==t&&"ArrowDown"!==t)return;if(E("keyboard"),e.target.closest('input, textarea, select, [contenteditable="true"], [data-marqueeflow-extension-controls]'))return;const r=e.target.closest(".marqueeflow-editor__thumb");if(!r)return;const o=Number(r.dataset.thumbIndex);if(Number.isNaN(o))return;const n="ArrowLeft"===t||"ArrowRight"===t,i="ArrowUp"===t||"ArrowDown"===t,m=!!e.target.closest(".marqueeflow-editor__remove");if(n){let r=o;if("ArrowLeft"===t?r=o-1:"ArrowRight"===t&&(r=o+1),e.preventDefault(),e.stopPropagation(),a)return void(P(o,r)&&(b(r),y((0,l.sprintf)(/* translators: 1: new position, 2: total number of images */ /* translators: 1: new position, 2: total number of images */ 2 (0,l.__)("Image moved to position %1$d of %2$d.","marqueeflow"),r+1,s.length)),M(r)));if(r<0||r>=s.length)return;return b(r),void M(r)}i&&(e.preventDefault(),e.stopPropagation(),b(o),m?M(o):requestAnimationFrame(()=>{const e=I.current?.querySelector(`[data-thumb-index="${o}"] .marqueeflow-editor__remove`);e&&e.focus()}))}},s.map((t,r)=>(0,a.createElement)("div",{key:t.id||r,"data-thumb-index":r,className:"marqueeflow-editor__thumb"+(S===r?" is-dragging":""),tabIndex:r===v?0:-1,"aria-label":(0,l.sprintf)((0,l.__)("Image %1$d of %2$d","marqueeflow"),r+1,s.length),"aria-describedby":"marqueeflow-editor-keyboard-hint",onFocus:()=>b(r),onPointerDown:e=>$(e,r),onPointerMove:H,onPointerUp:R,style:{touchAction:"none"}},(0,a.createElement)("img",{src:t.url,alt:t.alt}),((t,l)=>{const r=(0,e.applyFilters)("marqueeflow.editor.imageControls",null,t,{...u,index:l});return null==r?null:(0,a.createElement)("div",{"data-marqueeflow-extension-controls":!0},r)})(t,r),(0,a.createElement)("button",{className:"marqueeflow-editor__remove",onClick:()=>(e=>{const t=s.filter((t,a)=>a!==e),a=0===t.length?null:Math.min(e,t.length-1);A.current=a,m({images:t}),null===a?(b(0),y((0,l.__)("Image removed.","marqueeflow"))):(b(a),y((0,l.sprintf)(/* translators: 1: new focused position, 2: total number of images */ /* translators: 1: new focused position, 2: total number of images */ 3 (0,l.__)("Image removed. Focus moved to image %1$d of %2$d.","marqueeflow"),a+1,t.length)))})(r),onFocus:()=>b(r),type:"button",tabIndex:-1,"aria-label":(0,l.__)("Remove image","marqueeflow")},"✕")))))))},save:function({attributes:e}){return null}})&&(window.marqueeflowEditorApi=Object.freeze({apiVersion:1,sharedAppearance:!0,sharedLayout:!0,sharedAnimation:!0,blockName:i.name}),(0,e.doAction)("marqueeflow.editor.ready",window.marqueeflowEditorApi))})(); -
marqueeflow/trunk/includes/class-mf-block-marqueeflow.php
r3788849 r3789556 56 56 57 57 wp_set_script_translations( 'marqueeflow-block-editor', 'marqueeflow' ); 58 wp_add_inline_script( 59 'marqueeflow-block-editor', 60 'window.marqueeflowUpgrade = ' . wp_json_encode( [ 61 'show' => ! class_exists( 'MarqueeFlow_Pro_Plugin', false ), 62 'url' => esc_url_raw( MARQUEEFLOW_PRO_URL ), 63 ] ) . ';', 64 'before' 65 ); 58 66 59 67 } -
marqueeflow/trunk/marqueeflow.php
r3788849 r3789556 4 4 * Plugin URI: https://wordpress.org/plugins/marqueeflow/ 5 5 * Description: A lightweight marquee-style slider for continuously scrolling images. 6 * Version: 1.0. 26 * Version: 1.0.3 7 7 * Author: tupacan 8 8 * Author URI: https://profiles.wordpress.org/tupacan/ … … 110 110 private static ?MarqueeFlow_Plugin $instance = null; 111 111 112 public const VERSION = '1.0. 2';112 public const VERSION = '1.0.3'; 113 113 public const SLUG = 'marqueeflow'; 114 114 … … 129 129 130 130 add_action( 'plugins_loaded', [ $this, 'init' ] ); 131 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ $this, 'add_action_links' ] ); 131 132 } 132 133 … … 151 152 } 152 153 154 /** Promotion describes the add-on; it never enables paid behavior. */ 155 public function add_action_links( array $links ): array { 156 if ( class_exists( 'MarqueeFlow_Pro_Plugin', false ) ) { 157 return $links; 158 } 159 $links[] = '<a href="' . esc_url( MARQUEEFLOW_PRO_URL ) . '" target="_blank" rel="noopener noreferrer">' . 160 esc_html__( 'See Pro plans', 'marqueeflow' ) . '</a>'; 161 return $links; 162 } 163 153 164 public function init(): void { 154 165 MarqueeFlow_Assets::init(); -
marqueeflow/trunk/readme.txt
r3788849 r3789556 4 4 Requires at least: 6.3 5 5 Tested up to: 7.1 6 Stable tag: 1.0. 26 Stable tag: 1.0.3 7 7 Requires PHP: 8.0 8 8 License: GPLv2 or later … … 23 23 * Max image width control to prevent wide logos from dominating 24 24 * Direction control: Left to Right or Right to Left 25 * Image corner radius 25 26 * Pause on hover 26 27 * Drag-and-drop image reordering in the editor … … 36 37 3. Adjust speed, height, and style in the sidebar 37 38 4. Publish 39 40 = MarqueeFlow Pro add-on = 41 42 For custom image height and spacing, faded edges, image opacity and grayscale effects, see [MarqueeFlow Pro plans](https://marqueeflow.pages.dev/). Pro is a separate paid add-on and requires this Free plugin to stay installed and active. An eligible activated license is required for paid controls and effects. Free works independently without a license or Freemius SDK. 38 43 39 44 == Installation == … … 68 73 == Changelog == 69 74 75 = 1.0.3 = 76 * Add a compact Pro plans panel in the block sidebar and a plugin-row pricing link. 77 * Hide Free promotion when the separate Pro add-on is active. 78 * Keep all Free controls and frontend behavior unchanged. 79 70 80 = 1.0.2 = 71 81 * Reorganized block settings into Images and Animation panels. -
marqueeflow/trunk/src/blocks/marqueeflow/edit.js
r3788849 r3789556 263 263 }; 264 264 265 const upgrade = globalThis?.marqueeflowUpgrade; 266 const showUpgrade = upgrade?.show === true && typeof upgrade.url === 'string' && /^https:\/\//.test( upgrade.url ); 267 265 268 const radius = Number.isFinite( attributes.borderRadius ) ? Math.trunc( Math.min( 100, Math.max( 0, attributes.borderRadius ) ) ) : 0; 266 269 const basePreview = { … … 280 283 <> 281 284 <InspectorControls> 285 { showUpgrade && ( 286 <PanelBody className="mf-upgrade-panel" title={ __( 'MarqueeFlow Pro', 'marqueeflow' ) } initialOpen={ true }> 287 <p>{ __( 'Add custom image sizing and spacing, fade edges, opacity and grayscale effects with the Pro add-on.', 'marqueeflow' ) }</p> 288 <Button variant="primary" href={ upgrade.url } target="_blank" rel="noopener noreferrer"> 289 { __( 'See Pro plans', 'marqueeflow' ) } 290 <span className="dashicons dashicons-external" aria-hidden="true" /> 291 <span className="marqueeflow-editor__sr-only">{ __( ' (opens in a new tab)', 'marqueeflow' ) }</span> 292 </Button> 293 </PanelBody> 294 ) } 295 282 296 <PanelBody className="marqueeflow-inspector-panel" title={ __( 'Images', 'marqueeflow' ) } initialOpen={ true }> 283 297 <SelectControl
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)