| @@ -29,9 +29,9 @@ | ||
| 29 | 29 | * |
| 30 | 30 | * Reported to Elegant Themes. Remove this file when Divi ships |
| 31 | 31 | * the fix upstream. |
| 32 | 32 | * |
| 33 | - * @package WP_Desktop_Mode\Compat | |
| 33 | + * @package OpenStation\Compat | |
| 34 | 34 | */ |
| 35 | 35 | |
| 36 | 36 | defined( 'ABSPATH' ) || exit; |
| 37 | 37 | |
| @@ -83,9 +83,9 @@ | ||
| 83 | 83 | * the fix upstream. |
| 84 | 84 | * |
| 85 | 85 | * @return void |
| 86 | 86 | */ |
| 87 | -function desktop_mode_compat_divi_fix_gutenberg_deps() { | |
| 87 | +function openstation_compat_divi_fix_gutenberg_deps() { | |
| 88 | 88 | global $wp_scripts; |
| 89 | 89 | |
| 90 | 90 | if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { |
| 91 | 91 | return; |
| @@ -103,9 +103,9 @@ | ||
| 103 | 103 | $registration->deps[] = $dep; |
| 104 | 104 | } |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | - if ( desktop_mode_is_chromeless_request() ) { | |
| 107 | + if ( openstation_is_chromeless_request() ) { | |
| 108 | 108 | wp_add_inline_script( |
| 109 | 109 | 'et-builder-gutenberg', |
| 110 | 110 | 'window.et_gb = window;', |
| 111 | 111 | 'before' |
| @@ -111,9 +111,9 @@ | ||
| 111 | 111 | 'before' |
| 112 | 112 | ); |
| 113 | 113 | } |
| 114 | 114 | } |
| 115 | -add_action( 'enqueue_block_editor_assets', 'desktop_mode_compat_divi_fix_gutenberg_deps', 999 ); | |
| 115 | +add_action( 'enqueue_block_editor_assets', 'openstation_compat_divi_fix_gutenberg_deps', 999 ); | |
| 116 | 116 | |
| 117 | 117 | /** |
| 118 | 118 | * Signal Divi's Visual Builder frame-helpers that the iframe context |
| 119 | 119 | * is "top-level-equivalent" so its `top_window` export resolves to |
| @@ -148,9 +148,9 @@ | ||
| 148 | 148 | * — exactly the classic-admin behavior. The flag costs nothing |
| 149 | 149 | * outside Divi (no other code in the WP stack reads `__Cypress__`) |
| 150 | 150 | * and is idempotent (we OR with the existing value). |
| 151 | 151 | * |
| 152 | - * Scope: only when the current user has desktop mode enabled AND | |
| 152 | + * Scope: only when the current user has OpenStation enabled AND | |
| 153 | 153 | * the rendered document is loaded inside an iframe (`window.top !== |
| 154 | 154 | * window`). The inline script is a few-byte no-op everywhere else. |
| 155 | 155 | * Front-end only — admin pages use `et_gb` (see above) and route |
| 156 | 156 | * through a different compat path. |
| @@ -159,20 +159,20 @@ | ||
| 159 | 159 | * `top_window` iframe-aware upstream. |
| 160 | 160 | * |
| 161 | 161 | * @return void |
| 162 | 162 | */ |
| 163 | -function desktop_mode_compat_divi_vb_iframe_signal() { | |
| 163 | +function openstation_compat_divi_vb_iframe_signal() { | |
| 164 | 164 | if ( is_admin() ) { |
| 165 | 165 | return; |
| 166 | 166 | } |
| 167 | - if ( ! desktop_mode_is_enabled() ) { | |
| 167 | + if ( ! openstation_is_enabled() ) { | |
| 168 | 168 | return; |
| 169 | 169 | } |
| 170 | 170 | // Bail when Divi isn't active — the inline script below is |
| 171 | 171 | // shaped entirely around Divi's frame-helpers and VB preloader. |
| 172 | 172 | // Other handlers in this file already gate on |
| 173 | - // `desktop_mode_compat_divi_is_active()`; this one was missed. | |
| 174 | - if ( ! desktop_mode_compat_divi_is_active() ) { | |
| 173 | + // `openstation_compat_divi_is_active()`; this one was missed. | |
| 174 | + if ( ! openstation_compat_divi_is_active() ) { | |
| 175 | 175 | return; |
| 176 | 176 | } |
| 177 | 177 | // `app_window=1` flags the inner VB iframe Divi spawns inside the |
| 178 | 178 | // `/?p=N&et_fb=1` page. The outer ("VB-top") frame is what hosts |
| @@ -181,9 +181,9 @@ | ||
| 181 | 181 | // VB-top — the inner frame's `__Cypress__` signal is enough. |
| 182 | 182 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only flag set by Divi itself when constructing the inner iframe. |
| 183 | 183 | $is_app_frame = isset( $_GET['app_window'] ) && '1' === sanitize_text_field( wp_unslash( $_GET['app_window'] ) ); |
| 184 | 184 | ?> |
| 185 | -<script id="desktop-mode-compat-divi-vb"> | |
| 185 | +<script id="os-compat-divi-vb"> | |
| 186 | 186 | ( function () { |
| 187 | 187 | if ( window.top === window ) { return; } |
| 188 | 188 | <?php if ( $is_app_frame ) : ?> |
| 189 | 189 | // Inside Divi's own inner builder iframe. We only want to |
| @@ -210,9 +210,9 @@ | ||
| 210 | 210 | * `window.top.document`. The intent is "and also clear it on the |
| 211 | 211 | * outer VB-top frame I'm rendered into." In classic admin |
| 212 | 212 | * `window.top` IS the VB-top, so that works. |
| 213 | 213 | * |
| 214 | - * In a Desktop Mode chromeless iframe, the nesting is one deeper | |
| 214 | + * In a OpenStation chromeless iframe, the nesting is one deeper | |
| 215 | 215 | * — the inner React app's `window.top` is the desktop shell, |
| 216 | 216 | * which has no Divi elements. Root.js cleans its own doc and |
| 217 | 217 | * no-ops on the shell, leaving THIS document's preloader stuck |
| 218 | 218 | * forever. |
| @@ -272,9 +272,9 @@ | ||
| 272 | 272 | } )(); |
| 273 | 273 | </script> |
| 274 | 274 | <?php |
| 275 | 275 | } |
| 276 | -add_action( 'wp_head', 'desktop_mode_compat_divi_vb_iframe_signal', 1 ); | |
| 276 | +add_action( 'wp_head', 'openstation_compat_divi_vb_iframe_signal', 1 ); | |
| 277 | 277 | |
| 278 | 278 | /** |
| 279 | 279 | * Iframe-side: hijack clicks on Divi's "Use Divi Builder" / |
| 280 | 280 | * "Edit With The Divi Builder" buttons and links, and hand the |
| @@ -283,9 +283,9 @@ | ||
| 283 | 283 | * |
| 284 | 284 | * Why we hijack instead of letting Divi navigate: |
| 285 | 285 | * |
| 286 | 286 | * Divi's Visual Builder fundamentally doesn't behave well inside |
| 287 | - * Desktop Mode's nested iframe chain (shell -> chromeless iframe | |
| 287 | + * OpenStation's nested iframe chain (shell -> chromeless iframe | |
| 288 | 288 | * -> Divi's inner app-frame). Earlier attempts to transparently |
| 289 | 289 | * eject mid-navigation hit a chain of subtle race conditions — |
| 290 | 290 | * Divi captures `Location.prototype` references early, makes its |
| 291 | 291 | * REST save through a path our `fetch`/`XHR` wraps don't reach, |
| @@ -290,9 +290,9 @@ | ||
| 290 | 290 | * Divi captures `Location.prototype` references early, makes its |
| 291 | 291 | * REST save through a path our `fetch`/`XHR` wraps don't reach, |
| 292 | 292 | * and the page-leave tears down our console before any diagnostic |
| 293 | 293 | * we add survives the navigation. The honest fix is to ask the |
| 294 | - * user, explicitly, whether they want to leave Desktop Mode for | |
| 294 | + * user, explicitly, whether they want to leave OpenStation for | |
| 295 | 295 | * this edit session. |
| 296 | 296 | * |
| 297 | 297 | * Detection is by visible text content on the clicked element |
| 298 | 298 | * rather than by selector — Divi changes the button class across |
| @@ -308,17 +308,17 @@ | ||
| 308 | 308 | * blocks) is covered. |
| 309 | 309 | * |
| 310 | 310 | * @return void |
| 311 | 311 | */ |
| 312 | -function desktop_mode_compat_divi_eject_iframe_patch() { | |
| 313 | - if ( ! desktop_mode_is_chromeless_request() ) { | |
| 312 | +function openstation_compat_divi_eject_iframe_patch() { | |
| 313 | + if ( ! openstation_is_chromeless_request() ) { | |
| 314 | 314 | return; |
| 315 | 315 | } |
| 316 | - if ( ! desktop_mode_compat_divi_is_active() ) { | |
| 316 | + if ( ! openstation_compat_divi_is_active() ) { | |
| 317 | 317 | return; |
| 318 | 318 | } |
| 319 | 319 | ?> |
| 320 | -<script id="desktop-mode-compat-divi-vb-handoff"> | |
| 320 | +<script id="os-compat-divi-vb-handoff"> | |
| 321 | 321 | ( function () { |
| 322 | 322 | var BTN_TEXTS = [ |
| 323 | 323 | 'use divi builder', |
| 324 | 324 | 'use the divi builder', |
| @@ -335,9 +335,9 @@ | ||
| 335 | 335 | } |
| 336 | 336 | function postHandoff( currentUrl ) { |
| 337 | 337 | try { |
| 338 | 338 | window.top.postMessage( |
| 339 | - { type: 'desktop-mode-divi-vb-handoff', url: String( currentUrl ) }, | |
| 339 | + { type: 'os-divi-vb-handoff', url: String( currentUrl ) }, | |
| 340 | 340 | window.location.origin |
| 341 | 341 | ); |
| 342 | 342 | } catch ( e ) {} |
| 343 | 343 | } |
| @@ -359,10 +359,10 @@ | ||
| 359 | 359 | postHandoff( window.location.href ); |
| 360 | 360 | } |
| 361 | 361 | function attachClickListener( doc ) { |
| 362 | 362 | try { |
| 363 | - if ( doc.__desktopModeDiviHandoffAttached ) { return; } | |
| 364 | - doc.__desktopModeDiviHandoffAttached = true; | |
| 363 | + if ( doc.__openStationDiviHandoffAttached ) { return; } | |
| 364 | + doc.__openStationDiviHandoffAttached = true; | |
| 365 | 365 | doc.addEventListener( 'click', onClick, true ); |
| 366 | 366 | } catch ( e ) {} |
| 367 | 367 | } |
| 368 | 368 | function walkAndAttach( root ) { |
| @@ -373,10 +373,10 @@ | ||
| 373 | 373 | frames.forEach( function ( iframe ) { |
| 374 | 374 | try { |
| 375 | 375 | if ( iframe.contentDocument ) { walkAndAttach( iframe.contentDocument ); } |
| 376 | 376 | } catch ( e ) {} |
| 377 | - if ( iframe.__desktopModeDiviHandoffHooked ) { return; } | |
| 378 | - iframe.__desktopModeDiviHandoffHooked = true; | |
| 377 | + if ( iframe.__openStationDiviHandoffHooked ) { return; } | |
| 378 | + iframe.__openStationDiviHandoffHooked = true; | |
| 379 | 379 | iframe.addEventListener( 'load', function () { |
| 380 | 380 | try { if ( iframe.contentDocument ) { walkAndAttach( iframe.contentDocument ); } } catch ( e ) {} |
| 381 | 381 | } ); |
| 382 | 382 | } ); |
| @@ -394,13 +394,13 @@ | ||
| 394 | 394 | } )(); |
| 395 | 395 | </script> |
| 396 | 396 | <?php |
| 397 | 397 | } |
| 398 | -add_action( 'admin_head', 'desktop_mode_compat_divi_eject_iframe_patch', 0 ); | |
| 398 | +add_action( 'admin_head', 'openstation_compat_divi_eject_iframe_patch', 0 ); | |
| 399 | 399 | |
| 400 | 400 | /** |
| 401 | 401 | * Parent-shell side: receive the handoff message, ask the user |
| 402 | - * to confirm via `wp.desktop.confirm()`, and on accept navigate | |
| 402 | + * to confirm via `wp.os.confirm()`, and on accept navigate | |
| 403 | 403 | * `window.top.location.href` to the iframe's current URL — which |
| 404 | 404 | * is the post-edit page. The user lands at top level on the same |
| 405 | 405 | * post they were editing, clicks "Use Divi Builder" again with a |
| 406 | 406 | * single browser tab, and Divi runs in its native single-frame |
| @@ -414,34 +414,31 @@ | ||
| 414 | 414 | * same origin. Foreign frames can't trigger the handoff. |
| 415 | 415 | * |
| 416 | 416 | * @return void |
| 417 | 417 | */ |
| 418 | -function desktop_mode_compat_divi_eject_parent_listener() { | |
| 419 | - if ( ! desktop_mode_is_enabled() ) { | |
| 418 | +function openstation_compat_divi_eject_parent_listener() { | |
| 419 | + if ( ! openstation_is_shell_request() ) { | |
| 420 | 420 | return; |
| 421 | 421 | } |
| 422 | - if ( desktop_mode_is_chromeless_request() || desktop_mode_is_classic_request() ) { | |
| 422 | + if ( ! openstation_compat_divi_is_active() ) { | |
| 423 | 423 | return; |
| 424 | 424 | } |
| 425 | - if ( ! desktop_mode_compat_divi_is_active() ) { | |
| 426 | - return; | |
| 427 | - } | |
| 428 | 425 | ?> |
| 429 | -<script id="desktop-mode-compat-divi-vb-handoff-parent"> | |
| 426 | +<script id="os-compat-divi-vb-handoff-parent"> | |
| 430 | 427 | ( function () { |
| 431 | 428 | // Reshape the iframe's URL into a top-level classic-admin URL. |
| 432 | - // The iframe carries `desktop_mode_chromeless=1`, which would | |
| 429 | + // The iframe carries `openstation_chromeless=1`, which would | |
| 433 | 430 | // keep the chromeless render alive even at top level — leaving |
| 434 | 431 | // the user on what looks like the same headless Gutenberg they |
| 435 | 432 | // already had inside the window. We want a normal wp-admin page |
| 436 | 433 | // instead, so strip that flag and add `desktop_mode_classic=1` |
| 437 | - // so our own `desktop_mode_redirect_plain_admin_to_portal()` in | |
| 434 | + // so our own `openstation_redirect_plain_admin_to_portal()` in | |
| 438 | 435 | // `includes/portal.php` skips its portal-bounce for this load. |
| 439 | 436 | function handoffUrl( raw ) { |
| 440 | 437 | try { |
| 441 | 438 | var parsed = new URL( String( raw || '' ), window.location.href ); |
| 442 | 439 | if ( parsed.origin !== window.location.origin ) { return null; } |
| 443 | - parsed.searchParams.delete( 'desktop_mode_chromeless' ); | |
| 440 | + parsed.searchParams.delete( 'openstation_chromeless' ); | |
| 444 | 441 | parsed.searchParams.set( 'desktop_mode_classic', '1' ); |
| 445 | 442 | return parsed.toString(); |
| 446 | 443 | } catch ( e ) { return null; } |
| 447 | 444 | } |
| @@ -446,22 +443,22 @@ | ||
| 446 | 443 | } catch ( e ) { return null; } |
| 447 | 444 | } |
| 448 | 445 | window.addEventListener( 'message', function ( ev ) { |
| 449 | 446 | if ( ev.origin !== window.location.origin ) { return; } |
| 450 | - if ( ! ev.data || ev.data.type !== 'desktop-mode-divi-vb-handoff' ) { return; } | |
| 447 | + if ( ! ev.data || ev.data.type !== 'os-divi-vb-handoff' ) { return; } | |
| 451 | 448 | var url = handoffUrl( ev.data.url ); |
| 452 | 449 | if ( ! url ) { return; } |
| 453 | 450 | var promptUser; |
| 454 | - if ( window.wp && window.wp.desktop && typeof window.wp.desktop.confirm === 'function' ) { | |
| 455 | - promptUser = window.wp.desktop.confirm( { | |
| 451 | + if ( window.wp && window.wp.os && typeof window.wp.os.confirm === 'function' ) { | |
| 452 | + promptUser = window.wp.os.confirm( { | |
| 456 | 453 | title: 'Divi needs its own browser tab', |
| 457 | - message: 'Divi\u2019s Visual Builder cannot run inside a Desktop Mode window \u2014 it needs the full browser tab to render and save correctly. There is no workaround on our side; Divi simply doesn\u2019t support being nested.', | |
| 454 | + message: 'Divi\u2019s Visual Builder cannot run inside a OpenStation window \u2014 it needs the full browser tab to render and save correctly. There is no workaround on our side; Divi simply doesn\u2019t support being nested.', | |
| 458 | 455 | confirmLabel: 'Open Divi in this tab', |
| 459 | 456 | hideCancel: true, |
| 460 | 457 | dismissable: true, |
| 461 | 458 | } ); |
| 462 | 459 | } else { |
| 463 | - // Defense-in-depth no-op. `wp.desktop.confirm` is | |
| 460 | + // Defense-in-depth no-op. `wp.os.confirm` is | |
| 464 | 461 | // reliably present on every shell page where this |
| 465 | 462 | // listener emits, so this branch is unreachable in |
| 466 | 463 | // practice. A `window.confirm` here would violate the |
| 467 | 464 | // codebase-wide "no native dialogs" rule (see CLAUDE.md); |
| @@ -475,9 +472,9 @@ | ||
| 475 | 472 | } )(); |
| 476 | 473 | </script> |
| 477 | 474 | <?php |
| 478 | 475 | } |
| 479 | -add_action( 'admin_footer', 'desktop_mode_compat_divi_eject_parent_listener', 1 ); | |
| 476 | +add_action( 'admin_footer', 'openstation_compat_divi_eject_parent_listener', 1 ); | |
| 480 | 477 | |
| 481 | 478 | |
| 482 | 479 | /** |
| 483 | 480 | * Detect whether Divi (theme or standalone Divi Builder plugin) |
| @@ -486,9 +483,9 @@ | ||
| 486 | 483 | * |
| 487 | 484 | * @return bool True when the Divi theme is active OR the Divi |
| 488 | 485 | * Builder plugin is active. |
| 489 | 486 | */ |
| 490 | -function desktop_mode_compat_divi_is_active() { | |
| 487 | +function openstation_compat_divi_is_active() { | |
| 491 | 488 | $theme = wp_get_theme(); |
| 492 | 489 | if ( $theme instanceof WP_Theme ) { |
| 493 | 490 | $name = (string) $theme->get( 'Name' ); |
| 494 | 491 | $template = (string) $theme->get_template(); |