Changeset 3465978
- Timestamp:
- 02/20/2026 06:05:53 PM (5 weeks ago)
- Location:
- theme-image-block
- Files:
-
- 28 added
- 18 edited
- 1 copied
-
tags/1.1.1 (copied) (copied from theme-image-block/trunk)
-
tags/1.1.1/LICENSE (modified) (1 diff)
-
tags/1.1.1/blocks/build/theme-image/index.asset.php (modified) (1 diff)
-
tags/1.1.1/blocks/build/theme-image/index.js (modified) (1 diff)
-
tags/1.1.1/blocks/src/theme-image/block.json (modified) (1 diff)
-
tags/1.1.1/blocks/src/theme-image/index.js (modified) (10 diffs)
-
tags/1.1.1/composer.json (modified) (2 diffs)
-
tags/1.1.1/eslint.config.mjs (added)
-
tags/1.1.1/readme.txt (modified) (2 diffs)
-
tags/1.1.1/src/Block.php (modified) (2 diffs)
-
tags/1.1.1/theme-image-block.php (modified) (1 diff)
-
tags/1.1.1/vendor (added)
-
tags/1.1.1/vendor/autoload.php (added)
-
tags/1.1.1/vendor/composer (added)
-
tags/1.1.1/vendor/composer/ClassLoader.php (added)
-
tags/1.1.1/vendor/composer/InstalledVersions.php (added)
-
tags/1.1.1/vendor/composer/LICENSE (added)
-
tags/1.1.1/vendor/composer/autoload_classmap.php (added)
-
tags/1.1.1/vendor/composer/autoload_namespaces.php (added)
-
tags/1.1.1/vendor/composer/autoload_psr4.php (added)
-
tags/1.1.1/vendor/composer/autoload_real.php (added)
-
tags/1.1.1/vendor/composer/autoload_static.php (added)
-
tags/1.1.1/vendor/composer/installed.json (added)
-
tags/1.1.1/vendor/composer/installed.php (added)
-
trunk/LICENSE (modified) (1 diff)
-
trunk/blocks/build/theme-image/index.asset.php (modified) (1 diff)
-
trunk/blocks/build/theme-image/index.js (modified) (1 diff)
-
trunk/blocks/src/theme-image/block.json (modified) (1 diff)
-
trunk/blocks/src/theme-image/index.js (modified) (10 diffs)
-
trunk/composer.json (modified) (2 diffs)
-
trunk/eslint.config.mjs (added)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/Block.php (modified) (2 diffs)
-
trunk/theme-image-block.php (modified) (1 diff)
-
trunk/vendor (added)
-
trunk/vendor/autoload.php (added)
-
trunk/vendor/composer (added)
-
trunk/vendor/composer/ClassLoader.php (added)
-
trunk/vendor/composer/InstalledVersions.php (added)
-
trunk/vendor/composer/LICENSE (added)
-
trunk/vendor/composer/autoload_classmap.php (added)
-
trunk/vendor/composer/autoload_namespaces.php (added)
-
trunk/vendor/composer/autoload_psr4.php (added)
-
trunk/vendor/composer/autoload_real.php (added)
-
trunk/vendor/composer/autoload_static.php (added)
-
trunk/vendor/composer/installed.json (added)
-
trunk/vendor/composer/installed.php (added)
Legend:
- Unmodified
- Added
- Removed
-
theme-image-block/tags/1.1.1/LICENSE
r3421447 r3465978 1 1 Theme Image Block - a plugin for WordPress 2 2 3 Copyright 2025 by Happy Prime3 Copyright 2025-2026 by Happy Prime 4 4 5 5 This program is free software; you can redistribute it and/or modify -
theme-image-block/tags/1.1.1/blocks/build/theme-image/index.asset.php
r3421447 r3465978 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => ' a084c1de89a76e2f384a');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '38acce586dd7a3df84e2'); -
theme-image-block/tags/1.1.1/blocks/build/theme-image/index.js
r3421447 r3465978 1 (()=>{"use strict";const e=window.wp.blockEditor,t=window.wp.blocks,l=window.wp.components,a=window.wp.i18n,n=window.wp.element,o=window.wp.primitives,i=window.ReactJSXRuntime;var c=(0,i.jsx)(o.SVG,{ viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(o.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v8.4l-3-2.9c-.3-.3-.8-.3-1 0L11.9 14 9 12c-.3-.2-.6-.2-.8 0l-3.6 2.6V5c-.1-.3.1-.5.4-.5zm14 15H5c-.3 0-.5-.2-.5-.5v-2.4l4.1-3 3 1.9c.3.2.7.2.9-.1L16 12l3.5 3.4V19c0 .3-.2.5-.5.5z"})}),m=(0,i.jsx)(o.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(o.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M6 5.5h12a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H6a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5ZM4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Zm4 10h2v-1.5H8V16Zm5 0h-2v-1.5h2V16Zm1 0h2v-1.5h-2V16Z"})});const r=JSON.parse('{"UU":"happyprime/theme-image"}');(0,t.registerBlockType)(r.UU,{edit:function({attributes:t,setAttributes:o}){const{themeImage:i,imageSize:r,imageStyle:s,inlineSVG:h,linkUrl:g,linkTarget:p,linkRel:b,caption:k,showCaption:u,altText:_,omitAltText:d}=t,[v,w]=(0,n.useState)(null),[R,f]=(0,n.useState)(!1),S=happyprime_themeimageblock_data?.images||[],y=happyprime_themeimageblock_data?.styles||[],T=[{value:"",label:(0,a.__)("Select an image","theme-image-block")},...S.map(e=>({value:e.slug,label:e.label}))],C=S.find(e=>e.slug===i),E=[{value:"original",label:(0,a.__)("Original","theme-image-block")}];C&&C.variations&&Object.keys(C.variations).forEach(e=>{const t=C.variations[e];E.push({value:e,label:t.name||e})});let x=C?.value||"";C&&"original"!==r&&C.variations&&C.variations[r]&&(x=C.variations[r].path),(0,n.useEffect)(()=>{if(h&&x&&x.toLowerCase().endsWith(".svg")){const e=`${happyprimeData.themeUrl}/${x}`;fetch(e).then(e=>e.text()).then(e=>{w(e)}).catch(e=>{console.error("Failed to fetch SVG:",e),w(null)})}else w(null)},[h,x]);const V=(0,e.useBlockProps)({className:h?"has-inline-svg":""}),I=x&&happyprimeData?.themeUrl?`${happyprimeData.themeUrl}/${x}`:"",U=x&&x.toLowerCase().endsWith(".svg"),B=y.find(e=>e.slug===s),$=B?.width||"",j=B?.height||"";let A,L=null;if(h&&v){const e=[];$?e.push(`width: ${$}`):$||e.push("width: 100%"),j&&e.push(`height: ${j}`);const t=e.join("; "),l=v.match(/<svg([^>]*)>/);if(l){const e=l[1].match(/style="([^"]*)"/);if(e){const l=e[1];L=v.replace(/<svg([^>]*)>/,e=>e.replace(/style="[^"]*"/,`style="${l}; ${t}"`))}else L=v.replace(/<svg([^>]*)>/,`<svg$1 style="${t}">`)}}if(I)if(h&&L)A=g?React.createElement("a",{href:g,target:p,rel:b,dangerouslySetInnerHTML:{__html:L}}):null;else{const e={};$&&(e.width=$),j&&(e.height=j);const t=React.createElement("img",{src:I,alt:C?.alt||(0,a.__)("Theme image preview","theme-image-block"),style:Object.keys(e).length>0?e:void 0});A=g?React.createElement("a",{href:g,target:p,rel:b},t):t}else A=React.createElement(l.Placeholder,{icon:React.createElement(e.BlockIcon,{icon:c}),label:(0,a.__)("Theme Image","theme-image-block"),instructions:(0,a.__)("Select an image from the block settings","theme-image-block")});const O=h&&L&&!g?{...V,dangerouslySetInnerHTML:{__html:L}}:V;return React.createElement(React.Fragment,null,I&&React.createElement(e.BlockControls,{group:"block"},React.createElement(l.ToolbarButton,{icon:"admin-links",label:(0,a.__)("Link","theme-image-block"),onClick:()=>f(!0),isActive:!!g}),g&&React.createElement(l.ToolbarButton,{icon:"editor-unlink",label:(0,a.__)("Unlink","theme-image-block"),onClick:()=>{o({linkUrl:"",linkTarget:"",linkRel:""})}}),React.createElement(l.ToolbarButton,{icon:m,label:(0,a.__)("Add caption","theme-image-block"),onClick:()=>o({showCaption:!u}),isActive:u})),R&&React.createElement(l.Popover,{position:"bottom center",onClose:()=>f(!1),anchor:document.querySelector(".wp-block-happyprime-theme-image")},React.createElement(e.__experimentalLinkControl,{value:{url:g,opensInNewTab:"_blank"===p,nofollow:b?.includes("nofollow")},onChange:e=>{const t=[];e?.opensInNewTab&&t.push("noopener","noreferrer"),e?.nofollow&&t.push("nofollow"),o({linkUrl:e?.url||"",linkTarget:e?.opensInNewTab?"_blank":"",linkRel:t.join(" ")})},onRemove:()=>{o({linkUrl:"",linkTarget:"",linkRel:""}),f(!1)},settings:[{id:"opensInNewTab",title:(0,a.__)("Open in new tab","theme-image-block")},{id:"nofollow",title:(0,a.__)("Mark as nofollow","theme-image-block")}]})),React.createElement(e.InspectorControls,null,React.createElement(l.PanelBody,{title:(0,a.__)("Settings","theme-image-block"),initialOpen:!0},React.createElement(l.SelectControl,{label:(0,a.__)("Theme Image","theme-image-block"),value:i,options:T,onChange:e=>{o({themeImage:e,imageSize:"original"})},help:(0,a.__)("Select a registered theme image.","theme-image-block")}),C&&C.variations&&Object.keys(C.variations).length>0&&React.createElement(l.SelectControl,{label:(0,a.__)("Variation","theme-image-block"),value:r,options:E,onChange:e=>o({imageSize:e}),help:(0,a.__)("Select the image variation.","theme-image-block")}),React.createElement(l.SelectControl,{label:(0,a.__)("Style","theme-image-block"),value:s,options:[{value:"",label:(0,a.__)("Default","theme-image-block")},...y.map(e=>({value:e.slug,label:e.name}))],onChange:e=>o({imageStyle:e}),help:(0,a.__)("Select a registered style to apply.","theme-image-block")}),U&&React.createElement(l.ToggleControl,{label:(0,a.__)("Inline SVG","theme-image-block"),checked:h,onChange:e=>o({inlineSVG:e}),help:(0,a.__)("Render SVG code inline.","theme-image-block")}),!d&&React.createElement(l.TextControl,{label:(0,a.__)("Alt Text","theme-image-block"),value:_,onChange:e=>o({altText:e}),placeholder:C?.alt||"",help:(0,a.__)("Alternative text for the image. Leave empty to use the registered default.","theme-image-block")}),React.createElement(l.ToggleControl,{label:(0,a.__)("Omit alt text","theme-image-block"),checked:d,onChange:e=>o({omitAltText:e}),help:(0,a.__)("Output empty alt text, even if a registered value exists.","theme-image-block")}))),React.createElement("figure",O,A,I&&u&&React.createElement(e.RichText,{tagName:"figcaption",placeholder:C?.caption||(0,a.__)("Add caption…","theme-image-block"),value:k,onChange:e=>o({caption:e}),allowedFormats:["core/bold","core/italic","core/link"]})))}})})();1 (()=>{"use strict";const e=window.wp.blockEditor,t=window.wp.blocks,l=window.wp.components,a=window.wp.i18n,n=window.wp.element,o=window.wp.primitives,i=window.ReactJSXRuntime;var c=(0,i.jsx)(o.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(o.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v8.4l-3-2.9c-.3-.3-.8-.3-1 0L11.9 14 9 12c-.3-.2-.6-.2-.8 0l-3.6 2.6V5c-.1-.3.1-.5.4-.5zm14 15H5c-.3 0-.5-.2-.5-.5v-2.4l4.1-3 3 1.9c.3.2.7.2.9-.1L16 12l3.5 3.4V19c0 .3-.2.5-.5.5z"})}),m=(0,i.jsx)(o.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(o.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M6 5.5h12a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H6a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5ZM4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Zm4 10h2v-1.5H8V16Zm5 0h-2v-1.5h2V16Zm1 0h2v-1.5h-2V16Z"})});const r=JSON.parse('{"UU":"happyprime/theme-image"}');(0,t.registerBlockType)(r.UU,{edit:function({attributes:t,setAttributes:o}){const{themeImage:i,imageSize:r,imageStyle:s,inlineSVG:h,linkUrl:g,linkTarget:p,linkRel:b,caption:k,showCaption:_,altText:u,omitAltText:d}=t,[v,w]=(0,n.useState)(null),[R,f]=(0,n.useState)(!1),y=(0,n.useRef)(),S=happyprime_themeimageblock_data?.images||[],E=happyprime_themeimageblock_data?.styles||[],C=[{value:"",label:(0,a.__)("Select an image","theme-image-block")},...S.map(e=>({value:e.slug,label:e.label}))],T=S.find(e=>e.slug===i),x=[{value:"original",label:(0,a.__)("Original","theme-image-block")}];T&&T.variations&&Object.keys(T.variations).forEach(e=>{const t=T.variations[e];x.push({value:e,label:t.name||e})});let V=T?.value||"";T&&"original"!==r&&T.variations&&T.variations[r]&&(V=T.variations[r].path),(0,n.useEffect)(()=>{if(h&&V&&V.toLowerCase().endsWith(".svg")){const e=`${happyprime_themeimageblock_data.themeUrl}/${V}`;fetch(e).then(e=>e.text()).then(e=>{w(e)}).catch(e=>{console.error("Failed to fetch SVG:",e),w(null)})}else w(null)},[h,V]);const I=(0,e.useBlockProps)({ref:y,className:h?"has-inline-svg":""}),U=V&&happyprime_themeimageblock_data?.themeUrl?`${happyprime_themeimageblock_data.themeUrl}/${V}`:"",B=V&&V.toLowerCase().endsWith(".svg"),$=E.find(e=>e.slug===s),j=$?.width||"",A=$?.height||"";let O,L=null;if(h&&v){const e=[];j&&e.push(`width: ${j}`),A&&e.push(`height: ${A}`);const t=e.join("; "),l=v.match(/<svg([^>]*)>/);if(l){const e=l[1].match(/style="([^"]*)"/);if(e){const l=e[1];L=v.replace(/<svg([^>]*)>/,e=>e.replace(/style="[^"]*"/,`style="${l}; ${t}"`))}else L=v.replace(/<svg([^>]*)>/,`<svg$1 style="${t}">`)}}if(U)if(h&&L){const e=React.createElement("span",{dangerouslySetInnerHTML:{__html:L},style:{display:"contents"}});O=g?React.createElement("a",{href:g,target:p,rel:b},e):e}else{const e={};j&&(e.width=j),A&&(e.height=A);const t=d?"":u||T?.alt||"",l=React.createElement("img",{src:U,alt:t,style:Object.keys(e).length>0?e:void 0});O=g?React.createElement("a",{href:g,target:p,rel:b},l):l}else O=React.createElement(l.Placeholder,{icon:React.createElement(e.BlockIcon,{icon:c}),label:(0,a.__)("Theme Image","theme-image-block"),instructions:(0,a.__)("Select an image from the block settings","theme-image-block")});const G=I;return React.createElement(React.Fragment,null,U&&React.createElement(e.BlockControls,{group:"block"},React.createElement(l.ToolbarButton,{icon:"admin-links",label:(0,a.__)("Link","theme-image-block"),onClick:()=>f(!0),isActive:!!g}),g&&React.createElement(l.ToolbarButton,{icon:"editor-unlink",label:(0,a.__)("Unlink","theme-image-block"),onClick:()=>{o({linkUrl:"",linkTarget:"",linkRel:""})}}),React.createElement(l.ToolbarButton,{icon:m,label:(0,a.__)("Add caption","theme-image-block"),onClick:()=>o({showCaption:!_}),isActive:_})),R&&React.createElement(l.Popover,{position:"bottom center",onClose:()=>f(!1),anchor:y.current},React.createElement(e.__experimentalLinkControl,{value:{url:g,opensInNewTab:"_blank"===p,nofollow:b?.includes("nofollow")},onChange:e=>{const t=[];e?.opensInNewTab&&t.push("noopener","noreferrer"),e?.nofollow&&t.push("nofollow"),o({linkUrl:e?.url||"",linkTarget:e?.opensInNewTab?"_blank":"",linkRel:t.join(" ")})},onRemove:()=>{o({linkUrl:"",linkTarget:"",linkRel:""}),f(!1)},settings:[{id:"opensInNewTab",title:(0,a.__)("Open in new tab","theme-image-block")},{id:"nofollow",title:(0,a.__)("Mark as nofollow","theme-image-block")}]})),React.createElement(e.InspectorControls,null,React.createElement(l.PanelBody,{title:(0,a.__)("Settings","theme-image-block"),initialOpen:!0},React.createElement(l.SelectControl,{label:(0,a.__)("Theme Image","theme-image-block"),value:i,options:C,onChange:e=>{o({themeImage:e,imageSize:"original"})},help:(0,a.__)("Select a registered theme image.","theme-image-block")}),T&&T.variations&&Object.keys(T.variations).length>0&&React.createElement(l.SelectControl,{label:(0,a.__)("Variation","theme-image-block"),value:r,options:x,onChange:e=>o({imageSize:e}),help:(0,a.__)("Select the image variation.","theme-image-block")}),React.createElement(l.SelectControl,{label:(0,a.__)("Style","theme-image-block"),value:s,options:[{value:"",label:(0,a.__)("Default","theme-image-block")},...E.map(e=>({value:e.slug,label:e.name}))],onChange:e=>o({imageStyle:e}),help:(0,a.__)("Select a registered style to apply.","theme-image-block")}),B&&React.createElement(l.ToggleControl,{label:(0,a.__)("Inline SVG","theme-image-block"),checked:h,onChange:e=>o({inlineSVG:e}),help:(0,a.__)("Render SVG code inline.","theme-image-block")}),!d&&React.createElement(l.TextControl,{label:(0,a.__)("Alt Text","theme-image-block"),value:u,onChange:e=>o({altText:e}),placeholder:T?.alt||"",help:(0,a.__)("Alternative text for the image. Leave empty to use the registered default.","theme-image-block")}),React.createElement(l.ToggleControl,{label:(0,a.__)("Omit alt text","theme-image-block"),checked:d,onChange:e=>o({omitAltText:e}),help:(0,a.__)("Output empty alt text, even if a registered value exists.","theme-image-block")}))),React.createElement("figure",G,O,U&&_&&React.createElement(e.RichText,{tagName:"figcaption",placeholder:T?.caption||(0,a.__)("Add caption…","theme-image-block"),value:k,onChange:e=>o({caption:e}),allowedFormats:["core/bold","core/italic","core/link"]})))}})})(); -
theme-image-block/tags/1.1.1/blocks/src/theme-image/block.json
r3421447 r3465978 66 66 } 67 67 }, 68 "textdomain": " happyprime",68 "textdomain": "theme-image-block", 69 69 "editorScript": "file:../../build/theme-image/index.js", 70 70 "style": "file:./style.css" -
theme-image-block/tags/1.1.1/blocks/src/theme-image/index.js
r3421447 r3465978 21 21 } from '@wordpress/components'; 22 22 import { __ } from '@wordpress/i18n'; 23 import { useState, useEffect } from '@wordpress/element';23 import { useState, useEffect, useRef } from '@wordpress/element'; 24 24 import { image, caption as captionIcon } from '@wordpress/icons'; 25 25 … … 53 53 const [svgContent, setSvgContent] = useState(null); 54 54 const [isEditingLink, setIsEditingLink] = useState(false); 55 const blockRef = useRef(); 55 56 56 57 // Get registered theme images and styles from localized data. … … 105 106 imagePath.toLowerCase().endsWith('.svg') 106 107 ) { 107 const svgUrl = `${happyprime Data.themeUrl}/${imagePath}`;108 const svgUrl = `${happyprime_themeimageblock_data.themeUrl}/${imagePath}`; 108 109 fetch(svgUrl) 109 110 .then((response) => response.text()) … … 121 122 122 123 const blockProps = useBlockProps({ 124 ref: blockRef, 123 125 className: inlineSVG ? 'has-inline-svg' : '', 124 126 }); 125 127 126 128 const imageUrl = 127 imagePath && happyprime Data?.themeUrl128 ? `${happyprime Data.themeUrl}/${imagePath}`129 imagePath && happyprime_themeimageblock_data?.themeUrl 130 ? `${happyprime_themeimageblock_data.themeUrl}/${imagePath}` 129 131 : ''; 130 132 const isSVG = imagePath && imagePath.toLowerCase().endsWith('.svg'); … … 144 146 if (width) { 145 147 styles.push(`width: ${width}`); 146 } else if (!width) {147 // Default width for editor preview when not specified.148 styles.push('width: 100%');149 148 } 150 149 if (height) { … … 194 193 // For inline SVG, apply dangerouslySetInnerHTML to link or wrapper 195 194 // to match server-side structure without extra figure wrapper. 195 const svgElement = ( 196 <span 197 dangerouslySetInnerHTML={{ __html: processedSvg }} 198 style={{ display: 'contents' }} 199 /> 200 ); 196 201 if (linkUrl) { 197 202 content = ( 198 <a 199 href={linkUrl} 200 target={linkTarget} 201 rel={linkRel} 202 dangerouslySetInnerHTML={{ __html: processedSvg }} 203 /> 203 <a href={linkUrl} target={linkTarget} rel={linkRel}> 204 {svgElement} 205 </a> 204 206 ); 205 207 } else { 206 // Will be applied to wrapper figure via blockProps below. 207 content = null; 208 content = svgElement; 208 209 } 209 210 } else { … … 217 218 } 218 219 220 const editorAlt = omitAltText ? '' : altText || currentImage?.alt || ''; 221 219 222 const img = ( 220 223 <img 221 224 src={imageUrl} 222 alt={ 223 currentImage?.alt || 224 __('Theme image preview', 'theme-image-block') 225 } 225 alt={editorAlt} 226 226 style={ 227 227 Object.keys(imgStyles).length > 0 ? imgStyles : undefined … … 238 238 } 239 239 240 // For inline SVG without link, apply HTML directly to wrapper. 241 const wrapperProps = 242 inlineSVG && processedSvg && !linkUrl 243 ? { 244 ...blockProps, 245 dangerouslySetInnerHTML: { __html: processedSvg }, 246 } 247 : blockProps; 240 const wrapperProps = blockProps; 248 241 249 242 return ( … … 273 266 icon={captionIcon} 274 267 label={__('Add caption', 'theme-image-block')} 275 onClick={() => setAttributes({ showCaption: !showCaption })} 268 onClick={() => 269 setAttributes({ showCaption: !showCaption }) 270 } 276 271 isActive={showCaption} 277 272 /> … … 283 278 position="bottom center" 284 279 onClose={() => setIsEditingLink(false)} 285 anchor={document.querySelector( 286 '.wp-block-happyprime-theme-image' 287 )} 280 anchor={blockRef.current} 288 281 > 289 282 <LinkControl -
theme-image-block/tags/1.1.1/composer.json
r3421447 r3465978 14 14 } 15 15 }, 16 "repositories": [ 17 { 18 "type": "package", 19 "package": { 20 "name": "phpcompatibility/php-compatibility", 21 "type": "phpcodesniffer-standard", 22 "version": "9.99.9", 23 "source": { 24 "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", 25 "type": "git", 26 "reference": "9f7142356b5674164a6f6dbe12a7a1bcc632db21" 27 } 28 } 29 } 30 ], 16 31 "autoload": { 17 32 "psr-4": { … … 21 36 "require-dev": { 22 37 "happyprime/coding-standards": "*", 23 "phpcompatibility/php-compatibility": " dev-develop as 9.99.99"38 "phpcompatibility/php-compatibility": "9.99.9" 24 39 }, 25 40 "scripts": { -
theme-image-block/tags/1.1.1/readme.txt
r3423224 r3465978 4 4 Requires at least: 6.8 5 5 Tested up to: 6.9 6 Stable tag: 1.1. 06 Stable tag: 1.1.1 7 7 License: GPLv2 or later 8 8 Requires PHP: 7.4 … … 76 76 ## Changelog 77 77 78 ### 1.1.1 79 80 * Prevent fatal error on activation. 81 * Improve HTML processing when rendering output. 82 * Fix reference to renamed global JavaScript variable. 83 * Fix textdomain mismatch. 84 * Improve support for multiple theme image blocks in one editor view. 85 78 86 ### 1.1.0 79 87 -
theme-image-block/tags/1.1.1/src/Block.php
r3421447 r3465978 181 181 if ( $link_url ) { 182 182 $content = '<a>' . $content . '</a>'; 183 184 $html = new \WP_HTML_Tag_Processor( $content ); 185 if ( $html->next_tag( array( 'tag_name' => 'a' ) ) ) { 186 $html->set_attribute( 'href', $link_url ); 187 if ( $link_target ) { 188 $html->set_attribute( 'target', $link_target ); 189 } 190 if ( $link_rel ) { 191 $html->set_attribute( 'rel', $link_rel ); 192 } 193 } 194 195 $content = $html->get_updated_html(); 183 196 } 184 197 185 198 $html = new \WP_HTML_Tag_Processor( $content ); 186 if ( $html->next_tag( array( 'tag_name' => 'a' ) ) ) {187 $html->set_attribute( 'href', $link_url );188 if ( $link_target ) {189 $html->set_attribute( 'target', $link_target );190 }191 if ( $link_rel ) {192 $html->set_attribute( 'rel', $link_rel );193 }194 }195 196 // This seems to be the best way to rewind and seek again? Seems strange.197 $html = new \WP_HTML_Tag_Processor( $html->get_updated_html() );198 199 199 200 if ( $html->next_tag( array( 'tag_name' => 'img' ) ) ) { … … 218 219 } 219 220 220 $wrapper_attrs = array( 'class' => implode( ' ', $wrapper_classes ) ); 221 $wrapper_attrs = ! empty( $wrapper_classes ) 222 ? array( 'class' => implode( ' ', $wrapper_classes ) ) 223 : array(); 221 224 222 225 return sprintf( -
theme-image-block/tags/1.1.1/theme-image-block.php
r3421447 r3465978 3 3 * Plugin Name: Theme Image Block 4 4 * Description: Use images from your theme as blocks in content. 5 * Version: 1.1. 05 * Version: 1.1.1 6 6 * Author: Happy Prime 7 7 * Author URI: https://happyprime.co -
theme-image-block/trunk/LICENSE
r3421447 r3465978 1 1 Theme Image Block - a plugin for WordPress 2 2 3 Copyright 2025 by Happy Prime3 Copyright 2025-2026 by Happy Prime 4 4 5 5 This program is free software; you can redistribute it and/or modify -
theme-image-block/trunk/blocks/build/theme-image/index.asset.php
r3421447 r3465978 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => ' a084c1de89a76e2f384a');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '38acce586dd7a3df84e2'); -
theme-image-block/trunk/blocks/build/theme-image/index.js
r3421447 r3465978 1 (()=>{"use strict";const e=window.wp.blockEditor,t=window.wp.blocks,l=window.wp.components,a=window.wp.i18n,n=window.wp.element,o=window.wp.primitives,i=window.ReactJSXRuntime;var c=(0,i.jsx)(o.SVG,{ viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(o.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v8.4l-3-2.9c-.3-.3-.8-.3-1 0L11.9 14 9 12c-.3-.2-.6-.2-.8 0l-3.6 2.6V5c-.1-.3.1-.5.4-.5zm14 15H5c-.3 0-.5-.2-.5-.5v-2.4l4.1-3 3 1.9c.3.2.7.2.9-.1L16 12l3.5 3.4V19c0 .3-.2.5-.5.5z"})}),m=(0,i.jsx)(o.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(o.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M6 5.5h12a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H6a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5ZM4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Zm4 10h2v-1.5H8V16Zm5 0h-2v-1.5h2V16Zm1 0h2v-1.5h-2V16Z"})});const r=JSON.parse('{"UU":"happyprime/theme-image"}');(0,t.registerBlockType)(r.UU,{edit:function({attributes:t,setAttributes:o}){const{themeImage:i,imageSize:r,imageStyle:s,inlineSVG:h,linkUrl:g,linkTarget:p,linkRel:b,caption:k,showCaption:u,altText:_,omitAltText:d}=t,[v,w]=(0,n.useState)(null),[R,f]=(0,n.useState)(!1),S=happyprime_themeimageblock_data?.images||[],y=happyprime_themeimageblock_data?.styles||[],T=[{value:"",label:(0,a.__)("Select an image","theme-image-block")},...S.map(e=>({value:e.slug,label:e.label}))],C=S.find(e=>e.slug===i),E=[{value:"original",label:(0,a.__)("Original","theme-image-block")}];C&&C.variations&&Object.keys(C.variations).forEach(e=>{const t=C.variations[e];E.push({value:e,label:t.name||e})});let x=C?.value||"";C&&"original"!==r&&C.variations&&C.variations[r]&&(x=C.variations[r].path),(0,n.useEffect)(()=>{if(h&&x&&x.toLowerCase().endsWith(".svg")){const e=`${happyprimeData.themeUrl}/${x}`;fetch(e).then(e=>e.text()).then(e=>{w(e)}).catch(e=>{console.error("Failed to fetch SVG:",e),w(null)})}else w(null)},[h,x]);const V=(0,e.useBlockProps)({className:h?"has-inline-svg":""}),I=x&&happyprimeData?.themeUrl?`${happyprimeData.themeUrl}/${x}`:"",U=x&&x.toLowerCase().endsWith(".svg"),B=y.find(e=>e.slug===s),$=B?.width||"",j=B?.height||"";let A,L=null;if(h&&v){const e=[];$?e.push(`width: ${$}`):$||e.push("width: 100%"),j&&e.push(`height: ${j}`);const t=e.join("; "),l=v.match(/<svg([^>]*)>/);if(l){const e=l[1].match(/style="([^"]*)"/);if(e){const l=e[1];L=v.replace(/<svg([^>]*)>/,e=>e.replace(/style="[^"]*"/,`style="${l}; ${t}"`))}else L=v.replace(/<svg([^>]*)>/,`<svg$1 style="${t}">`)}}if(I)if(h&&L)A=g?React.createElement("a",{href:g,target:p,rel:b,dangerouslySetInnerHTML:{__html:L}}):null;else{const e={};$&&(e.width=$),j&&(e.height=j);const t=React.createElement("img",{src:I,alt:C?.alt||(0,a.__)("Theme image preview","theme-image-block"),style:Object.keys(e).length>0?e:void 0});A=g?React.createElement("a",{href:g,target:p,rel:b},t):t}else A=React.createElement(l.Placeholder,{icon:React.createElement(e.BlockIcon,{icon:c}),label:(0,a.__)("Theme Image","theme-image-block"),instructions:(0,a.__)("Select an image from the block settings","theme-image-block")});const O=h&&L&&!g?{...V,dangerouslySetInnerHTML:{__html:L}}:V;return React.createElement(React.Fragment,null,I&&React.createElement(e.BlockControls,{group:"block"},React.createElement(l.ToolbarButton,{icon:"admin-links",label:(0,a.__)("Link","theme-image-block"),onClick:()=>f(!0),isActive:!!g}),g&&React.createElement(l.ToolbarButton,{icon:"editor-unlink",label:(0,a.__)("Unlink","theme-image-block"),onClick:()=>{o({linkUrl:"",linkTarget:"",linkRel:""})}}),React.createElement(l.ToolbarButton,{icon:m,label:(0,a.__)("Add caption","theme-image-block"),onClick:()=>o({showCaption:!u}),isActive:u})),R&&React.createElement(l.Popover,{position:"bottom center",onClose:()=>f(!1),anchor:document.querySelector(".wp-block-happyprime-theme-image")},React.createElement(e.__experimentalLinkControl,{value:{url:g,opensInNewTab:"_blank"===p,nofollow:b?.includes("nofollow")},onChange:e=>{const t=[];e?.opensInNewTab&&t.push("noopener","noreferrer"),e?.nofollow&&t.push("nofollow"),o({linkUrl:e?.url||"",linkTarget:e?.opensInNewTab?"_blank":"",linkRel:t.join(" ")})},onRemove:()=>{o({linkUrl:"",linkTarget:"",linkRel:""}),f(!1)},settings:[{id:"opensInNewTab",title:(0,a.__)("Open in new tab","theme-image-block")},{id:"nofollow",title:(0,a.__)("Mark as nofollow","theme-image-block")}]})),React.createElement(e.InspectorControls,null,React.createElement(l.PanelBody,{title:(0,a.__)("Settings","theme-image-block"),initialOpen:!0},React.createElement(l.SelectControl,{label:(0,a.__)("Theme Image","theme-image-block"),value:i,options:T,onChange:e=>{o({themeImage:e,imageSize:"original"})},help:(0,a.__)("Select a registered theme image.","theme-image-block")}),C&&C.variations&&Object.keys(C.variations).length>0&&React.createElement(l.SelectControl,{label:(0,a.__)("Variation","theme-image-block"),value:r,options:E,onChange:e=>o({imageSize:e}),help:(0,a.__)("Select the image variation.","theme-image-block")}),React.createElement(l.SelectControl,{label:(0,a.__)("Style","theme-image-block"),value:s,options:[{value:"",label:(0,a.__)("Default","theme-image-block")},...y.map(e=>({value:e.slug,label:e.name}))],onChange:e=>o({imageStyle:e}),help:(0,a.__)("Select a registered style to apply.","theme-image-block")}),U&&React.createElement(l.ToggleControl,{label:(0,a.__)("Inline SVG","theme-image-block"),checked:h,onChange:e=>o({inlineSVG:e}),help:(0,a.__)("Render SVG code inline.","theme-image-block")}),!d&&React.createElement(l.TextControl,{label:(0,a.__)("Alt Text","theme-image-block"),value:_,onChange:e=>o({altText:e}),placeholder:C?.alt||"",help:(0,a.__)("Alternative text for the image. Leave empty to use the registered default.","theme-image-block")}),React.createElement(l.ToggleControl,{label:(0,a.__)("Omit alt text","theme-image-block"),checked:d,onChange:e=>o({omitAltText:e}),help:(0,a.__)("Output empty alt text, even if a registered value exists.","theme-image-block")}))),React.createElement("figure",O,A,I&&u&&React.createElement(e.RichText,{tagName:"figcaption",placeholder:C?.caption||(0,a.__)("Add caption…","theme-image-block"),value:k,onChange:e=>o({caption:e}),allowedFormats:["core/bold","core/italic","core/link"]})))}})})();1 (()=>{"use strict";const e=window.wp.blockEditor,t=window.wp.blocks,l=window.wp.components,a=window.wp.i18n,n=window.wp.element,o=window.wp.primitives,i=window.ReactJSXRuntime;var c=(0,i.jsx)(o.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(o.Path,{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v8.4l-3-2.9c-.3-.3-.8-.3-1 0L11.9 14 9 12c-.3-.2-.6-.2-.8 0l-3.6 2.6V5c-.1-.3.1-.5.4-.5zm14 15H5c-.3 0-.5-.2-.5-.5v-2.4l4.1-3 3 1.9c.3.2.7.2.9-.1L16 12l3.5 3.4V19c0 .3-.2.5-.5.5z"})}),m=(0,i.jsx)(o.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(o.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M6 5.5h12a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H6a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5ZM4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Zm4 10h2v-1.5H8V16Zm5 0h-2v-1.5h2V16Zm1 0h2v-1.5h-2V16Z"})});const r=JSON.parse('{"UU":"happyprime/theme-image"}');(0,t.registerBlockType)(r.UU,{edit:function({attributes:t,setAttributes:o}){const{themeImage:i,imageSize:r,imageStyle:s,inlineSVG:h,linkUrl:g,linkTarget:p,linkRel:b,caption:k,showCaption:_,altText:u,omitAltText:d}=t,[v,w]=(0,n.useState)(null),[R,f]=(0,n.useState)(!1),y=(0,n.useRef)(),S=happyprime_themeimageblock_data?.images||[],E=happyprime_themeimageblock_data?.styles||[],C=[{value:"",label:(0,a.__)("Select an image","theme-image-block")},...S.map(e=>({value:e.slug,label:e.label}))],T=S.find(e=>e.slug===i),x=[{value:"original",label:(0,a.__)("Original","theme-image-block")}];T&&T.variations&&Object.keys(T.variations).forEach(e=>{const t=T.variations[e];x.push({value:e,label:t.name||e})});let V=T?.value||"";T&&"original"!==r&&T.variations&&T.variations[r]&&(V=T.variations[r].path),(0,n.useEffect)(()=>{if(h&&V&&V.toLowerCase().endsWith(".svg")){const e=`${happyprime_themeimageblock_data.themeUrl}/${V}`;fetch(e).then(e=>e.text()).then(e=>{w(e)}).catch(e=>{console.error("Failed to fetch SVG:",e),w(null)})}else w(null)},[h,V]);const I=(0,e.useBlockProps)({ref:y,className:h?"has-inline-svg":""}),U=V&&happyprime_themeimageblock_data?.themeUrl?`${happyprime_themeimageblock_data.themeUrl}/${V}`:"",B=V&&V.toLowerCase().endsWith(".svg"),$=E.find(e=>e.slug===s),j=$?.width||"",A=$?.height||"";let O,L=null;if(h&&v){const e=[];j&&e.push(`width: ${j}`),A&&e.push(`height: ${A}`);const t=e.join("; "),l=v.match(/<svg([^>]*)>/);if(l){const e=l[1].match(/style="([^"]*)"/);if(e){const l=e[1];L=v.replace(/<svg([^>]*)>/,e=>e.replace(/style="[^"]*"/,`style="${l}; ${t}"`))}else L=v.replace(/<svg([^>]*)>/,`<svg$1 style="${t}">`)}}if(U)if(h&&L){const e=React.createElement("span",{dangerouslySetInnerHTML:{__html:L},style:{display:"contents"}});O=g?React.createElement("a",{href:g,target:p,rel:b},e):e}else{const e={};j&&(e.width=j),A&&(e.height=A);const t=d?"":u||T?.alt||"",l=React.createElement("img",{src:U,alt:t,style:Object.keys(e).length>0?e:void 0});O=g?React.createElement("a",{href:g,target:p,rel:b},l):l}else O=React.createElement(l.Placeholder,{icon:React.createElement(e.BlockIcon,{icon:c}),label:(0,a.__)("Theme Image","theme-image-block"),instructions:(0,a.__)("Select an image from the block settings","theme-image-block")});const G=I;return React.createElement(React.Fragment,null,U&&React.createElement(e.BlockControls,{group:"block"},React.createElement(l.ToolbarButton,{icon:"admin-links",label:(0,a.__)("Link","theme-image-block"),onClick:()=>f(!0),isActive:!!g}),g&&React.createElement(l.ToolbarButton,{icon:"editor-unlink",label:(0,a.__)("Unlink","theme-image-block"),onClick:()=>{o({linkUrl:"",linkTarget:"",linkRel:""})}}),React.createElement(l.ToolbarButton,{icon:m,label:(0,a.__)("Add caption","theme-image-block"),onClick:()=>o({showCaption:!_}),isActive:_})),R&&React.createElement(l.Popover,{position:"bottom center",onClose:()=>f(!1),anchor:y.current},React.createElement(e.__experimentalLinkControl,{value:{url:g,opensInNewTab:"_blank"===p,nofollow:b?.includes("nofollow")},onChange:e=>{const t=[];e?.opensInNewTab&&t.push("noopener","noreferrer"),e?.nofollow&&t.push("nofollow"),o({linkUrl:e?.url||"",linkTarget:e?.opensInNewTab?"_blank":"",linkRel:t.join(" ")})},onRemove:()=>{o({linkUrl:"",linkTarget:"",linkRel:""}),f(!1)},settings:[{id:"opensInNewTab",title:(0,a.__)("Open in new tab","theme-image-block")},{id:"nofollow",title:(0,a.__)("Mark as nofollow","theme-image-block")}]})),React.createElement(e.InspectorControls,null,React.createElement(l.PanelBody,{title:(0,a.__)("Settings","theme-image-block"),initialOpen:!0},React.createElement(l.SelectControl,{label:(0,a.__)("Theme Image","theme-image-block"),value:i,options:C,onChange:e=>{o({themeImage:e,imageSize:"original"})},help:(0,a.__)("Select a registered theme image.","theme-image-block")}),T&&T.variations&&Object.keys(T.variations).length>0&&React.createElement(l.SelectControl,{label:(0,a.__)("Variation","theme-image-block"),value:r,options:x,onChange:e=>o({imageSize:e}),help:(0,a.__)("Select the image variation.","theme-image-block")}),React.createElement(l.SelectControl,{label:(0,a.__)("Style","theme-image-block"),value:s,options:[{value:"",label:(0,a.__)("Default","theme-image-block")},...E.map(e=>({value:e.slug,label:e.name}))],onChange:e=>o({imageStyle:e}),help:(0,a.__)("Select a registered style to apply.","theme-image-block")}),B&&React.createElement(l.ToggleControl,{label:(0,a.__)("Inline SVG","theme-image-block"),checked:h,onChange:e=>o({inlineSVG:e}),help:(0,a.__)("Render SVG code inline.","theme-image-block")}),!d&&React.createElement(l.TextControl,{label:(0,a.__)("Alt Text","theme-image-block"),value:u,onChange:e=>o({altText:e}),placeholder:T?.alt||"",help:(0,a.__)("Alternative text for the image. Leave empty to use the registered default.","theme-image-block")}),React.createElement(l.ToggleControl,{label:(0,a.__)("Omit alt text","theme-image-block"),checked:d,onChange:e=>o({omitAltText:e}),help:(0,a.__)("Output empty alt text, even if a registered value exists.","theme-image-block")}))),React.createElement("figure",G,O,U&&_&&React.createElement(e.RichText,{tagName:"figcaption",placeholder:T?.caption||(0,a.__)("Add caption…","theme-image-block"),value:k,onChange:e=>o({caption:e}),allowedFormats:["core/bold","core/italic","core/link"]})))}})})(); -
theme-image-block/trunk/blocks/src/theme-image/block.json
r3421447 r3465978 66 66 } 67 67 }, 68 "textdomain": " happyprime",68 "textdomain": "theme-image-block", 69 69 "editorScript": "file:../../build/theme-image/index.js", 70 70 "style": "file:./style.css" -
theme-image-block/trunk/blocks/src/theme-image/index.js
r3421447 r3465978 21 21 } from '@wordpress/components'; 22 22 import { __ } from '@wordpress/i18n'; 23 import { useState, useEffect } from '@wordpress/element';23 import { useState, useEffect, useRef } from '@wordpress/element'; 24 24 import { image, caption as captionIcon } from '@wordpress/icons'; 25 25 … … 53 53 const [svgContent, setSvgContent] = useState(null); 54 54 const [isEditingLink, setIsEditingLink] = useState(false); 55 const blockRef = useRef(); 55 56 56 57 // Get registered theme images and styles from localized data. … … 105 106 imagePath.toLowerCase().endsWith('.svg') 106 107 ) { 107 const svgUrl = `${happyprime Data.themeUrl}/${imagePath}`;108 const svgUrl = `${happyprime_themeimageblock_data.themeUrl}/${imagePath}`; 108 109 fetch(svgUrl) 109 110 .then((response) => response.text()) … … 121 122 122 123 const blockProps = useBlockProps({ 124 ref: blockRef, 123 125 className: inlineSVG ? 'has-inline-svg' : '', 124 126 }); 125 127 126 128 const imageUrl = 127 imagePath && happyprime Data?.themeUrl128 ? `${happyprime Data.themeUrl}/${imagePath}`129 imagePath && happyprime_themeimageblock_data?.themeUrl 130 ? `${happyprime_themeimageblock_data.themeUrl}/${imagePath}` 129 131 : ''; 130 132 const isSVG = imagePath && imagePath.toLowerCase().endsWith('.svg'); … … 144 146 if (width) { 145 147 styles.push(`width: ${width}`); 146 } else if (!width) {147 // Default width for editor preview when not specified.148 styles.push('width: 100%');149 148 } 150 149 if (height) { … … 194 193 // For inline SVG, apply dangerouslySetInnerHTML to link or wrapper 195 194 // to match server-side structure without extra figure wrapper. 195 const svgElement = ( 196 <span 197 dangerouslySetInnerHTML={{ __html: processedSvg }} 198 style={{ display: 'contents' }} 199 /> 200 ); 196 201 if (linkUrl) { 197 202 content = ( 198 <a 199 href={linkUrl} 200 target={linkTarget} 201 rel={linkRel} 202 dangerouslySetInnerHTML={{ __html: processedSvg }} 203 /> 203 <a href={linkUrl} target={linkTarget} rel={linkRel}> 204 {svgElement} 205 </a> 204 206 ); 205 207 } else { 206 // Will be applied to wrapper figure via blockProps below. 207 content = null; 208 content = svgElement; 208 209 } 209 210 } else { … … 217 218 } 218 219 220 const editorAlt = omitAltText ? '' : altText || currentImage?.alt || ''; 221 219 222 const img = ( 220 223 <img 221 224 src={imageUrl} 222 alt={ 223 currentImage?.alt || 224 __('Theme image preview', 'theme-image-block') 225 } 225 alt={editorAlt} 226 226 style={ 227 227 Object.keys(imgStyles).length > 0 ? imgStyles : undefined … … 238 238 } 239 239 240 // For inline SVG without link, apply HTML directly to wrapper. 241 const wrapperProps = 242 inlineSVG && processedSvg && !linkUrl 243 ? { 244 ...blockProps, 245 dangerouslySetInnerHTML: { __html: processedSvg }, 246 } 247 : blockProps; 240 const wrapperProps = blockProps; 248 241 249 242 return ( … … 273 266 icon={captionIcon} 274 267 label={__('Add caption', 'theme-image-block')} 275 onClick={() => setAttributes({ showCaption: !showCaption })} 268 onClick={() => 269 setAttributes({ showCaption: !showCaption }) 270 } 276 271 isActive={showCaption} 277 272 /> … … 283 278 position="bottom center" 284 279 onClose={() => setIsEditingLink(false)} 285 anchor={document.querySelector( 286 '.wp-block-happyprime-theme-image' 287 )} 280 anchor={blockRef.current} 288 281 > 289 282 <LinkControl -
theme-image-block/trunk/composer.json
r3421447 r3465978 14 14 } 15 15 }, 16 "repositories": [ 17 { 18 "type": "package", 19 "package": { 20 "name": "phpcompatibility/php-compatibility", 21 "type": "phpcodesniffer-standard", 22 "version": "9.99.9", 23 "source": { 24 "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", 25 "type": "git", 26 "reference": "9f7142356b5674164a6f6dbe12a7a1bcc632db21" 27 } 28 } 29 } 30 ], 16 31 "autoload": { 17 32 "psr-4": { … … 21 36 "require-dev": { 22 37 "happyprime/coding-standards": "*", 23 "phpcompatibility/php-compatibility": " dev-develop as 9.99.99"38 "phpcompatibility/php-compatibility": "9.99.9" 24 39 }, 25 40 "scripts": { -
theme-image-block/trunk/readme.txt
r3423224 r3465978 4 4 Requires at least: 6.8 5 5 Tested up to: 6.9 6 Stable tag: 1.1. 06 Stable tag: 1.1.1 7 7 License: GPLv2 or later 8 8 Requires PHP: 7.4 … … 76 76 ## Changelog 77 77 78 ### 1.1.1 79 80 * Prevent fatal error on activation. 81 * Improve HTML processing when rendering output. 82 * Fix reference to renamed global JavaScript variable. 83 * Fix textdomain mismatch. 84 * Improve support for multiple theme image blocks in one editor view. 85 78 86 ### 1.1.0 79 87 -
theme-image-block/trunk/src/Block.php
r3421447 r3465978 181 181 if ( $link_url ) { 182 182 $content = '<a>' . $content . '</a>'; 183 184 $html = new \WP_HTML_Tag_Processor( $content ); 185 if ( $html->next_tag( array( 'tag_name' => 'a' ) ) ) { 186 $html->set_attribute( 'href', $link_url ); 187 if ( $link_target ) { 188 $html->set_attribute( 'target', $link_target ); 189 } 190 if ( $link_rel ) { 191 $html->set_attribute( 'rel', $link_rel ); 192 } 193 } 194 195 $content = $html->get_updated_html(); 183 196 } 184 197 185 198 $html = new \WP_HTML_Tag_Processor( $content ); 186 if ( $html->next_tag( array( 'tag_name' => 'a' ) ) ) {187 $html->set_attribute( 'href', $link_url );188 if ( $link_target ) {189 $html->set_attribute( 'target', $link_target );190 }191 if ( $link_rel ) {192 $html->set_attribute( 'rel', $link_rel );193 }194 }195 196 // This seems to be the best way to rewind and seek again? Seems strange.197 $html = new \WP_HTML_Tag_Processor( $html->get_updated_html() );198 199 199 200 if ( $html->next_tag( array( 'tag_name' => 'img' ) ) ) { … … 218 219 } 219 220 220 $wrapper_attrs = array( 'class' => implode( ' ', $wrapper_classes ) ); 221 $wrapper_attrs = ! empty( $wrapper_classes ) 222 ? array( 'class' => implode( ' ', $wrapper_classes ) ) 223 : array(); 221 224 222 225 return sprintf( -
theme-image-block/trunk/theme-image-block.php
r3421447 r3465978 3 3 * Plugin Name: Theme Image Block 4 4 * Description: Use images from your theme as blocks in content. 5 * Version: 1.1. 05 * Version: 1.1.1 6 6 * Author: Happy Prime 7 7 * Author URI: https://happyprime.co
Note: See TracChangeset
for help on using the changeset viewer.