PluginProbe
AI Builder – Generate pages, blocks, images & translate with AI / 2.1.3
AI Builder – Generate pages, blocks, images & translate with AI v2.1.3
2.8.0 2.7.10 2.7.9 2.7.8 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 All 123 releases
ai-builder / assets / js / src / editor-blocks / yt-video / index.js

index.js in AI Builder – Generate pages, blocks, images & translate with AI 2.1.3, at assets/js/src/editor-blocks/yt-video/index.js

150 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 const { registerBlockType } = wp.blocks;
2 const { __ } = wp.i18n;
3 const { TextControl, PanelBody, SelectControl } = wp.components;
4 const { InspectorControls, useBlockProps } = wp.blockEditor || wp.editor;
5
6 function toEmbedUrl(input) {
7 if (!input) return "";
8 try {
9 const url = new URL(input);
10 if (url.hostname.includes("youtu.be")) {
11 return `https://www.youtube.com/embed/${url.pathname.replace("/", "")}`;
12 }
13 if (url.hostname.includes("youtube.com")) {
14 const v = url.searchParams.get("v");
15 if (v) return `https://www.youtube.com/embed/${v}`;
16 // already embed
17 if (url.pathname.startsWith("/embed/")) return url.toString();
18 }
19 } catch (e) {}
20 return input;
21 }
22
23 function computeStyle({ width, align, padding, margin }) {
24 const style = {};
25 if (width) {
26 // Accept values like 100%, 800px, 60ch, etc.
27 style.maxWidth = width;
28 style.width = "100%";
29 }
30 if (padding) style.padding = padding;
31 if (margin) style.margin = margin;
32 if (align === "center") {
33 style.marginLeft = "auto";
34 style.marginRight = "auto";
35 } else if (align === "right") {
36 style.marginLeft = "auto";
37 } // left = default
38 return style;
39 }
40
41 registerBlockType("ai-builder/aibui-yt-video", {
42 title: __("YouTube Video (AI Builder)", "ai-builder"),
43 icon: "video-alt3",
44 category: "widgets",
45 supports: { align: ["wide", "full"], html: false },
46 attributes: {
47 url: { type: "string", default: "" },
48 title: { type: "string", default: "" },
49 width: { type: "string", default: "100%" },
50 align: { type: "string", default: "center" }, // left | center | right
51 padding: { type: "string", default: "" },
52 margin: { type: "string", default: "" },
53 },
54 edit: (props) => {
55 const { attributes, setAttributes } = props;
56 const { url, title, width, align, padding, margin } = attributes;
57 const blockProps = useBlockProps({ className: "aibui-yt" });
58 const embed = toEmbedUrl(url);
59 const wrapStyle = computeStyle({ width, align, padding, margin });
60 return (
61 <div {...blockProps}>
62 <InspectorControls>
63 <PanelBody title={__("Settings", "ai-builder")} initialOpen>
64 <TextControl
65 label={__("YouTube URL", "ai-builder")}
66 value={url}
67 onChange={(v) => setAttributes({ url: v })}
68 placeholder="https://www.youtube.com/watch?v=..."
69 />
70 <TextControl
71 label={__("Title (optional)", "ai-builder")}
72 value={title}
73 onChange={(v) => setAttributes({ title: v })}
74 />
75 <TextControl
76 label={__("Max width", "ai-builder")}
77 value={width}
78 onChange={(v) => setAttributes({ width: v })}
79 help={__("Any CSS size (e.g. 100%, 800px, 60ch)", "ai-builder")}
80 />
81 <SelectControl
82 label={__("Align", "ai-builder")}
83 value={align}
84 options={[
85 { label: __("Left", "ai-builder"), value: "left" },
86 { label: __("Center", "ai-builder"), value: "center" },
87 { label: __("Right", "ai-builder"), value: "right" },
88 ]}
89 onChange={(v) => setAttributes({ align: v })}
90 />
91 <TextControl
92 label={__("Padding (optional)", "ai-builder")}
93 value={padding}
94 onChange={(v) => setAttributes({ padding: v })}
95 placeholder="e.g. 12px 16px"
96 />
97 <TextControl
98 label={__("Margin (optional)", "ai-builder")}
99 value={margin}
100 onChange={(v) => setAttributes({ margin: v })}
101 placeholder="e.g. 20px auto"
102 />
103 </PanelBody>
104 </InspectorControls>
105 {title ? <h3 className="aibui-yt-title">{title}</h3> : null}
106 {embed ? (
107 <div className="aibui-yt-wrap" style={wrapStyle}>
108 <iframe
109 src={embed}
110 title={title || "YouTube video"}
111 frameBorder="0"
112 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
113 allowFullScreen
114 ></iframe>
115 </div>
116 ) : (
117 <div className="aibui-yt-placeholder">
118 {__("Paste a YouTube URL in settings", "ai-builder")}
119 </div>
120 )}
121 </div>
122 );
123 },
124 save: (props) => {
125 const { attributes } = props;
126 const { url, title, width, align, padding, margin } = attributes;
127 const embed = toEmbedUrl(url);
128 const blockProps = wp.blockEditor
129 ? wp.blockEditor.useBlockProps.save({ className: "aibui-yt" })
130 : {};
131 const wrapStyle = computeStyle({ width, align, padding, margin });
132 return (
133 <div {...blockProps}>
134 {title ? <h3 className="aibui-yt-title">{title}</h3> : null}
135 {embed ? (
136 <div className="aibui-yt-wrap" style={wrapStyle}>
137 <iframe
138 src={embed}
139 title={title || "YouTube video"}
140 frameBorder="0"
141 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
142 allowFullScreen
143 ></iframe>
144 </div>
145 ) : null}
146 </div>
147 );
148 },
149 });
150