{
  "version": 3,
  "sources": ["../../../src/components/post-preview-button/index.js"],
  "sourcesContent": ["import { renderToString } from '@wordpress/element';\nimport { Button, MenuItem, Path, SVG } from '@wordpress/components';\nimport { __, _x } from '@wordpress/i18n';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { applyFilters } from '@wordpress/hooks';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { external } from '@wordpress/icons';\nimport { VisuallyHidden } from '@wordpress/ui';\nimport { store as editorStore } from '../../store';\n\nfunction buildInterstitialMarkup() {\n\tlet markup = renderToString(\n\t\t<div className=\"editor-post-preview-button__interstitial-message\">\n\t\t\t<SVG xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\">\n\t\t\t\t<Path\n\t\t\t\t\tclassName=\"outer\"\n\t\t\t\t\td=\"M48 12c19.9 0 36 16.1 36 36S67.9 84 48 84 12 67.9 12 48s16.1-36 36-36\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t/>\n\t\t\t\t<Path\n\t\t\t\t\tclassName=\"inner\"\n\t\t\t\t\td=\"M69.5 46.4c0-3.9-1.4-6.7-2.6-8.8-1.6-2.6-3.1-4.9-3.1-7.5 0-2.9 2.2-5.7 5.4-5.7h.4C63.9 19.2 56.4 16 48 16c-11.2 0-21 5.7-26.7 14.4h2.1c3.3 0 8.5-.4 8.5-.4 1.7-.1 1.9 2.4.2 2.6 0 0-1.7.2-3.7.3L40 67.5l7-20.9L42 33c-1.7-.1-3.3-.3-3.3-.3-1.7-.1-1.5-2.7.2-2.6 0 0 5.3.4 8.4.4 3.3 0 8.5-.4 8.5-.4 1.7-.1 1.9 2.4.2 2.6 0 0-1.7.2-3.7.3l11.5 34.3 3.3-10.4c1.6-4.5 2.4-7.8 2.4-10.5zM16.1 48c0 12.6 7.3 23.5 18 28.7L18.8 35c-1.7 4-2.7 8.4-2.7 13zm32.5 2.8L39 78.6c2.9.8 5.9 1.3 9 1.3 3.7 0 7.3-.6 10.6-1.8-.1-.1-.2-.3-.2-.4l-9.8-26.9zM76.2 36c0 3.2-.6 6.9-2.4 11.4L64 75.6c9.5-5.5 15.9-15.8 15.9-27.6 0-5.5-1.4-10.8-3.9-15.3.1 1 .2 2.1.2 3.3z\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t/>\n\t\t\t</SVG>\n\t\t\t<p>{ __( 'Generating preview…' ) }</p>\n\t\t</div>\n\t);\n\n\tmarkup += `\n\t\t<style>\n\t\t\tbody {\n\t\t\t\tmargin: 0;\n\t\t\t}\n\t\t\t.editor-post-preview-button__interstitial-message {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\twidth: 100vw;\n\t\t\t}\n\t\t\t@-webkit-keyframes paint {\n\t\t\t\t0% {\n\t\t\t\t\tstroke-dashoffset: 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t@-moz-keyframes paint {\n\t\t\t\t0% {\n\t\t\t\t\tstroke-dashoffset: 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t@-o-keyframes paint {\n\t\t\t\t0% {\n\t\t\t\t\tstroke-dashoffset: 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t@keyframes paint {\n\t\t\t\t0% {\n\t\t\t\t\tstroke-dashoffset: 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t.editor-post-preview-button__interstitial-message svg {\n\t\t\t\twidth: 192px;\n\t\t\t\theight: 192px;\n\t\t\t\tstroke: #555d66;\n\t\t\t\tstroke-width: 0.75;\n\t\t\t}\n\t\t\t.editor-post-preview-button__interstitial-message svg .outer,\n\t\t\t.editor-post-preview-button__interstitial-message svg .inner {\n\t\t\t\tstroke-dasharray: 280;\n\t\t\t\tstroke-dashoffset: 280;\n\t\t\t\t-webkit-animation: paint 1.5s ease infinite alternate;\n\t\t\t\t-moz-animation: paint 1.5s ease infinite alternate;\n\t\t\t\t-o-animation: paint 1.5s ease infinite alternate;\n\t\t\t\tanimation: paint 1.5s ease infinite alternate;\n\t\t\t}\n\t\t\tp {\n\t\t\t\ttext-align: center;\n\t\t\t\tfont-family: -apple-system, system-ui, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\n\t\t\t}\n\t\t</style>\n\t`;\n\n\t/**\n\t * Filters the interstitial message shown when generating previews.\n\t *\n\t * @param {string} markup The preview interstitial markup.\n\t */\n\tmarkup = applyFilters( 'editor.PostPreview.interstitialMarkup', markup );\n\n\treturn markup;\n}\n\nfunction writeInterstitialMessage( targetDocument, markup ) {\n\ttargetDocument.write( markup );\n\ttargetDocument.title = __( 'Generating preview…' );\n\ttargetDocument.close();\n}\n\n/**\n * Resolves the preview window's `document`, working around\n * `Document-Isolation-Policy` (DIP) isolation.\n *\n * The editor screen is served with `Document-Isolation-Policy:\n * isolate-and-credentialless` to enable cross-origin isolation. This places the\n * editor tab and an already-open preview tab in separate agent clusters, so\n * synchronous access to a reused preview tab's `document` throws a\n * `SecurityError`. Navigating the reused tab back to `about:blank` returns it to\n * the opener's agent cluster and restores access. That navigation is\n * asynchronous and we can't attach a cross-isolation `load` listener, so poll\n * the `document` access (the operation that throws) until it succeeds, up to a\n * short timeout.\n *\n * @param {Window} previewWindow The preview window/tab.\n *\n * @return {?Document} The reachable preview document, or `null` if it never\n *                     becomes reachable within the timeout.\n */\nasync function getPreviewDocument( previewWindow ) {\n\t// A freshly opened tab is already on `about:blank` and accessible, so this\n\t// succeeds on the first preview without any reset.\n\ttry {\n\t\treturn previewWindow.document;\n\t} catch {\n\t\t// The reused preview tab is isolated from the editor; reset it below.\n\t}\n\n\tpreviewWindow.location = 'about:blank';\n\n\tconst timeoutMs = 1000;\n\tconst intervalMs = 50;\n\tconst deadline = Date.now() + timeoutMs;\n\tdo {\n\t\tawait new Promise( ( resolve ) => setTimeout( resolve, intervalMs ) );\n\t\ttry {\n\t\t\treturn previewWindow.document;\n\t\t} catch {\n\t\t\t// Navigation to `about:blank` hasn't completed yet; keep polling.\n\t\t}\n\t} while ( Date.now() < deadline );\n\n\treturn null;\n}\n\n/**\n * Writes the preview interstitial into the preview window, working around\n * `Document-Isolation-Policy` (DIP) isolation.\n *\n * The interstitial is a progressive enhancement: if the document never becomes\n * reachable we simply skip it, and the caller still navigates the preview to the\n * real content.\n *\n * @param {Window} previewWindow The preview window/tab.\n */\nasync function writeInterstitialIntoPreviewWindow( previewWindow ) {\n\tconst previewDocument = await getPreviewDocument( previewWindow );\n\tif ( previewDocument ) {\n\t\twriteInterstitialMessage( previewDocument, buildInterstitialMarkup() );\n\t}\n}\n\nfunction usePostPreviewProps( { forceIsAutosaveable, onPreview } ) {\n\tconst { postId, currentPostLink, previewLink, isSaveable, isViewable } =\n\t\tuseSelect( ( select ) => {\n\t\t\tconst editor = select( editorStore );\n\t\t\tconst core = select( coreStore );\n\n\t\t\tconst postType = core.getPostType(\n\t\t\t\teditor.getCurrentPostType( 'type' )\n\t\t\t);\n\t\t\tconst canView = postType?.viewable ?? false;\n\t\t\tif ( ! canView ) {\n\t\t\t\treturn { isViewable: canView };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tpostId: editor.getCurrentPostId(),\n\t\t\t\tcurrentPostLink: editor.getCurrentPostAttribute( 'link' ),\n\t\t\t\tpreviewLink: editor.getEditedPostPreviewLink(),\n\t\t\t\tisSaveable: editor.isEditedPostSaveable(),\n\t\t\t\tisViewable: canView,\n\t\t\t};\n\t\t}, [] );\n\n\tconst { __unstableSaveForPreview } = useDispatch( editorStore );\n\n\tif ( ! isViewable ) {\n\t\treturn null;\n\t}\n\n\tconst target = `wp-preview-${ postId }`;\n\n\tconst handlePreviewClick = async ( event ) => {\n\t\t// Preserve native link semantics with `href` and `target`, but intercept the\n\t\t// click because the final preview URL may depend on an asynchronous save.\n\t\t// Opening the named window synchronously also prevents popup blocking and\n\t\t// ensures subsequent previews reuse the same tab.\n\t\t// https://github.com/WordPress/gutenberg/pull/8330\n\t\tevent.preventDefault();\n\n\t\t// Open up a Preview tab if needed. This is where we'll show the preview.\n\t\tconst previewWindow = window.open( '', target );\n\n\t\t// Focus the Preview tab. This might not do anything, depending on the browser's\n\t\t// and user's preferences.\n\t\t// https://html.spec.whatwg.org/multipage/interaction.html#dom-window-focus\n\t\tpreviewWindow.focus();\n\n\t\tawait writeInterstitialIntoPreviewWindow( previewWindow );\n\n\t\tconst link = await __unstableSaveForPreview( { forceIsAutosaveable } );\n\n\t\tpreviewWindow.location = link;\n\n\t\tonPreview?.();\n\t};\n\n\t// Link to the `?preview=true` URL if we have it, since this lets us see\n\t// changes that were autosaved since the post was last published. Otherwise,\n\t// just link to the post's URL.\n\tconst href = previewLink || currentPostLink;\n\n\treturn {\n\t\thref,\n\t\ttarget,\n\t\tdisabled: ! isSaveable,\n\t\tonClick: handlePreviewClick,\n\t};\n}\n\n/**\n * Renders the post preview action as a menu item.\n *\n * @param {Object}   props                     The component props.\n * @param {boolean}  props.forceIsAutosaveable Whether to force autosave.\n * @param {Function} props.onPreview           The callback function for the preview event.\n *\n * @return {React.ReactNode} The rendered menu item.\n */\nexport function PostPreviewMenuItem( { forceIsAutosaveable, onPreview } ) {\n\tconst previewProps = usePostPreviewProps( {\n\t\tforceIsAutosaveable,\n\t\tonPreview,\n\t} );\n\n\tif ( ! previewProps ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<MenuItem icon={ external } { ...previewProps }>\n\t\t\t{ __( 'Preview in new tab' ) }\n\t\t</MenuItem>\n\t);\n}\n\n/**\n * Renders a button that opens a new window or tab for the preview,\n * writes the interstitial message to this window, and then navigates\n * to the actual preview link. The button is not rendered if the post\n * is not viewable and disabled if the post is not saveable.\n *\n * @param {Object}   props                     The component props.\n * @param {string}   props.className           The class name for the button.\n * @param {string}   props.textContent         The text content for the button.\n * @param {boolean}  props.forceIsAutosaveable Whether to force autosave.\n * @param {string}   props.role                The role attribute for the button.\n * @param {Function} props.onPreview           The callback function for preview event.\n *\n * @return {React.ReactNode} The rendered button component.\n */\nexport default function PostPreviewButton( {\n\tclassName,\n\ttextContent,\n\tforceIsAutosaveable,\n\trole,\n\tonPreview,\n} ) {\n\tconst previewProps = usePostPreviewProps( {\n\t\tforceIsAutosaveable,\n\t\tonPreview,\n\t} );\n\n\tif ( ! previewProps ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Button\n\t\t\tvariant={ ! className ? 'tertiary' : undefined }\n\t\t\tclassName={ className || 'editor-post-preview' }\n\t\t\trole={ role }\n\t\t\tsize=\"compact\"\n\t\t\taccessibleWhenDisabled\n\t\t\t{ ...previewProps }\n\t\t>\n\t\t\t{ textContent || (\n\t\t\t\t<>\n\t\t\t\t\t{ _x( 'Preview', 'imperative verb' ) }\n\t\t\t\t\t<VisuallyHidden render={ <span /> }>\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* translators: accessibility text */\n\t\t\t\t\t\t\t__( '(opens in a new tab)' )\n\t\t\t\t\t\t}\n\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t</>\n\t\t\t) }\n\t\t</Button>\n\t);\n}\n"],
  "mappings": "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",
  "names": []
}
