diff --git a/README.md b/README.md index 546bccc..289c948 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,12 @@ I probably won't write many tests, if any at all + [ ] Settings button & popup + [x] Remove white thingies and replace them by actual borders + [ ] Mashup profiles! / Codeforces automation -+ [ ] Navbar dropdowns ++ [x] Navbar dropdowns + Groups => My Groups, All Groups + Contests => My Contests, All Contests + Add "Friends" tab? -+ [ ] Goal: decrease number of clicks to navigate the site ++ [ ] Goal: decrease number of clicks to navigate the site (partially done with navbar dropdowns!) + [ ] Remove bloat from parcel's bundle -+ [ ] File dropdown to submit -+ [ ] Load pages with ajax so the script doesn't have to load every time (Hard, I think) \ No newline at end of file ++ [ ] File drag & drop to submit ++ [ ] Load pages with ajax so the script doesn't have to load every time (Hard, I think) ++ [ ] "Google this problem" button (for mashups) \ No newline at end of file diff --git a/src/dom.js b/src/dom.js index 61682ec..bffc91c 100644 --- a/src/dom.js +++ b/src/dom.js @@ -1,3 +1,7 @@ +/** + * @file Utilities to manipulate the DOM + */ + module.exports = { $(query, element) { return (element || document).querySelector(query); @@ -5,4 +9,7 @@ module.exports = { $$(query, element) { return (element || document).querySelectorAll(query); }, + on(element, event, handler) { + element.addEventListener(event, handler); + }, }; \ No newline at end of file diff --git a/src/navbar.js b/src/navbar.js new file mode 100644 index 0000000..a942ec7 --- /dev/null +++ b/src/navbar.js @@ -0,0 +1,107 @@ +/** + * @file Provides drowdown menus for the main navbar, for better site navigation + */ + +let dom = require('./dom'); + +module.exports = function() { + // Get user handle + const handle = dom.$('.lang-chooser').children[1].children[0].innerText.trim(); + + let oldNav = dom.$('.main-menu-list'); + let newNav = document.createElement('nav'); + newNav.className = 'cfpp-navbar'; + + // Without this the dropdowns don't appear + oldNav.parentNode.parentNode.style.overflow = 'visible'; + + let keys = { + "/groups": { + "My Groups": `/groups/with/${handle}`, + "My Teams": `/teams/with/${handle}`, + }, + "/problemset": { + "Status": "/problemset/status", + "Friends Status": "/problemset/status?friends=on", + "My Submissions": `/submissions/${handle}`, + "Favourites": `/favourite/problems`, + }, + "/contests": { + "My Contests": `/contests/with/${handle}`, + }, + "/gyms": { + "Mashups": "/mashups", + }, + "/ratings": { + "Friends": "/ratings/friend/true", + }, + }; + + // Iterate over all nav items and include them the new navbar + for (let item of oldNav.children) { + let link = item.children[0]; // tag + + // Create new item and append the old to it + let newItem = document.createElement('div'); + newItem.className = 'cfpp-navbar-item'; + newItem.appendChild(link); + + // Add dropdown menu, if needed + const href = link.getAttribute('href'); + if (keys[href]) { + let dropdown = document.createElement('div'); + dropdown.className = 'cfpp-dropdown'; + + for (let ddText in keys[href]) { + let ddItem = document.createElement('a'); + ddItem.innerText = ddText; + ddItem.href = keys[href][ddText]; + dropdown.appendChild(ddItem); + } + + newItem.appendChild(dropdown); + } + + newNav.appendChild(newItem); + } + + oldNav.replaceWith(newNav); + + + // Create styling for the new menu + const style = ` + .cfpp-navbar { + margin-left: 1.5em; + } + .cfpp-navbar-item { + display: inline-block; + position: relative; + margin-right: 1.5em; + } + .cfpp-navbar-item>a { + color: #212121; + } + .cfpp-dropdown { + position: absolute; + top: 100%; + left: 0; + width: 200%; + z-index: 99; + display: none; + background: #212121; + padding: 1em; + box-shadow: 1px 7px 19px #00000054; + } + .cfpp-dropdown a { + display: block; + color: #E0E0E0; + } + .cfpp-navbar-item:hover .cfpp-dropdown { + display: block; + } + `; + + let styleTag = document.createElement('style'); + styleTag.innerHTML = style; + document.body.appendChild(styleTag); +}; \ No newline at end of file