PageSourceSearch

https://www.correiodamanha.com.br/js/cm/components/MobileMenu.js?ver=7.0.38

js correiodamanha.com.br collected 2026-09-24 21:41:09 UTC 11,641 bytes, 273 lines download raw bytes

1/**
2 * Mobile Menu Component
3 * Standardized overlay for mobile navigation across all portal products
4 */
5
6const MobileMenu = {
7  getHomeSectionHref(sectionId) {
8    const safeSectionId = String(sectionId || "").replace(/^#/, "");
9    if (!safeSectionId) return "https://www.correiodamanha.com.br/";
10
11    const productRoutes = {
12      "rio-de-janeiro": "https://www.correiodamanha.com.br/cm/rio",
13      "sao-paulo": "https://www.correiodamanha.com.br/cm/sp",
14      "campinas": "https://www.correiodamanha.com.br/cm/campinas",
15      "distrito-federal": "https://www.correiodamanha.com.br/cm/df",
16      "petropolis": "https://www.correiodamanha.com.br/cm/petropolitano",
17      "sul-fluminense": "https://www.correiodamanha.com.br/cm/sul-fluminense",
18      "jornal-da-barra": "https://www.correiodamanha.com.br/cm/barra",
19      "jornal-de-turismo": "https://www.correiodamanha.com.br/cm/turismo",
20      "jornal-servidor": "https://www.correiodamanha.com.br/cm/servidor",
21    };
22
23    if (productRoutes[safeSectionId]) {
24      return productRoutes[safeSectionId];
25    }
26
27    const sectionRoutes = {
28      opiniao: "https://www.correiodamanha.com.br/opiniao",
29      magnavita: "https://www.correiodamanha.com.br/colunistas/magnavita",
30      politica: "https://www.correiodamanha.com.br/politica",
31      economia: "https://www.correiodamanha.com.br/economia",
32      justica: "https://www.correiodamanha.com.br/justica",
33      cultura: "https://www.correiodamanha.com.br/cultura",
34      esporte: "https://www.correiodamanha.com.br/esporte/esporte",
35      esportes: "https://www.correiodamanha.com.br/esporte/esporte",
36      mundo: "https://www.correiodamanha.com.br/mundo",
37    };
38
39    if (sectionRoutes[safeSectionId]) {
40      return sectionRoutes[safeSectionId];
41    }
42
43    return `#${safeSectionId}`;
44  },
45
46  getColumnsSubmenuHTML() {
47    const items = (window.CMColumns && window.CMColumns.getCatalog()) || [];
48    return items
49      .map(
50        (item) => `
51          <li><a href="${item.url}">${item.label}</a></li>
52        `,
53      )
54      .join("");
55  },
56
57  render() {
58    if (document.getElementById("mobile-menu-overlay")) return;
59    const isProductPage = document.body.classList.contains("is-cm-product-page");
60
61    const overlay = document.createElement("div");
62    overlay.id = "mobile-menu-overlay";
63    overlay.className = "mobile-menu-overlay";
64    overlay.innerHTML = `
65      <div class="mobile-menu-drawer">
66        <div class="mobile-menu-header">
67          <a href="https://www.correiodamanha.com.br/" class="mobile-logo-brand" aria-label="CM - O portal do grupo Correio da Manhã">
68            <span class="mobile-menu-monogram">CM</span>
69            <span class="mobile-menu-brand-rule" aria-hidden="true"></span>
70            <span class="mobile-logo-text">O portal do grupo Correio da Manhã</span>
71          </a>
72          <button class="mobile-menu-close" id="mobile-menu-close" aria-label="Fechar">
73            <i class="fas fa-times"></i>
74          </button>
75        </div>
76
77        <div class="mobile-menu-search">
78          <form class="mobile-search-form" action="/busca.php" method="get" role="search" data-cm-portal-search="true">
79            <input type="search" placeholder="" name="q" id="mobile-search-input" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
80            <button type="submit"><i class="fas fa-search"></i></button>
81          </form>
82        </div>
83
84        <nav class="mobile-nav-links">
85          <ul class="mobile-nav-main">
86            <li><a href="${this.getHomeSectionHref("opiniao")}"><i class="fas fa-comment-alt"></i> Opinião</a></li>
87            <li class="mobile-nav-has-submenu mobile-nav-has-split-link">
88              <div class="mobile-nav-link-row">
89                <a href="${this.getHomeSectionHref("magnavita")}" class="mobile-nav-link-primary">
90                  <i class="fas fa-star"></i> Colunistas
91                </a>
92                <button
93                  class="mobile-submenu-toggle"
94                  aria-expanded="false"
95                  aria-haspopup="true"
96                  aria-controls="mobile-submenu-colunas"
97                  aria-label="Abrir menu de Colunistas"
98                >
99                  <i class="fas fa-chevron-down mobile-submenu-arrow"></i>
100                </button>
101              </div>
102              <ul class="mobile-submenu mobile-submenu-columns" id="mobile-submenu-colunas">
103                ${this.getColumnsSubmenuHTML()}
104              </ul>
105            </li>
106            <li><a href="${this.getHomeSectionHref("politica")}
106"><i class="fas fa-landmark"></i> Política</a></li>
107            <li><a href="${this.getHomeSectionHref("economia")}"><i class="fas fa-chart-line"></i> Economia</a></li>
108            <li><a href="${this.getHomeSectionHref("justica")}"><i class="fas fa-balance-scale"></i> Justiça</a></li>
109            <li><a href="${this.getHomeSectionHref("cultura")}"><i class="fas fa-palette"></i> Cultura & Artes</a></li>
110            <li><a href="${this.getHomeSectionHref("esporte")}"><i class="fas fa-futbol"></i> Esportes</a></li>
111            <li><a href="${this.getHomeSectionHref("mundo")}"><i class="fas fa-globe"></i> Mundo</a></li>
112            ${isProductPage ? "" : `<li><a href="https://www.youtube.com/@TVCorreiodaManh%C3%A3"><i class="fab fa-youtube"></i> CM News TV</a></li>`}
113            <li class="mobile-nav-has-submenu">
114              <button class="mobile-submenu-toggle" aria-expanded="false" aria-haspopup="true">
115                <span><i class="fas fa-newspaper"></i> Nossos Jornais</span>
116                <i class="fas fa-chevron-down mobile-submenu-arrow"></i>
117              </button>
118              <ul class="mobile-submenu" id="mobile-submenu-jornais">
119                <li><a href="${this.getHomeSectionHref("rio-de-janeiro")}">Correio da Manhã RJ</a></li>
120                <li><a href="${this.getHomeSectionHref("sao-paulo")}">Correio da Manhã SP</a></li>
121                <li><a href="${this.getHomeSectionHref("campinas")}">Correio da Manhã Campinas</a></li>
122                <li><a href="${this.getHomeSectionHref("distrito-federal")}">Correio da Manhã DF</a></li>
123                <li><a href="${this.getHomeSectionHref("petropolis")}">Correio Petropolitano</a></li>
124                <li><a href="${this.getHomeSectionHref("sul-fluminense")}">Correio Sul Fluminense</a></li>
125                <li><a href="${this.getHomeSectionHref("jornal-da-barra")}">Jornal da Barra</a></li>
126                <li><a href="${this.getHomeSectionHref("jornal-de-turismo")}">Jornal de Turismo</a></li>
127                <li><a href="${this.getHomeSectionHref("jornal-servidor")}">Jornal do Servidor</a></li>
128              </ul>
129            </li>
130          </ul>
131        </nav>
132
133        <div class="mobile-menu-footer">
134          <div class="mobile-socials">
135            <a href="#" aria-label="Facebook"><i class="fab fa-facebook-f"></i></a>
136            <a href="https://www.instagram.com/correiodamanhabr/" target="_blank" rel="noopener noreferrer" aria-label="Instagram"><i class="fab fa-instagram"></i></a>
137            <a href="#" aria-label="Twitter"><i class="fab fa-twitter"></i></a>
138            <a href="https://www.youtube.com/@TVCorreiodaManhã" target="_blank" rel="noopener noreferrer" aria-label="YouTube"><i class="fab fa-youtube"></i></a>
139          </div>
140          <p class="mobile-copyright">© 2026 Correio da Manhã</p>
141        </div>
142      </div>
143    `;
144    document.body.appendChild(overlay);
145    this.init();
146  },
147
148  init() {
149    const closeBtn = document.getElementById("mobile-menu-close");
150    const overlay = document.getElementById("mobile-menu-overlay");
151    const searchForm = overlay?.querySelector(".mobile-search-form");
152
153    if (closeBtn && overlay) {
154      closeBtn.addEventListener("click", () => this.toggle(false));
155      overlay.addEventListener("click", (e) => {
156        if (e.target === overlay) this.toggle(false);
157      });
158    }
159
160    if (searchForm) {
161      searchForm.addEventListener("submit", () => {
162        this.toggle(false);
163      });
164    }
165
166    this.initSubmenus();
167
168    const links = overlay?.querySelectorAll(".mobile-nav-main a");
169    links?.forEach((link) => {
170      link.addEventListener("click", (e) => {
171        const href = link.getAttribute("href");
172        const target = this.resolveInPageTarget(href);
173
174        if (target) {
175          e.preventDefault();
176          target.scrollIntoView({ behavior: "smooth", block: "start" });
177          this.toggle(false);
178        } else if (href) {
179          this.toggle(false);
180        }
181      });
182    });
183  },
184
185  resolveInPageTarget(href) {
186    if (!href) return null;
187
188    let hash = "";
189    if (href.startsWith("#")) {
190      hash = href;
191    } else if (href.includes("#")) {
192      const [base, targetHash] = href.split("#");
193      const currentPage =
194        window.location.pathname.split("/").pop() || "index.html";
195      const normalizedBase = base || currentPage;
196
197      if (
198        normalizedBase === currentPage ||
199        (normalizedBase === "index.html" &&
200          (currentPage === "index.html" || currentPage === ""))
201      ) {
202        hash = `#${targetHash}`;
203      }
204    }
205
206    if (!hash || hash === "#") return null;
207    return document.querySelector(hash);
208  },
209
210  initSubmenus() {
211    const toggles = document.querySelectorAll(".mobile-submenu-toggle");
212
213    toggles.forEach((toggle) => {
214      toggle.addEventListener("click", (e) => {
215        e.preventDefault();
216        const submenu = toggle.closest(".mobile-nav-has-submenu").querySelector(".mobile-submenu");
217        const arrow = toggle.querySelector(".mobile-submenu-arrow");
218        const isExpanded = toggle.getAttribute("aria-expanded") === "true";
219
220        toggles.forEach((otherToggle) => {
221          if (otherToggle !== toggle) {
222            otherToggle.setAttribute("aria-expanded", "false");
223            otherToggle.classList.remove("active");
224            const otherSubmenu = otherToggle.closest(".mobile-nav-has-submenu").querySelector(".mobile-submenu");
225            const otherArrow = otherToggle.querySelector(
226              ".mobile-submenu-arrow",
227            );
228            if (otherSubmenu) otherSubmenu.classList.remove("active");
229            if (otherArrow) otherArrow.classList.remove("active");
230          }
231        });
232
233        toggle.setAttribute("aria-expanded", String(!isExpanded));
234        toggle.classList.toggle("active", !isExpanded);
235        if (submenu) submenu.classList.toggle("active", !isExpanded);
236        if (arrow) arrow.classList.toggle("active", !isExpanded);
237      });
238    });
239  },
240
241  toggle(show) {
242    const overlay = document.getElementById("mobile-menu-overlay");
243    if (!overlay) {
244      if (show) {
245        this.render();
246        setTimeout(() => this.toggle(true), 10);
247      }
248      return;
249    }
250
251    if (show) {
252      overlay.classList.add("active");
253      document.body.classList.add("mobile-menu-open");
254      document.body.style.overflow = "hidden";
255    } else {
256      overlay.classList.remove("active");
257      document.body.classList.remove("mobile-menu-open");
258      document.body.style.overflow = "";
259
260      const toggles = document.querySelectorAll(".mobile-submenu-toggle");
261      toggles.forEach((toggle) => {
262        toggle.setAttribute("aria-expanded", "false");
263        toggle.classList.remove("active");
264        const submenu = toggle.closest(".mobile-nav-has-submenu").querySelector(".mobile-submenu");
265        const arrow = toggle.querySelector(".mobile-submenu-arrow");
266        if (submenu) submenu.classList.remove("active");
267        if (arrow) arrow.classList.remove("active");
268      });
269    }
270  },
271};
272
273window.CMMobileMenu = MobileMenu;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.