Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 81 additions & 22 deletions docs/assets/javascripts/docs-theme.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,71 @@
var searchReturnTarget;
var tocScrollCleanup;
var footerWidgetObserver;
var persistentLayoutResizeBound;

function closeDrawerForPersistentLayout() {
if (!window.matchMedia("(min-width: 60em)").matches) {
return;
}

var drawerToggle = document.querySelector("#__drawer");
var drawerTrigger = document.querySelector("[data-drawer-trigger]");
if (drawerToggle && drawerToggle.checked) {
drawerToggle.checked = false;
drawerToggle.dispatchEvent(new Event("change"));
}

syncBackgroundInertState();
if (drawerTrigger) {
drawerTrigger.setAttribute("aria-expanded", "false");
drawerTrigger.setAttribute("aria-label", "Open navigation");
}
}
Comment on lines +6 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The closeDrawerForPersistentLayout function is registered as a resize event listener. Since resize events fire rapidly during window resizing, executing DOM queries, querySelectorAll, and attribute modifications on every tick can cause significant layout thrashing and performance degradation (jank). Since we only need to reset the layout when the drawer is actually open, we can return early if the drawer is not checked.

function closeDrawerForPersistentLayout() {
    if (!window.matchMedia("(min-width: 60em)").matches) {
        return;
    }

    var drawerToggle = document.querySelector("#__drawer");
    if (!drawerToggle || !drawerToggle.checked) {
        return;
    }

    var drawerTrigger = document.querySelector("[data-drawer-trigger]");
    drawerToggle.checked = false;
    drawerToggle.dispatchEvent(new Event("change"));

    syncBackgroundInertState();
    if (drawerTrigger) {
        drawerTrigger.setAttribute("aria-expanded", "false");
        drawerTrigger.setAttribute("aria-label", "Open navigation");
    }
}


function syncBackgroundInertState() {
var drawerToggle = document.querySelector("#__drawer");
var searchToggle = document.querySelector("#__search");
var shouldInertContent = Boolean(
(drawerToggle && drawerToggle.checked) || (searchToggle && searchToggle.checked)
);
var shouldInertPrimaryNavigation = Boolean(searchToggle && searchToggle.checked);

document.querySelectorAll(".md-content, .md-sidebar--secondary, footer").forEach(function (element) {
element.toggleAttribute("inert", shouldInertContent);
});
document.querySelectorAll(".md-sidebar--primary").forEach(function (element) {
element.toggleAttribute("inert", shouldInertPrimaryNavigation);
});
}

function initializeMobileProductSwitcher(drawer) {
var switcher = drawer.querySelector("[data-mobile-product-switcher]");
var productItems = Array.prototype.filter.call(
drawer.querySelectorAll(".md-nav--primary > .md-nav__list > .md-nav__item"),
function (item) { return item.classList.contains("md-nav__item--nested"); }
);
if (!switcher || !productItems.length || switcher.dataset.docsMobileProductInitialized) {
return;
}

function selectProduct(index) {
productItems.forEach(function (item, itemIndex) {
var isSelected = itemIndex === index;
item.classList.toggle("docs-mobile-product--selected", isSelected);

});
switcher.value = String(index);
}

var activeIndex = productItems.findIndex(function (item) {
return item.classList.contains("md-nav__item--active");
});
selectProduct(activeIndex >= 0 ? activeIndex : 0);
switcher.dataset.docsMobileProductInitialized = "true";
switcher.addEventListener("change", function () {
selectProduct(Number(switcher.value));
});
}

// Lift the floating support widget (Zendesk) above the footer once the footer
// scrolls into view, so it never overlaps the footer links. Purely additive:
Expand Down Expand Up @@ -84,6 +149,12 @@
element.textContent = String(new Date().getFullYear());
});

if (!persistentLayoutResizeBound) {
persistentLayoutResizeBound = true;
window.addEventListener("resize", closeDrawerForPersistentLayout);
}
closeDrawerForPersistentLayout();

