/** * editor/get-scripts + editor/set-scripts — typed read/patch over a BLOCK's * `spectraCustomJS` attribute (the per-block JS store). `spectraCustomJS` in * post_content is the single source of truth for page behaviour — Spectra Pro's * BlockJsCompiler renders it once at wp_footer (spectra-blocks-pro #165), * superseding the removed per-page `_spectra_blocks_page_scripts` meta. * * SESSION-SCOPED BY DESIGN (the apply_change philosophy): reads come from * `core/block-editor` getBlockAttributes (the live editing session, incl. * unsaved edits) and writes go through updateBlockAttributes — the block's JS * updates in the session immediately, is DISCARDED if the user discards the * session, and persists only on Save. A REST write here would race the open * editor's copy and mutate before save — never do that. * * Target a block by `clientId` (default = the page root container, the first * top-level block — page-wide behaviour). The stored code is raw JS; the * renderer wraps it in an IIFE and resolves the `_current_block_` token to the * block's scope class. */ (function () { // Block-editor store access comes from the ONE shared source // (editor/shared/editor-shared-utils.js): window in the browser, require() // under jest — so the editor handlers can't drift. function sharedEditorUtils() { if (typeof window !== 'undefined' && window.zipwpEditorShared) return window.zipwpEditorShared; if (typeof require === 'function') { try { return require('../shared/editor-shared-utils.js'); } catch (e) { return null; } } return null; } function blockEditorSelect() { var u = sharedEditorUtils(); return u && u.blockEditorSelect ? u.blockEditorSelect() : null; } function blockEditorDispatch() { var u = sharedEditorUtils(); return u && u.blockEditorDispatch ? u.blockEditorDispatch() : null; } function rootClientId(sel) { var u = sharedEditorUtils(); return u && u.rootClientId ? u.rootClientId(sel) : null; } function currentPostId() { var u = sharedEditorUtils(); return u && u.currentPostId ? u.currentPostId() : null; } // The target block: an explicit clientId, else the page root container. function resolveClientId(sel, args) { var cid = args && typeof args.clientId === 'string' && args.clientId !== '' ? args.clientId : null; return cid || rootClientId(sel); } // A block's current spectraCustomJS ('' when unset or the block is gone). function customJsOf(sel, clientId) { var attrs = sel && sel.getBlockAttributes ? sel.getBlockAttributes(clientId) : null; return attrs && typeof attrs.spectraCustomJS === 'string' ? attrs.spectraCustomJS : ''; } function handleGetScripts(args) { var sel = blockEditorSelect(); if (!sel || !sel.getBlockAttributes) { return { success: false, error: 'editor_unavailable: core/block-editor store not present (is the block editor open?)' }; } var clientId = resolveClientId(sel, args); if (!clientId) { return { success: false, error: 'no_block: the page has no blocks to read JS from' }; } return { success: true, data: { post_id: currentPostId(), client_id: clientId, code: customJsOf(sel, clientId), }, }; } // Throws on code the block renderer would reject — typed and loud beats a // silent drop. `