PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.8
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.8
1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 0.8.6 All 33 releases
desktop-mode / includes / window-actions.php

window-actions.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.8, at includes/window-actions.php

156 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Window actions-menu registration API.
4 *
5 * Mirrors the title-bar-button / command / settings-tab script
6 * registration pattern: minimum-ceremony PHP opt-in
7 * (`openstation_register_window_action_script`) tells the shell which
8 * enqueued scripts contribute rows to a window's ⋯ menu. The shell
9 * injects the script URL into the live-refresh payload, so a plugin
10 * activated mid-session gets its row on the next menu open with no F5
11 * — and, more to the point, a plugin *deactivated* mid-session loses
12 * it just as promptly.
13 *
14 * That second half is the reason this file exists. `WindowActionDef`
15 * has always documented an `owner` field as the handle to unregister
16 * by on deactivation, and the registry has always implemented
17 * `unregisterWindowActionsByOwner()`. Nothing called it: without a
18 * server-side opt-in there was no payload key to diff, so the promise
19 * in the docs described behaviour no code performed.
20 *
21 * Actions themselves are declared JS-side via
22 * `wp.os.registerWindowAction( … )` — label, icon, predicate and
23 * handler all live in the plugin's TypeScript / JavaScript, because
24 * all four are read per menu open against a live window object.
25 *
26 * @package OpenStation
27 */
28
29 defined( 'ABSPATH' ) || exit;
30
31 /**
32 * Declare a WP-registered script handle as a window-action provider.
33 *
34 * Example:
35 *
36 * ```php
37 * add_action( 'admin_enqueue_scripts', function () {
38 * wp_register_script(
39 * 'my-plugin-window-actions',
40 * plugins_url( 'js/window-actions.js', __FILE__ ),
41 * array( 'openstation' ),
42 * '1.0.0',
43 * true
44 * );
45 * wp_enqueue_script( 'my-plugin-window-actions' );
46 * }, 5 ); // Before the shell harvests the payload at priority 10.
47 * openstation_register_window_action_script( 'my-plugin-window-actions' );
48 * ```
49 *
50 * For live unregistration on deactivation, the plugin's JS should set
51 * `owner: 'my-plugin-window-actions'` on each `registerWindowAction`
52 * call. Otherwise the row stays until the next page reload — graceful
53 * backwards-compat, the same bargain commands and title-bar buttons
54 * offer.
55 *
56 * @param string $handle WP-registered script handle.
57 * @return true|WP_Error `true` on success; `WP_Error` on validation failure.
58 */
59 function openstation_register_window_action_script( $handle ) {
60 $handle = (string) $handle;
61 if ( '' === $handle ) {
62 return openstation_registration_error(
63 'openstation_missing_handle',
64 __( 'Window action script registration requires a non-empty script handle.', 'desktop-mode' )
65 );
66 }
67
68 openstation_desktop_window_action_script_registry( $handle, true );
69
70 /**
71 * Fires after a window action script handle is registered.
72 *
73 * @param string $handle The registered script handle.
74 */
75 do_action( 'openstation_window_action_script_registered', $handle );
76
77 return true;
78 }
79
80 /**
81 * Internal module-level registry for window action script handles.
82 *
83 * @internal
84 *
85 * @param string $handle Script handle to read or write.
86 * @param bool|null $value Pass `true` to register; `null` to read only.
87 * @return array|bool When called with no args returns the full store.
88 */
89 function openstation_desktop_window_action_script_registry( $handle = '', $value = null ) {
90 static $store = array();
91
92 if ( '__flush__' === (string) $handle ) {
93 $store = array();
94 return array();
95 }
96 if ( '' === (string) $handle ) {
97 return $store;
98 }
99 if ( null !== $value ) {
100 $store[ (string) $handle ] = (bool) $value;
101 }
102 return isset( $store[ (string) $handle ] ) ? $store[ (string) $handle ] : false;
103 }
104
105 /**
106 * Test-only: clear the registry between PHPUnit cases. See
107 * {@see openstation_flush_script_handle_registries()}.
108 */
109 function openstation_flush_desktop_window_action_script_registry() {
110 openstation_desktop_window_action_script_registry( '__flush__' );
111 }
112
113 /**
114 * Build the script-handle payload fed to the shell. Handles that
115 * aren't currently enqueued resolve to an empty URL and are dropped.
116 *
117 * @return array[] List of `{ handle, scriptUrl, scriptBefore, scriptAfter, scriptL10n, scriptTranslations }` entries.
118 */
119 function openstation_build_desktop_window_action_scripts_payload() {
120 $registry = openstation_desktop_window_action_script_registry();
121 if ( ! is_array( $registry ) || empty( $registry ) ) {
122 return array();
123 }
124
125 $out = array();
126 $seen = array();
127 foreach ( $registry as $handle => $active ) {
128 if ( ! $active || isset( $seen[ $handle ] ) ) {
129 continue;
130 }
131 $payload = openstation_resolve_script_payload( $handle );
132 if ( '' === $payload['url'] ) {
133 // Loud diagnostic — visible under WP_DEBUG. A typo'd handle,
134 // or a register call made before `wp_register_script()`,
135 // otherwise registers nothing and leaves the author staring
136 // at a ⋯ menu that never grew a row.
137 openstation_warn_unresolvable_script_handle(
138 'openstation_register_window_action_script',
139 'Window action',
140 (string) $handle
141 );
142 continue;
143 }
144 $out[] = array(
145 'handle' => (string) $handle,
146 'scriptUrl' => $payload['url'],
147 'scriptBefore' => $payload['before'],
148 'scriptAfter' => $payload['after'],
149 'scriptL10n' => $payload['l10n'],
150 'scriptTranslations' => $payload['translations'],
151 );
152 $seen[ $handle ] = true;
153 }
154 return $out;
155 }
156