Markus Michalski FAQ

Tab Swap: Technical Details

Technical details of Tab Swap: object.view signal, the inline script, the four required DOM elements, PJAX re-run, version check, CSP nonce and file structure.

Deutsche Version

Back to overview

Tab Swap: Technical Details

Flow

graph TD
    A["osTicket starts, plugin bootstrap()"] --> B["checkVersion(): store installed_version"]
    B --> C{"Enable Tab Swap on?"}
    C -->|"No"| D["No signal, no script"]
    C -->|"Yes"| E["object.view signal connected"]
    E --> F{"Object is a ticket?"}
    F -->|"No"| G["Nothing happens"]
    F -->|"Yes"| H["Inline script is output"]
    H --> I["Browser: swap tabs"]

Plugin metadata

Property Value
Plugin ID net.markus-michalski:tab-swap
Name Tab Swap
Plugin class TabSwapPlugin in class.TabSwapPlugin.php
Configuration class TabSwapConfig in config.php
Instances Singleton: exactly one instance, enable() creates it if needed
PHP >=7.4 (composer.json)

Server side

Output script

The plugin outputs an element of the form <script data-plugin="tab-swap" data-version="..." nonce="...">:

Browser side

The script only acts once all prerequisites are met:

  1. The elements #post-reply-tab, #post-note-tab, #reply and #note exist.
  2. Both tabs are visible (offsetParent is not null).

Then the following happens:

  1. The li element of the note tab is moved before the li of the reply tab inside #response-tabs.
  2. The class active is removed from the reply tab and aria-selected="false" is set. On the note tab, active is added and aria-selected="true" is set.
  3. #reply gets display: none, #note gets display: block.

The swap runs once per page build. So that it also applies to pages built later, the script uses:

jQuery is not strictly required. Without it, only the reaction to redraw.staff is omitted.

File structure

tab-swap/
├── plugin.php               # plugin metadata
├── class.TabSwapPlugin.php  # plugin class, signal handler, inline script
└── config.php               # TabSwapConfig with the two fields

The repository additionally contains composer.json, PHPUnit tests, a CI workflow and documentation. CI checks syntax and runs the tests with PHP 7.4 to 8.3.