| @@ -1,11 +1,11 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Desktop Mode — Native-window tabs registry. | |
| 3 | + * OpenStation — Native-window tabs registry. | |
| 4 | 4 | * |
| 5 | 5 | * Multi-tab native windows are a sister-to-the-window |
| 6 | 6 | * registration: a tab is owned by some window id and its content |
| 7 | - * is wrapped in `<wpd-tabpanel>` automatically by the shell. The | |
| 7 | + * is wrapped in `<os-tabpanel>` automatically by the shell. The | |
| 8 | 8 | * MAIN_TAB constant reserves the `'main'` value for the window's |
| 9 | 9 | * own `template` callback so plugins can't accidentally collide |
| 10 | 10 | * with the built-in main pane. |
| 11 | 11 | * |
| @@ -11,10 +11,9 @@ | ||
| 11 | 11 | * |
| 12 | 12 | * Extracted from `components.php` during the architecture-0.8.1 |
| 13 | 13 | * PHP slicing (phase 6). |
| 14 | 14 | * |
| 15 | - * @package Desktop_Mode | |
| 16 | - * @since 0.8.1 | |
| 15 | + * @package OpenStation | |
| 17 | 16 | */ |
| 18 | 17 | |
| 19 | 18 | defined( 'ABSPATH' ) || exit; |
| 20 | 19 | |
| @@ -24,14 +23,12 @@ | ||
| 24 | 23 | * registration's `template` callback, and its label is the |
| 25 | 24 | * window's `main_tab_label` (falling back to the window `title`). |
| 26 | 25 | * |
| 27 | 26 | * Plugins cannot register an additional tab with this value — |
| 28 | - * {@see desktop_mode_register_window_tab()} returns | |
| 29 | - * `desktop_mode_reserved_tab_value` when they try. | |
| 30 | - * | |
| 31 | - * @since 0.11.0 | |
| 27 | + * {@see openstation_register_window_tab()} returns | |
| 28 | + * `openstation_reserved_tab_value` when they try. | |
| 32 | 29 | */ |
| 33 | -const DESKTOP_MODE_NATIVE_WINDOW_MAIN_TAB = 'main'; | |
| 30 | +const OPENSTATION_NATIVE_WINDOW_MAIN_TAB = 'main'; | |
| 34 | 31 | |
| 35 | 32 | /** |
| 36 | 33 | * Register an additional tab on an existing native window. |
| 37 | 34 | * |
| @@ -42,23 +39,23 @@ | ||
| 42 | 39 | * alongside it. Cross-plugin extension is supported — a companion |
| 43 | 40 | * plugin can attach a tab to someone else's window. |
| 44 | 41 | * |
| 45 | 42 | * Registering even a single tab turns on the auto-wrap path in |
| 46 | - * `desktop_mode_build_native_window_template_html()`: the shell wraps the | |
| 47 | - * window body in `<wpd-stack>` + `<wpd-tabs>` + `<wpd-tabpanel>` | |
| 43 | + * `openstation_build_native_window_template_html()`: the shell wraps the | |
| 44 | + * window body in `<os-stack>` + `<os-tabs>` + `<os-tabpanel>` | |
| 48 | 45 | * elements automatically. Plugin authors no longer hand-write that |
| 49 | - * markup — the shell provides it and `<wpd-tabpanel>` auto-swap | |
| 50 | - * (from 0.11) handles visibility. | |
| 46 | + * markup — the shell provides it and `<os-tabpanel>` auto-swap | |
| 47 | + * handles visibility. | |
| 51 | 48 | * |
| 52 | 49 | * ```php |
| 53 | 50 | * // Plugin that owns the window declares its own tabs: |
| 54 | - * desktop_mode_register_window( 'jorvy', array( | |
| 51 | + * openstation_register_window( 'jorvy', array( | |
| 55 | 52 | * 'title' => 'Jorvy', |
| 56 | 53 | * 'main_tab_label' => 'Quotes', |
| 57 | 54 | * 'template' => function () { echo '<p class="quote"></p>'; }, |
| 58 | 55 | * 'script' => 'jorvy-main', |
| 59 | 56 | * ) ); |
| 60 | - * desktop_mode_register_window_tab( 'jorvy', array( | |
| 57 | + * openstation_register_window_tab( 'jorvy', array( | |
| 61 | 58 | * 'value' => 'about', |
| 62 | 59 | * 'label' => 'About', |
| 63 | 60 | * 'template' => function () { echo '<p>Marvel quotes, rotated every 10s.</p>'; }, |
| 64 | 61 | * ) ); |
| @@ -63,9 +60,9 @@ | ||
| 63 | 60 | * 'template' => function () { echo '<p>Marvel quotes, rotated every 10s.</p>'; }, |
| 64 | 61 | * ) ); |
| 65 | 62 | * |
| 66 | 63 | * // A companion plugin attaches a tab to someone else's window: |
| 67 | - * desktop_mode_register_window_tab( 'jorvy', array( | |
| 64 | + * openstation_register_window_tab( 'jorvy', array( | |
| 68 | 65 | * 'value' => 'stats', |
| 69 | 66 | * 'label' => 'Stats', |
| 70 | 67 | * 'template' => 'jorvy_stats_pane', |
| 71 | 68 | * 'script' => 'jorvy-stats', |
| @@ -71,10 +68,8 @@ | ||
| 71 | 68 | * 'script' => 'jorvy-stats', |
| 72 | 69 | * ) ); |
| 73 | 70 | * ``` |
| 74 | 71 | * |
| 75 | - * @since 0.11.0 | |
| 76 | - * | |
| 77 | 72 | * @param string $window_id Id of the native window this tab belongs to. |
| 78 | 73 | * @param array $args { |
| 79 | 74 | * @type string $value Tab id (unique within the window). |
| 80 | 75 | * Required. Cannot equal the reserved |
| @@ -82,9 +77,9 @@ | ||
| 82 | 77 | * own template tab. |
| 83 | 78 | * @type string $label Display label on the tab strip. Required. |
| 84 | 79 | * @type callable $template Callback that echoes the tab's |
| 85 | 80 | * pane HTML. Wrapped in |
| 86 | - * `<wpd-tabpanel for="<value>">` by | |
| 81 | + * `<os-tabpanel for="<value>">` by | |
| 87 | 82 | * the shell. Required. |
| 88 | 83 | * @type string $script Optional script handle enqueued |
| 89 | 84 | * when the window is active — useful |
| 90 | 85 | * when a tab needs its own JS module |
| @@ -94,17 +89,17 @@ | ||
| 94 | 89 | * window; lower renders earlier. |
| 95 | 90 | * Default 100. |
| 96 | 91 | * @type string[] $capabilities Gate: ALL caps must match. Any |
| 97 | 92 | * missed cap returns |
| 98 | - * `WP_Error desktop_mode_capability_denied`. | |
| 93 | + * `WP_Error openstation_capability_denied`. | |
| 99 | 94 | * } |
| 100 | 95 | * @return true|WP_Error `true` on success; `WP_Error` otherwise. |
| 101 | 96 | */ |
| 102 | -function desktop_mode_register_window_tab( $window_id, $args = array() ) { | |
| 97 | +function openstation_register_window_tab( $window_id, $args = array() ) { | |
| 103 | 98 | $window_id = sanitize_key( (string) $window_id ); |
| 104 | 99 | if ( '' === $window_id ) { |
| 105 | - return desktop_mode_registration_error( | |
| 106 | - 'desktop_mode_missing_window_id', | |
| 100 | + return openstation_registration_error( | |
| 101 | + 'openstation_missing_window_id', | |
| 107 | 102 | __( 'Window id is required when registering a tab.', 'desktop-mode' ) |
| 108 | 103 | ); |
| 109 | 104 | } |
| 110 | 105 | |
| @@ -115,20 +110,23 @@ | ||
| 115 | 110 | 'script' => '', |
| 116 | 111 | 'position' => 100, |
| 117 | 112 | 'capabilities' => array(), |
| 118 | 113 | ); |
| 119 | - $args = wp_parse_args( $args, $defaults ); | |
| 114 | + $args = wp_parse_args( $args, $defaults ); | |
| 120 | 115 | |
| 121 | 116 | foreach ( (array) $args['capabilities'] as $cap ) { |
| 122 | 117 | if ( ! current_user_can( (string) $cap ) ) { |
| 123 | - return desktop_mode_registration_error( | |
| 124 | - 'desktop_mode_capability_denied', | |
| 118 | + return openstation_registration_error( | |
| 119 | + 'openstation_capability_denied', | |
| 125 | 120 | sprintf( |
| 126 | 121 | /* translators: %s: capability slug. */ |
| 127 | 122 | __( 'Current user lacks the %s capability required to register this window tab.', 'desktop-mode' ), |
| 128 | 123 | (string) $cap |
| 129 | 124 | ), |
| 130 | - array( 'capability' => (string) $cap, 'window_id' => $window_id ) | |
| 125 | + array( | |
| 126 | + 'capability' => (string) $cap, | |
| 127 | + 'window_id' => $window_id, | |
| 128 | + ) | |
| 131 | 129 | ); |
| 132 | 130 | } |
| 133 | 131 | } |
| 134 | 132 | |
| @@ -135,52 +133,58 @@ | ||
| 135 | 133 | // Tab values accept both flat slugs ('convert') and a single |
| 136 | 134 | // `vendor/sub-id` namespace ('plugin/convert') so two plugins |
| 137 | 135 | // targeting the same window can ship same-named tabs without |
| 138 | 136 | // stomping each other in the registry. The downstream uses |
| 139 | - // (`wpd-tabpanel[for="…"]`, `<wpd-tab value="…">`) all pass the | |
| 137 | + // (`os-tabpanel[for="…"]`, `<os-tab value="…">`) all pass the | |
| 140 | 138 | // value through esc_attr and use it as an attribute selector, |
| 141 | 139 | // which tolerates the slash. |
| 142 | 140 | $value_raw = strtolower( trim( (string) $args['value'] ) ); |
| 143 | 141 | if ( '' === $value_raw ) { |
| 144 | - return desktop_mode_registration_error( | |
| 145 | - 'desktop_mode_missing_tab_value', | |
| 142 | + return openstation_registration_error( | |
| 143 | + 'openstation_missing_tab_value', | |
| 146 | 144 | __( 'Window tab registration requires a non-empty `value`.', 'desktop-mode' ), |
| 147 | 145 | array( 'window_id' => $window_id ) |
| 148 | 146 | ); |
| 149 | 147 | } |
| 150 | 148 | if ( ! preg_match( '/^[a-z0-9_-]+(\/[a-z0-9_-]+)?$/', $value_raw ) ) { |
| 151 | - return desktop_mode_registration_error( | |
| 152 | - 'desktop_mode_invalid_tab_value', | |
| 149 | + return openstation_registration_error( | |
| 150 | + 'openstation_invalid_tab_value', | |
| 153 | 151 | sprintf( |
| 154 | 152 | /* translators: %s: the invalid value. */ |
| 155 | 153 | __( 'Window tab `value` "%s" must match /^[a-z0-9_-]+(\/[a-z0-9_-]+)?$/ — lowercase alphanum + hyphen/underscore, with at most one `vendor/sub-id` slash.', 'desktop-mode' ), |
| 156 | 154 | $value_raw |
| 157 | 155 | ), |
| 158 | - array( 'window_id' => $window_id, 'value' => $value_raw ) | |
| 156 | + array( | |
| 157 | + 'window_id' => $window_id, | |
| 158 | + 'value' => $value_raw, | |
| 159 | + ) | |
| 159 | 160 | ); |
| 160 | 161 | } |
| 161 | 162 | $value = $value_raw; |
| 162 | - if ( DESKTOP_MODE_NATIVE_WINDOW_MAIN_TAB === $value ) { | |
| 163 | - return desktop_mode_registration_error( | |
| 164 | - 'desktop_mode_reserved_tab_value', | |
| 163 | + if ( OPENSTATION_NATIVE_WINDOW_MAIN_TAB === $value ) { | |
| 164 | + return openstation_registration_error( | |
| 165 | + 'openstation_reserved_tab_value', | |
| 165 | 166 | sprintf( |
| 166 | 167 | /* translators: %s: the reserved value. */ |
| 167 | 168 | __( 'The tab value "%s" is reserved for the window\'s own template tab.', 'desktop-mode' ), |
| 168 | - DESKTOP_MODE_NATIVE_WINDOW_MAIN_TAB | |
| 169 | + OPENSTATION_NATIVE_WINDOW_MAIN_TAB | |
| 169 | 170 | ), |
| 170 | - array( 'window_id' => $window_id, 'value' => $value ) | |
| 171 | + array( | |
| 172 | + 'window_id' => $window_id, | |
| 173 | + 'value' => $value, | |
| 174 | + ) | |
| 171 | 175 | ); |
| 172 | 176 | } |
| 173 | 177 | if ( '' === (string) $args['label'] ) { |
| 174 | - return desktop_mode_registration_error( | |
| 175 | - 'desktop_mode_missing_label', | |
| 178 | + return openstation_registration_error( | |
| 179 | + 'openstation_missing_label', | |
| 176 | 180 | __( 'Window tab registration requires a non-empty `label`.', 'desktop-mode' ), |
| 177 | 181 | array( 'window_id' => $window_id ) |
| 178 | 182 | ); |
| 179 | 183 | } |
| 180 | 184 | if ( ! is_callable( $args['template'] ) ) { |
| 181 | - return desktop_mode_registration_error( | |
| 182 | - 'desktop_mode_invalid_template', | |
| 185 | + return openstation_registration_error( | |
| 186 | + 'openstation_invalid_template', | |
| 183 | 187 | __( 'Window tab registration requires a callable `template` that echoes the pane body.', 'desktop-mode' ), |
| 184 | 188 | array( 'window_id' => $window_id ) |
| 185 | 189 | ); |
| 186 | 190 | } |
| @@ -191,23 +195,21 @@ | ||
| 191 | 195 | 'template' => $args['template'], |
| 192 | 196 | 'script' => (string) $args['script'], |
| 193 | 197 | 'position' => (int) $args['position'], |
| 194 | 198 | ); |
| 195 | - desktop_mode_desktop_window_tab_registry( $window_id, $value, $entry ); | |
| 199 | + openstation_desktop_window_tab_registry( $window_id, $value, $entry ); | |
| 196 | 200 | |
| 197 | 201 | /** |
| 198 | 202 | * Fires after a native window tab is successfully registered. |
| 199 | 203 | * |
| 200 | - * Does NOT fire when `desktop_mode_register_window_tab()` returns | |
| 204 | + * Does NOT fire when `openstation_register_window_tab()` returns | |
| 201 | 205 | * a `WP_Error`. |
| 202 | 206 | * |
| 203 | - * @since 0.11.0 | |
| 204 | - * | |
| 205 | 207 | * @param string $window_id The window this tab belongs to. |
| 206 | 208 | * @param string $value The tab value. |
| 207 | 209 | * @param array $entry The stored registry entry. |
| 208 | 210 | */ |
| 209 | - do_action( 'desktop_mode_window_tab_registered', $window_id, $value, $entry ); | |
| 211 | + do_action( 'openstation_window_tab_registered', $window_id, $value, $entry ); | |
| 210 | 212 | |
| 211 | 213 | return true; |
| 212 | 214 | } |
| 213 | 215 | |
| @@ -216,9 +218,8 @@ | ||
| 216 | 218 | * `[window_id][value]`. Pass `$entry = null` and any non-empty |
| 217 | 219 | * `$value` to read a single entry; pass both `$window_id` and |
| 218 | 220 | * `$value` empty to get the full registry. |
| 219 | 221 | * |
| 220 | - * @since 0.11.0 | |
| 221 | 222 | * @internal |
| 222 | 223 | * |
| 223 | 224 | * @param string $window_id Window id (or '' to read everything). |
| 224 | 225 | * @param string $value Tab value (or '' to read every tab |
| @@ -225,9 +226,9 @@ | ||
| 225 | 226 | * on the given window). |
| 226 | 227 | * @param array|null $entry Entry to store, or null to just read. |
| 227 | 228 | * @return array|null |
| 228 | 229 | */ |
| 229 | -function desktop_mode_desktop_window_tab_registry( $window_id = '', $value = '', $entry = null ) { | |
| 230 | +function openstation_desktop_window_tab_registry( $window_id = '', $value = '', $entry = null ) { | |
| 230 | 231 | static $store = array(); |
| 231 | 232 | |
| 232 | 233 | if ( '' === (string) $window_id ) { |
| 233 | 234 | return $store; |
| @@ -253,24 +254,22 @@ | ||
| 253 | 254 | * order). |
| 254 | 255 | * |
| 255 | 256 | * Shape per entry: `{ value, label, template, script, is_main, position }`. |
| 256 | 257 | * |
| 257 | - * Filterable via `desktop_mode_window_tabs` so a late-loading plugin | |
| 258 | + * Filterable via `openstation_window_tabs` so a late-loading plugin | |
| 258 | 259 | * can reorder, hide, or relabel tabs another plugin registered — |
| 259 | - * mirrors the `desktop_mode_wallpapers` filter discipline. | |
| 260 | + * mirrors the `openstation_wallpapers` filter discipline. | |
| 260 | 261 | * |
| 261 | - * @since 0.11.0 | |
| 262 | - * | |
| 263 | 262 | * @param string $window_id Window id. |
| 264 | 263 | * @return array[] |
| 265 | 264 | */ |
| 266 | -function desktop_mode_get_native_window_tabs( $window_id ) { | |
| 267 | - $window = desktop_mode_native_window_registry( (string) $window_id ); | |
| 265 | +function openstation_get_native_window_tabs( $window_id ) { | |
| 266 | + $window = openstation_native_window_registry( (string) $window_id ); | |
| 268 | 267 | if ( ! is_array( $window ) ) { |
| 269 | 268 | return array(); |
| 270 | 269 | } |
| 271 | 270 | |
| 272 | - $extras = desktop_mode_desktop_window_tab_registry( $window_id ); | |
| 271 | + $extras = openstation_desktop_window_tab_registry( $window_id ); | |
| 273 | 272 | if ( ! is_array( $extras ) ) { |
| 274 | 273 | $extras = array(); |
| 275 | 274 | } |
| 276 | 275 | |
| @@ -278,11 +277,11 @@ | ||
| 278 | 277 | // `main_tab_label` was set during registration. |
| 279 | 278 | $main_label = '' !== (string) $window['main_tab_label'] |
| 280 | 279 | ? (string) $window['main_tab_label'] |
| 281 | 280 | : (string) $window['title']; |
| 282 | - $tabs = array( | |
| 281 | + $tabs = array( | |
| 283 | 282 | array( |
| 284 | - 'value' => DESKTOP_MODE_NATIVE_WINDOW_MAIN_TAB, | |
| 283 | + 'value' => OPENSTATION_NATIVE_WINDOW_MAIN_TAB, | |
| 285 | 284 | 'label' => $main_label, |
| 286 | 285 | 'template' => $window['template'], |
| 287 | 286 | 'script' => '', |
| 288 | 287 | 'is_main' => true, |
| @@ -290,16 +289,20 @@ | ||
| 290 | 289 | ), |
| 291 | 290 | ); |
| 292 | 291 | |
| 293 | 292 | // Additional tabs sorted by position. Values are trusted — they |
| 294 | - // come from sanitize_key() at registration time. | |
| 293 | + // were validated against /^[a-z0-9_-]+(\/[a-z0-9_-]+)?$/ at | |
| 294 | + // registration time (sanitize_key would strip the namespace slash). | |
| 295 | 295 | $sorted = array_values( $extras ); |
| 296 | - usort( $sorted, static function ( $a, $b ) { | |
| 297 | - if ( $a['position'] === $b['position'] ) { | |
| 298 | - return 0; | |
| 296 | + usort( | |
| 297 | + $sorted, | |
| 298 | + static function ( $a, $b ) { | |
| 299 | + if ( $a['position'] === $b['position'] ) { | |
| 300 | + return 0; | |
| 301 | + } | |
| 302 | + return $a['position'] < $b['position'] ? -1 : 1; | |
| 299 | 303 | } |
| 300 | - return $a['position'] < $b['position'] ? -1 : 1; | |
| 301 | - } ); | |
| 304 | + ); | |
| 302 | 305 | foreach ( $sorted as $tab ) { |
| 303 | 306 | $tabs[] = array( |
| 304 | 307 | 'value' => $tab['value'], |
| 305 | 308 | 'label' => $tab['label'], |
| @@ -318,12 +321,10 @@ | ||
| 318 | 321 | * The main tab's `template` is the window's own template |
| 319 | 322 | * callback; replacing it at filter time is supported but |
| 320 | 323 | * unusual — prefer updating the window registration itself. |
| 321 | 324 | * |
| 322 | - * @since 0.11.0 | |
| 323 | - * | |
| 324 | 325 | * @param array[] $tabs Ordered tab descriptors. |
| 325 | 326 | * @param string $window_id Window id. |
| 326 | 327 | */ |
| 327 | - $filtered = apply_filters( 'desktop_mode_window_tabs', $tabs, $window_id ); | |
| 328 | + $filtered = apply_filters( 'openstation_window_tabs', $tabs, $window_id ); | |
| 328 | 329 | return is_array( $filtered ) ? $filtered : $tabs; |
| 329 | 330 | } |