From 6cec5a987eb520e9e194272756e383891a156b06 Mon Sep 17 00:00:00 2001 From: Sally Makin Date: Mon, 19 Jan 2026 10:35:22 +0000 Subject: [PATCH 1/3] remove CLA check --- .github/pull_request_template.md | 8 -------- .github/workflows/cla-check.yaml | 13 ------------- docs/contributing/index.md | 11 ----------- 3 files changed, 32 deletions(-) delete mode 100644 .github/workflows/cla-check.yaml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 5b51c8c7..16af5bc3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -19,14 +19,6 @@ Example: --- -### Contributor License Agreement (CLA) - -By contributing to this project, you agree to the terms of -the [Canonical Contributor License Agreement (CLA)](https://ubuntu.com/legal/contributors). -If you have not already signed the CLA, [please do so here](https://ubuntu.com/legal/contributors). - ---- - ### Commit Message for Squash Merge We typically squash commits when merging. You can specify the commit message that should be used in this case if you wish. diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml deleted file mode 100644 index 56b465cb..00000000 --- a/.github/workflows/cla-check.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# This workflow checks if the contributor has signed the Canonical Contributor Licence Agreement (CLA) -name: Canonical Contributor Licence Agreement check - -on: - pull_request: - branches: [main] - -jobs: - cla-check: - runs-on: ubuntu-latest - steps: - - name: Check if CLA signed - uses: canonical/has-signed-canonical-cla@v2 diff --git a/docs/contributing/index.md b/docs/contributing/index.md index 6bfd8675..7d2386a5 100644 --- a/docs/contributing/index.md +++ b/docs/contributing/index.md @@ -45,17 +45,6 @@ There are some prerequisites to contributing to Ubuntu Server documentation. tasks can be done using [GitHub's web interface](https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files). On the command line, we use the standard "fork and pull" process. -- **Licensing** - The first time you contribute to a Canonical project, you will need to sign - the Canonical License agreement (CLA). If you have already signed it, e.g. - when contributing to another Canonical project, you do not need to sign it - again. - - This license protects your copyright over your contributions, including the - right to use them elsewhere, but grants us (Canonical) permission to use - them in our project. You can read [more about the CLA](https://canonical.com/legal/contributors) before you - [sign the CLA](https://canonical.com/legal/contributors/agreement). - ## The Ubuntu Server docs overview This documentation is [hosted in GitHub](https://github.com/canonical/ubuntu-server-documentation) and rendered on Read the Docs. You From 97db0d6169abfdc857d90b25935d4d056aeee6e8 Mon Sep 17 00:00:00 2001 From: Sally Makin Date: Mon, 19 Jan 2026 15:11:48 +0000 Subject: [PATCH 2/3] Testing changes to tooltip css --- docs/.sphinx/_static/css/custom.css | 112 ++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/docs/.sphinx/_static/css/custom.css b/docs/.sphinx/_static/css/custom.css index 8649f712..a68f89bd 100644 --- a/docs/.sphinx/_static/css/custom.css +++ b/docs/.sphinx/_static/css/custom.css @@ -391,3 +391,115 @@ p code.literal { .highlight .o { color: #BB5400; } + +/* Hoverxref tooltip dark mode support + The hoverxref extension uses Tippy.js which renders tooltips with light backgrounds by default. + These styles ensure tooltips match the current theme (light/dark mode). */ + +/* Light mode tooltip styles (default) */ +.tippy-box[data-theme~='material'] { + background-color: #fff; + color: #111; + border: 1px solid #e0e0e0; +} + +.tippy-box[data-theme~='material'] .tippy-content { + background-color: #fff; + color: #111; +} + +.tippy-box[data-theme~='material'][data-placement^='top'] > .tippy-arrow::before { + border-top-color: #e0e0e0; +} + +.tippy-box[data-theme~='material'][data-placement^='bottom'] > .tippy-arrow::before { + border-bottom-color: #e0e0e0; +} + +.tippy-box[data-theme~='material'][data-placement^='left'] > .tippy-arrow::before { + border-left-color: #e0e0e0; +} + +.tippy-box[data-theme~='material'][data-placement^='right'] > .tippy-arrow::before { + border-right-color: #e0e0e0; +} + +/* Dark mode tooltip styles - when user selects dark theme */ +@media not print { + body[data-theme="dark"] .tippy-box[data-theme~='material'] { + background-color: #2b2b2b; + color: #f7f7f7; + border: 1px solid #555; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'] .tippy-content { + background-color: #2b2b2b; + color: #f7f7f7; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='top'] > .tippy-arrow::before { + border-top-color: #555; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='bottom'] > .tippy-arrow::before { + border-bottom-color: #555; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='left'] > .tippy-arrow::before { + border-left-color: #555; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='right'] > .tippy-arrow::before { + border-right-color: #555; + } + + /* Style links within tooltips for dark mode */ + body[data-theme="dark"] .tippy-box[data-theme~='material'] a { + color: #58a6ff; + } + + body[data-theme="dark"] .tippy-box[data-theme~='material'] code { + background-color: #3b3b3b; + color: #e0e0e0; + } +} + +/* Dark mode tooltip styles - when system prefers dark scheme */ +@media (prefers-color-scheme: dark) { + body:not([data-theme="light"]) .tippy-box[data-theme~='material'] { + background-color: #2b2b2b; + color: #f7f7f7; + border: 1px solid #555; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'] .tippy-content { + background-color: #2b2b2b; + color: #f7f7f7; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='top'] > .tippy-arrow::before { + border-top-color: #555; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='bottom'] > .tippy-arrow::before { + border-bottom-color: #555; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='left'] > .tippy-arrow::before { + border-left-color: #555; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='right'] > .tippy-arrow::before { + border-right-color: #555; + } + + /* Style links within tooltips for dark mode */ + body:not([data-theme="light"]) .tippy-box[data-theme~='material'] a { + color: #58a6ff; + } + + body:not([data-theme="light"]) .tippy-box[data-theme~='material'] code { + background-color: #3b3b3b; + color: #e0e0e0; + } +} From c40b52e0e11b9b346c38fdbfcbfb471227fe843a Mon Sep 17 00:00:00 2001 From: Sally Makin Date: Mon, 19 Jan 2026 17:16:44 +0000 Subject: [PATCH 3/3] More experiments, can't preview changes locally --- docs/.sphinx/_static/css/custom.css | 121 +++++--------- .../.sphinx/_static/js/hoverxref-dark-mode.js | 156 ++++++++++++++++++ docs/conf.py | 1 + 3 files changed, 199 insertions(+), 79 deletions(-) create mode 100644 docs/.sphinx/_static/js/hoverxref-dark-mode.js diff --git a/docs/.sphinx/_static/css/custom.css b/docs/.sphinx/_static/css/custom.css index a68f89bd..1d0527a5 100644 --- a/docs/.sphinx/_static/css/custom.css +++ b/docs/.sphinx/_static/css/custom.css @@ -394,7 +394,8 @@ p code.literal { /* Hoverxref tooltip dark mode support The hoverxref extension uses Tippy.js which renders tooltips with light backgrounds by default. - These styles ensure tooltips match the current theme (light/dark mode). */ + Tippy appends tooltips directly to body, so we use a .dark-mode class added by JavaScript + (see hoverxref-dark-mode.js) rather than relying on theme context selectors. */ /* Light mode tooltip styles (default) */ .tippy-box[data-theme~='material'] { @@ -424,82 +425,44 @@ p code.literal { border-right-color: #e0e0e0; } -/* Dark mode tooltip styles - when user selects dark theme */ -@media not print { - body[data-theme="dark"] .tippy-box[data-theme~='material'] { - background-color: #2b2b2b; - color: #f7f7f7; - border: 1px solid #555; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'] .tippy-content { - background-color: #2b2b2b; - color: #f7f7f7; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='top'] > .tippy-arrow::before { - border-top-color: #555; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='bottom'] > .tippy-arrow::before { - border-bottom-color: #555; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='left'] > .tippy-arrow::before { - border-left-color: #555; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'][data-placement^='right'] > .tippy-arrow::before { - border-right-color: #555; - } - - /* Style links within tooltips for dark mode */ - body[data-theme="dark"] .tippy-box[data-theme~='material'] a { - color: #58a6ff; - } - - body[data-theme="dark"] .tippy-box[data-theme~='material'] code { - background-color: #3b3b3b; - color: #e0e0e0; - } -} - -/* Dark mode tooltip styles - when system prefers dark scheme */ -@media (prefers-color-scheme: dark) { - body:not([data-theme="light"]) .tippy-box[data-theme~='material'] { - background-color: #2b2b2b; - color: #f7f7f7; - border: 1px solid #555; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'] .tippy-content { - background-color: #2b2b2b; - color: #f7f7f7; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='top'] > .tippy-arrow::before { - border-top-color: #555; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='bottom'] > .tippy-arrow::before { - border-bottom-color: #555; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='left'] > .tippy-arrow::before { - border-left-color: #555; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'][data-placement^='right'] > .tippy-arrow::before { - border-right-color: #555; - } - - /* Style links within tooltips for dark mode */ - body:not([data-theme="light"]) .tippy-box[data-theme~='material'] a { - color: #58a6ff; - } - - body:not([data-theme="light"]) .tippy-box[data-theme~='material'] code { - background-color: #3b3b3b; - color: #e0e0e0; - } +/* Dark mode tooltip styles - applied via .dark-mode class by JavaScript */ +.tippy-box[data-theme~='material'].dark-mode { + background-color: #2b2b2b; + color: #f7f7f7; + border: 1px solid #555; +} + +.tippy-box[data-theme~='material'].dark-mode .tippy-content { + background-color: #2b2b2b; + color: #f7f7f7; +} + +.tippy-box[data-theme~='material'].dark-mode[data-placement^='top'] > .tippy-arrow::before { + border-top-color: #555; +} + +.tippy-box[data-theme~='material'].dark-mode[data-placement^='bottom'] > .tippy-arrow::before { + border-bottom-color: #555; +} + +.tippy-box[data-theme~='material'].dark-mode[data-placement^='left'] > .tippy-arrow::before { + border-left-color: #555; +} + +.tippy-box[data-theme~='material'].dark-mode[data-placement^='right'] > .tippy-arrow::before { + border-right-color: #555; +} + +/* Style links within dark mode tooltips */ +.tippy-box[data-theme~='material'].dark-mode a { + color: #58a6ff; +} + +/* Style code blocks within dark mode tooltips */ +.tippy-box[data-theme~='material'].dark-mode code { + background-color: #3b3b3b; + color: #e0e0e0; + border: 1px solid #555; + padding: 0.1em 0.3em; + border-radius: 3px; } diff --git a/docs/.sphinx/_static/js/hoverxref-dark-mode.js b/docs/.sphinx/_static/js/hoverxref-dark-mode.js new file mode 100644 index 00000000..4e2dfd67 --- /dev/null +++ b/docs/.sphinx/_static/js/hoverxref-dark-mode.js @@ -0,0 +1,156 @@ +/** + * Hoverxref Dark Mode Support + * + * This script ensures that hoverxref tooltips (powered by Tippy.js) + * adapt to the current theme (light/dark mode). + * + * Tippy.js appends tooltip elements directly to the body, outside the + * themed content area, so we need to dynamically update their styling + * based on the current theme. + */ + +(function() { + 'use strict'; + + /** + * Get the current theme from the body's data-theme attribute + * @returns {string} 'light', 'dark', or 'auto' + */ + function getCurrentTheme() { + return document.body.getAttribute('data-theme') || 'auto'; + } + + /** + * Determine if dark mode should be active + * @returns {boolean} + */ + function isDarkMode() { + const theme = getCurrentTheme(); + if (theme === 'dark') { + return true; + } else if (theme === 'light') { + return false; + } else { + // Theme is 'auto', check system preference + return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + } + } + + /** + * Update all visible tooltips to match the current theme + */ + function updateTooltipThemes() { + const tooltips = document.querySelectorAll('.tippy-box'); + const darkMode = isDarkMode(); + + tooltips.forEach(function(tooltip) { + if (darkMode) { + tooltip.classList.add('dark-mode'); + } else { + tooltip.classList.remove('dark-mode'); + } + }); + } + + /** + * Set up a MutationObserver to watch for new tooltips being added to the DOM + */ + function observeTooltips() { + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + mutation.addedNodes.forEach(function(node) { + // Check if the added node is a tooltip or contains tooltips + if (node.nodeType === 1) { // Element node + if (node.classList && node.classList.contains('tippy-box')) { + // A tooltip was added + if (isDarkMode()) { + node.classList.add('dark-mode'); + } + } else if (node.querySelectorAll) { + // Check for tooltips within the added node + const tooltips = node.querySelectorAll('.tippy-box'); + if (tooltips.length > 0 && isDarkMode()) { + tooltips.forEach(function(tooltip) { + tooltip.classList.add('dark-mode'); + }); + } + } + } + }); + }); + }); + + // Observe the body for tooltip additions + observer.observe(document.body, { + childList: true, + subtree: true + }); + } + + /** + * Watch for theme changes on the body element + */ + function observeThemeChanges() { + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') { + updateTooltipThemes(); + } + }); + }); + + observer.observe(document.body, { + attributes: true, + attributeFilter: ['data-theme'] + }); + } + + /** + * Watch for system color scheme preference changes + */ + function observeSystemThemeChanges() { + if (window.matchMedia) { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + + // Modern browsers + if (mediaQuery.addEventListener) { + mediaQuery.addEventListener('change', function() { + // Only update if theme is set to 'auto' + if (getCurrentTheme() === 'auto') { + updateTooltipThemes(); + } + }); + } else if (mediaQuery.addListener) { + // Fallback for older browsers + mediaQuery.addListener(function() { + if (getCurrentTheme() === 'auto') { + updateTooltipThemes(); + } + }); + } + } + } + + /** + * Initialize the dark mode support + */ + function init() { + // Wait for DOM to be ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function() { + observeTooltips(); + observeThemeChanges(); + observeSystemThemeChanges(); + updateTooltipThemes(); + }); + } else { + observeTooltips(); + observeThemeChanges(); + observeSystemThemeChanges(); + updateTooltipThemes(); + } + } + + // Start the script + init(); +})(); diff --git a/docs/conf.py b/docs/conf.py index 0de0f2f7..3f44a8f9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -178,6 +178,7 @@ "js/header-nav.js", "js/github_issue_links.js", "js/bundle.js", + "js/hoverxref-dark-mode.js", ] source_suffix = {