PluginProbe
AI / trunk
AI vtrunk
1.3.0 1.2.0 1.1.0 1.0.2 1.0.1 1.0.0 0.9.0 trunk 0.1.1 0.2.0 0.2.1 0.3.0 0.3.1 0.4.0 0.4.1 0.5.0 0.6.0 0.7.0 0.8.0
ai / build-scripts / experiments / title-generation.js

title-generation.js in AI trunk, at build-scripts/experiments/title-generation.js

2 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (()=>{"use strict";const e={n:t=>{const n=t&&t.__esModule?()=>t.default:()=>t;return e.d(n,{a:n}),n},d:(t,n)=>{if(Array.isArray(n))for(var i=0;i<n.length;){var o=n[i++],r=n[i++];e.o(t,o)?0===r&&i++:0===r?Object.defineProperty(t,o,{enumerable:!0,value:n[i++]}):Object.defineProperty(t,o,{enumerable:!0,get:r})}else for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.hasOwn(e,t)},t=window.wp.blockEditor,n=window.wp.compose,i=window.wp.hooks,o=window.wp.plugins,r=window.wp.components,s=window.wp.data,l=window.wp.editor,a=window.wp.element,c=window.wp.primitives,u=window.ReactJSXRuntime;var d=(0,u.jsx)(c.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(c.Path,{d:"m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"})});const p=window.wp.i18n,w=window.wp.notices,m=window.wp.apiFetch;var f=e.n(m);const b=window.wp.url;let h=!1;const g=()=>{h||(console.warn("[AI] Client ability execution is unavailable. Falling back to REST."),h=!0)},y=(e,t,n)=>{if("GET"===n||"DELETE"===n)return{path:null==t?`/wp-abilities/v1/abilities/${e}/run`:(0,b.addQueryArgs)(`/wp-abilities/v1/abilities/${e}/run`,{input:t}),method:n};const i={path:`/wp-abilities/v1/abilities/${e}/run`,method:"POST"};return void 0!==t&&(i.data={input:t}),i};const _=window.wp.wordcount;const v="ai_title_generation_error",x=()=>{const e=window.aiTitleGenerationData??{};return{enabled:e.enabled??!1,minContentLength:e.minContentLength??250}};async function T(e,t){const n={context:e.toString(),content:t},i=await async function(e,t,n){try{const n=await(async()=>{try{const{ready:e}=await import("@wordpress/core-abilities");return await e,await import("@wordpress/abilities")}catch{return null}})();if("function"==typeof n?.executeAbility)return await n.executeAbility(e,t);g()}catch(e){if(console.error(e),!(e=>{if(!e||"object"!=typeof e)return!1;const t="message"in e&&"string"==typeof e.message?e.message:"",n="code"in e&&"string"==typeof e.code?e.code:"";return"ability_not_found"===n||t.includes("Ability not found")||t.includes("missing callback")||"ability_invalid_input"===n})(e))throw e;g()}const i=n?.method??"POST";return await f()({...y(e,t,i),...n?.signal?{signal:n.signal}:{}})}("ai/title-generation",n);if(i&&"object"==typeof i&&"title"in i&&"string"==typeof i.title&&i.title.length>0)return i.title;throw new Error((0,p.__)("No title suggestion was generated.","ai"))}function j({isStandalone:e=!1}){const{postId:t,title:n,content:i}=(0,s.useSelect)(e=>{const t=e(l.store);return{postId:t.getCurrentPostId(),title:t.getEditedPostAttribute("title"),content:t.getEditedPostContent()}},[]),{editPost:o}=(0,s.useDispatch)(l.store),[c,m]=(0,a.useState)(!1),[f,b]=(0,a.useState)(!1),[h,g]=(0,a.useState)(!1),[y,j]=(0,a.useState)(""),S=(0,a.useRef)(null),E=(0,a.useRef)(null),C=(0,a.useRef)(null);(0,a.useEffect)(()=>()=>{C.current&&clearTimeout(C.current)},[]);const D=()=>{g(!1),j(""),C.current=setTimeout(()=>{C.current=null;const e=S.current?.ownerDocument.querySelector(".editor-post-title__input");e?.focus()},0)},P=n.trim().length>0,{minContentLength:k}=x(),F=!function(e,t){return function(e){return(0,_.count)(e,"characters_excluding_spaces")}(e)>=t}(i,k);let A=(0,p.__)("Generate","ai");c||f?A=(0,p.__)("Generating…","ai"):(P||h)&&(A=(0,p.__)("Regenerate","ai"));const B=(0,p.sprintf)(/* translators: %d: minimum number of characters required. */ /* translators: %d: minimum number of characters required. */
2 (0,p.__)("Title generation will be available when the post content has at least %d characters.","ai"),k),N=F?B:A,L=c||F,O=async()=>{if(!c&&function(e){const t=window.aiProviderData??{hasProvider:!1,connectorsUrl:""};if(t.hasProvider)return!0;const{connectorsUrl:n}=t;return(0,s.dispatch)(w.store).createErrorNotice((0,p.__)("This feature requires an AI Connector to function properly.","ai"),{id:e,isDismissible:!0,actions:n?[{label:(0,p.__)("Manage Connectors","ai"),url:n}]:[]}),!1}(v)){m(!0),(0,s.dispatch)(w.store).removeNotice(v);try{const e=await T(t,i);j(e),g(!0)}catch(e){const t="string"==typeof e?e:e?.message??(0,p.__)("Failed to generate title.","ai");(0,s.dispatch)(w.store).createErrorNotice(t,{id:v,isDismissible:!0})}finally{m(!1)}}};return x().enabled?(0,u.jsxs)(l.PostTypeSupportCheck,{supportKeys:"title",children:[e?(0,u.jsx)(r.Button,{ref:S,icon:d,variant:"secondary",label:N,showTooltip:!0,onClick:O,disabled:L,isBusy:c,accessibleWhenDisabled:!0,__next40pxDefaultSize:!0,children:A}):(0,u.jsx)(r.ToolbarGroup,{children:(0,u.jsx)(r.ToolbarButton,{ref:S,icon:d,label:N,showTooltip:!0,onClick:O,disabled:L,isBusy:c,children:A})}),h&&(0,u.jsxs)(r.Modal,{title:(0,p.__)("Title suggestion","ai"),onRequestClose:D,isFullScreen:!1,focusOnMount:"firstInputElement",size:"medium",className:"ai-title-generation-modal",children:[(0,u.jsx)("p",{className:"ai-title-generation-subtitle",children:(0,p.__)("Review, edit and insert the suggested title or regenerate a new one.","ai")}),(0,u.jsx)(r.TextareaControl,{rows:2,label:(0,p.__)("Generated title","ai"),hideLabelFromVision:!0,value:y,onChange:j,disabled:f,ref:E}),(0,u.jsxs)(r.Flex,{justify:"flex-end",gap:"3",className:"ai-title-generation-actions",children:[(0,u.jsx)(r.FlexItem,{children:(0,u.jsx)(r.Button,{accessibleWhenDisabled:!0,variant:"secondary",onClick:async()=>{b(!0),(0,s.dispatch)(w.store).removeNotice(v);try{const e=await T(t,i);j(e),C.current=setTimeout(()=>{C.current=null,E.current?.focus()},0)}catch(e){const t="string"==typeof e?e:e?.message??(0,p.__)("Failed to generate title.","ai");(0,s.dispatch)(w.store).createErrorNotice(t,{id:v,isDismissible:!0})}finally{b(!1)}},disabled:f,isBusy:f,__next40pxDefaultSize:!0,children:A})}),(0,u.jsx)(r.FlexItem,{children:(0,u.jsx)(r.Button,{variant:"primary",onClick:()=>{o({title:y}),D()},disabled:f||!y,__next40pxDefaultSize:!0,children:(0,p.__)("Insert","ai")})})]})]})]}):null}function S(e,t,n,i=200){let o=0,r=null;const s=()=>{o<n&&(o++,r=setTimeout(()=>{r=null,e()?t():s()},i))};return()=>{r||s()}}function E(e,t,n=10){return{focus:e,blur:()=>{setTimeout(t,n)}}}function C(e,t,n=!1){const i=n?"focusin":"focus",o=n?"focusout":"blur";return e.addEventListener(i,t.focus),e.addEventListener(o,t.blur),()=>{e.removeEventListener(i,t.focus),e.removeEventListener(o,t.blur)}}const D=(0,n.createHigherOrderComponent)(e=>n=>"core/post-title"!==n.name?(0,u.jsx)(e,{...n}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(e,{...n}),(0,u.jsx)(t.BlockControls,{children:(0,u.jsx)(j,{})})]}),"withTitleToolbar");(0,i.addFilter)("editor.BlockEdit","ai/title-generation",D),(0,o.registerPlugin)("ai-title-generation-normal-mode",{render:function(){return(0,a.useEffect)(()=>{let e=!1,t=null,n=null,i=null,o=null,r=null,s=null,l=null;const c=()=>{const e=document.querySelector('iframe[name="editor-canvas"], iframe.wp-block-editor-iframe__iframe');return e&&e.contentDocument?e.contentDocument:null},d=()=>{s&&(s.style.display="flex")},w=()=>{(()=>{const e=c();if(!e)return!1;const t=e.activeElement;return!(!t||t!==r&&!r?.contains(t)&&(!s||t!==s&&!s.contains(t)&&!s.querySelector(".components-dropdown-menu .is-opened")))})()?d():s&&(s.style.display="none")},m=()=>{if(e)return;const o=c();if(!o)return void S(()=>null!==c(),m,20)();if(o.querySelector(".ai-title-toolbar-wrapper"))return void(e=!0);const f=[".editor-post-title__input"];let b=null;for(const e of f)if(b=o.querySelector(e),b)break;if(!b)return void S(()=>{const e=c();return!!e&&!!e.querySelector(".editor-post-title__input")},m,10)();if(r=b,r.closest(".ai-title-toolbar-wrapper"))return void(e=!0);const h=r.parentElement;if(!h)return;const g=r.nextSibling;l=o.createElement("div"),l.className="ai-title-toolbar-wrapper",l.style.cssText="position: relative;",s=o.createElement("div"),s.className="ai-title-toolbar-container",s.setAttribute("role","toolbar"),s.setAttribute("aria-label",(0,p.__)("Generate title toolbar","ai")),s.style.cssText="display: none; position: absolute; z-index: 1000; top: -60px;",l.appendChild(s),l.appendChild(r),h.insertBefore(l,g),t=(0,a.createRoot)(s),t.render((0,u.jsx)(j,{isStandalone:!0}));const y=E(d,w);n=C(r,y);const _=E(d,w);i=C(s,_,!0),o.activeElement===r&&d(),e=!0},f=setTimeout(()=>{m()},100);let b=null,h=0;const g=()=>{if(o)return;const a=c();if(!a||!a.body)return void(h<20&&(h++,b=setTimeout(g,200)));const u=new MutationObserver(()=>{const o=!!a.querySelector(".ai-title-toolbar-wrapper");e&&!o&&(n&&(n(),n=null),i&&(i(),i=null),t&&(t.unmount(),t=null),l&&(l.remove(),l=null),s=null,r=null,e=!1),e||o||m()});u.observe(a.body,{childList:!0,subtree:!0}),o=u},y=setTimeout(g,100);return()=>{o&&o.disconnect(),clearTimeout(f),clearTimeout(y),b&&clearTimeout(b),n&&n(),i&&i(),t&&t.unmount(),l?l.remove():s&&s.remove()}},[]),(0,u.jsx)(u.Fragment,{})}})})();