diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..18aee20 --- /dev/null +++ b/metadata.json @@ -0,0 +1,10 @@ +{ + "author": "spleenftw", + "email": "", + "website": "https://github.com/spleenftw/bludit-toc", + "version": "1.0.0", + "releaseDate": "2026-06-04", + "license": "MIT", + "compatible": "3.22.0", + "notes": "Sticky Table of Contents sidebar (desktop) and floating drawer (mobile) built from the article's h2/h3/h4 headings." +} diff --git a/plugin.php b/plugin.php new file mode 100644 index 0000000..4f9c794 --- /dev/null +++ b/plugin.php @@ -0,0 +1,93 @@ +dbFields = array( + // Label shown at the top of the sidebar and in the mobile drawer. + 'title' => 'On this page', + // Pixel offset to clear the fixed navbar when jumping to a heading. + 'navbarHeight' => 80, + // Viewport width (px) at which the fixed sidebar appears. + // Below this width the mobile floating-button drawer is used instead. + 'minWidth' => 1280, + ); + } + + // ---- Admin settings form ---- + + public function form() { + global $L; + + $title = htmlspecialchars($this->getDbField('title'), ENT_QUOTES, 'UTF-8'); + $navbarHeight = (int) $this->getDbField('navbarHeight'); + $minWidth = (int) $this->getDbField('minWidth'); + + $h = ''; + + $h .= '
'; + $h .= ''; + $h .= ''; + $h .= '
'; + + $h .= '
'; + $h .= ''; + $h .= ''; + $h .= '' . $L->get('Used to offset hash-jump anchors so they clear the fixed navbar.') . ''; + $h .= '
'; + + $h .= '
'; + $h .= ''; + $h .= ''; + $h .= '' . $L->get('Viewport widths below this value use the mobile floating button instead.') . ''; + $h .= '
'; + + return $h; + } + + // ---- Front-end hooks ---- + + /** + * Inject the plugin CSS in . + */ + public function siteHead() { + $url = DOMAIN_PLUGINS . $this->directoryName . '/toc.css'; + return HTML::style($url) . PHP_EOL; + } + + /** + * Inject the ToC sidebar container right after . + * It is position:fixed, so placement in the DOM doesn't affect layout. + * JS will populate