if (tocScrollCleanup) {
tocScrollCleanup();
tocScrollCleanup = undefined;
Expand Down Expand Up @@ -124,46 +195,36 @@
var drawer = document.querySelector(".md-sidebar--primary");
if (drawer) {
drawer.id = "docs-navigation";
initializeMobileProductSwitcher(drawer);
}
// With navigation.instant, Material keeps the header and drawer mounted
// while emitting document$ for each page. Only bind these persistent
// controls once; otherwise every navigation adds another click handler
// and a hamburger tap toggles the checkbox an even number of times.
if (drawerToggle && drawerTrigger && drawer && !drawerTrigger.dataset.docsDrawerInitialized) {
drawerTrigger.dataset.docsDrawerInitialized = "true";
let suppressDrawerKeyboardClick = false;
drawerTrigger.addEventListener("keydown", function (event) {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
suppressDrawerKeyboardClick = true;
drawerToggle.click();
window.setTimeout(function () {
suppressDrawerKeyboardClick = false;
}, 250);
}
});
drawerTrigger.addEventListener("click", function (event) {
event.preventDefault();
if (suppressDrawerKeyboardClick && event.detail === 0) {
return;
}
drawerToggle.click();
});
drawerToggle.addEventListener("change", function () {
drawerTrigger.setAttribute("aria-expanded", String(drawerToggle.checked));
drawerTrigger.setAttribute("aria-label", drawerToggle.checked ? "Close navigation" : "Open navigation");
document.querySelectorAll(".md-content, .md-sidebar--secondary, footer").forEach(function (element) {
element.toggleAttribute("inert", drawerToggle.checked);
});
syncBackgroundInertState();

if (drawerToggle.checked) {
window.setTimeout(function () {
var firstLink = drawer.querySelector(".md-nav__list a[href]");
if (firstLink) {
firstLink.focus();
var navigationControls = drawer.querySelectorAll(".md-nav__link[href], .md-nav__link[tabindex=\"0\"]");

Check warning on line 219 in docs/assets/javascripts/docs-theme.js

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

docs/assets/javascripts/docs-theme.js#L219

Potential secret found.
var firstNavigationControl = Array.prototype.find.call(navigationControls, function (control) {
return control.offsetParent !== null;
});
if (firstNavigationControl) {
firstNavigationControl.focus();
}
}, 0);
} else {
} else if (!window.matchMedia("(min-width: 60em)").matches) {
drawerTrigger.focus();
}
});
Expand Down Expand Up @@ -193,9 +254,7 @@
searchTrigger.setAttribute("aria-expanded", String(searchToggle.checked));
});

document.querySelectorAll(".md-main, footer").forEach(function (element) {
element.toggleAttribute("inert", searchToggle.checked);
});
syncBackgroundInertState();

if (!searchToggle.checked) {
(searchReturnTarget || trigger).focus();
Expand Down
48 changes: 29 additions & 19 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Documentation homepage for the Codacy automated code review tool.

# Codacy documentation

Everything you need to set up Codacy, integrate it into your workflow, and get more value from your code-quality data.
Everything you need to set up Codacy and improve your software quality, AI, security, and coverage outcomes.
{ .docs-home-lead }

<div class="content-columns-wrapper">
Expand All @@ -25,46 +25,56 @@ Everything you need to set up Codacy, integrate it into your workflow, and get m
<section class="content-link-column" aria-labelledby="home-use-codacy">
<h2 id="home-use-codacy">Use Codacy</h2>

<a class="content-link" href="organizations/what-are-organizations/">
<h3>Create and manage an organization</h3>
<p>Bring repositories and teammates together with synchronized Git provider organizations.</p>
<a class="content-link" href="repositories/repository-dashboard/">
<h3>Quality</h3>
<p>Understand repository results and configure analysis that matches your engineering standards.</p>
</a>

<a class="content-link" href="repositories-configure/integrations/github-integration/">
<h3>Set up integrations</h3>
<p>Send analysis feedback and status checks directly to your pull requests.</p>
<a class="content-link" href="codacy-ai/codacy-ai/">
<h3>AI</h3>
<p>Configure AI-assisted code review and triage for your repositories and organization.</p>
</a>

<a class="content-link" href="organizations/managing-security-and-risk/">
<h3>Security</h3>
<p>Identify, prioritize, and manage security findings across your software portfolio.</p>
</a>

<a class="content-link" href="repositories/coverage/">
<h3>Coverage</h3>
<p>Monitor test coverage and set up reporting from your CI workflow.</p>
</a>
</section>
</div>

<h2 id="popular-topics">Popular topics</h2>

<div class="topic-row">
<a class="topic-card" href="organizations/managing-people/">
<a class="topic-card" href="codacy-guardrails/codacy-guardrails-getting-started/">
<div class="tc-icon">
<img alt="People" src="assets/images/icon-user-management.svg">
<img alt="Code" src="assets/images/icon-code.svg">
</div>
<div class="tc-content">
<h3>Manage people</h3>
<p>Invite teammates to analyze their work across private repositories.</p>
<h3>Develop with Codacy</h3>
<p>Use Guardrails, the Cloud CLI, and the API in your engineering workflow.</p>
</div>
</a>
<a class="topic-card" href="coverage-reporter/">
<a class="topic-card" href="organizations/what-are-organizations/">
<div class="tc-icon">
<img alt="Checklist" src="assets/images/icon-checklist.svg">
<img alt="People" src="assets/images/icon-user-management.svg">
</div>
<div class="tc-content">
<h3>Add coverage</h3>
<p>Show repository coverage reports and changes directly in Codacy.</p>
<h3>Manage Codacy</h3>
<p>Manage organizations, people, policies, reporting, and account settings.</p>
</div>
</a>
<a class="topic-card" href="codacy-api/using-the-codacy-api/">
<a class="topic-card" href="release-notes/">
<div class="tc-icon">
<img alt="Code" src="assets/images/icon-code.svg">
<img alt="Checklist" src="assets/images/icon-checklist.svg">
</div>
<div class="tc-content">
<h3>Use the Codacy API</h3>
<p>Retrieve data and automate configuration changes programmatically.</p>
<h3>Release notes</h3>
<p>See the latest updates for Codacy Cloud and Self-hosted.</p>
</div>
</a>
</div>
Loading
Loading