Skip to content

Commit

Permalink
innsida search now contains a menu. Changed the hotkey to be conceque…
Browse files Browse the repository at this point in the history
…nt with other scripts in this repo
  • Loading branch information
on committed Aug 7, 2025
1 parent a9d94e3 commit 0a1b853
Showing 1 changed file with 241 additions and 24 deletions.
265 changes: 241 additions & 24 deletions innsida-search.user.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// ==UserScript==
// @name Innsida - Quick Search
// @namespace http://tampermonkey.net/
// @version 1.0.4
// @description `Alt` + `/` to search on Innsida
// @version 1.2.0
// @description `Ctrl` + `Shift` + `F` to search on Innsida
// @author Øyvind Nilsen (on@ntnu.no)
// @match https://innsida.ntnu.no/*
// @grant none
// @run-at document-end
// @icon https://www.google.com/s2/favicons?sz=64&domain=ntnu.no
// @updateURL https://git.ntnu.no/M365-Drift/MonkeyMagic/raw/main/innsida-search.user.js
// @downloadURL https://git.ntnu.no/M365-Drift/MonkeyMagic/raw/main/innsida-search.user.js
Expand All @@ -14,39 +15,255 @@
(function() {
'use strict';

let currentSelection = 0; // 0 = input box, 1+ = menu items
let menuItems = [];
let links = [];

// Language support
const translations = {
en: {
searchPlaceholder: 'Search Innsida...',
mineNotFound: 'Mine div not found, using default links',
linksFound: 'Found {count} links in "mine" section'
},
nb: {
searchPlaceholder: 'Søk på Innsida...',
mineNotFound: 'Mine-div ikke funnet, bruker standardlenker',
linksFound: 'Fant {count} lenker i "mine"-seksjonen'
},
nn: {
searchPlaceholder: 'Søk på Innsida...',
mineNotFound: 'Mine-div ikkje funne, brukar standardlenkjer',
linksFound: 'Fann {count} lenkjer i "mine"-seksjonen'
}
};

function getCurrentLanguage() {
const lang = localStorage.getItem('colossus_lang') || 'en';
return translations[lang] ? lang : 'en';
}

function t(key, params = {}) {
const lang = getCurrentLanguage();
let text = translations[lang][key] || translations.en[key] || key;

// Replace placeholders
Object.keys(params).forEach(param => {
text = text.replace(`{${param}}`, params[param]);
});

return text;
}

// Create container
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '50%';
container.style.left = '50%';
container.style.transform = 'translate(-50%, -50%)';
container.style.zIndex = '10000';
container.style.display = 'none';
container.style.backgroundColor = 'white';
container.style.border = '2px solid #ccc';
container.style.borderRadius = '8px';
container.style.padding = '20px';
container.style.boxShadow = '0 4px 20px rgba(0,0,0,0.3)';
container.style.minWidth = '300px';
container.style.maxHeight = '80vh';
container.style.overflowY = 'auto';

// Create and style the input box
const inputBox = document.createElement('input');
inputBox.type = 'text';
inputBox.style.position = 'fixed';
inputBox.style.top = '10px';
inputBox.style.left = '50%';
inputBox.style.transform = 'translateX(-50%)';
inputBox.style.zIndex = '10000';
inputBox.style.display = 'none';
inputBox.style.padding = '5px';
inputBox.style.width = '100%';
inputBox.style.padding = '10px';
inputBox.style.fontSize = '16px';
document.body.appendChild(inputBox);
inputBox.style.border = '2px solid #007acc';
inputBox.style.borderRadius = '4px';
inputBox.style.marginBottom = '10px';
inputBox.style.outline = 'none';

// Create menu container
const menu = document.createElement('div');

container.appendChild(inputBox);
container.appendChild(menu);
document.body.appendChild(container);

function loadLinksFromMine() {
const mineDiv = document.querySelector('div#mine');
if (!mineDiv) {
console.log(t('mineNotFound'));
return [
{ text: 'DFØ Selvbetjening', url: 'https://selvbetjening.dfo.no/' },
{ text: 'Bestille', url: 'https://i.ntnu.no/bestille' },
{ text: 'Berg-Hansen', url: 'https://berg-hansen.eu.auth0.com/authorize?client_id=srhy4Jdgs38QCBhnoXBTP58FZ9ES6tmS&response_type=code&connection=Feide&redirect_uri=https://booking.webgate.no/account/callback' },
{ text: 'Parkering Sluppen', url: 'https://innsida.ntnu.no/start/feed/fead7da8-7ddf-3598-96fe-4fc9532a7a0b/6fe863b6-f206-3bb5-9f87-3b169c3a6d45' },
{ text: 'K-Sted', url: 'https://studntnu.sharepoint.com/:x:/s/KommIT/EXdOlr9S_R9ArkhP8IVHLSEBwhcATXuCPXdEwPgNIyVAnw?e=RdaIKK' }
];
}

const linkElements = mineDiv.querySelectorAll('a[href]');
const extractedLinks = [];

linkElements.forEach(linkEl => {
const href = linkEl.getAttribute('href');
const divEl = linkEl.querySelector('div');
const text = divEl ? divEl.textContent.trim() : href;

if (href && text) {
extractedLinks.push({ text, url: href });
}
});

console.log(t('linksFound', { count: extractedLinks.length }));
return extractedLinks.length > 0 ? extractedLinks : [
{ text: 'DFØ Selvbetjening', url: 'https://selvbetjening.dfo.no/' },
{ text: 'Bestille', url: 'https://i.ntnu.no/bestille' },
{ text: 'Berg-Hansen', url: 'https://berg-hansen.eu.auth0.com/authorize?client_id=srhy4Jdgs38QCBhnoXBTP58FZ9ES6tmS&response_type=code&connection=Feide&redirect_uri=https://booking.webgate.no/account/callback' },
{ text: 'Parkering Sluppen', url: 'https://innsida.ntnu.no/start/feed/fead7da8-7ddf-3598-96fe-4fc9532a7a0b/6fe863b6-f206-3bb5-9f87-3b169c3a6d45' },
{ text: 'K-Sted', url: 'https://studntnu.sharepoint.com/:x:/s/KommIT/EXdOlr9S_R9ArkhP8IVHLSEBwhcATXuCPXdEwPgNIyVAnw?e=RdaIKK' }
];
}

function createMenu() {
// Clear existing menu
menu.innerHTML = '';
menuItems = [];

// Load links from "mine" div only
links = loadLinksFromMine();

links.forEach((link, index) => {
const menuItem = document.createElement('div');
menuItem.textContent = link.text;
menuItem.style.padding = '8px 12px';
menuItem.style.cursor = 'pointer';
menuItem.style.borderRadius = '4px';
menuItem.style.marginBottom = '2px';
menuItem.style.backgroundColor = '#f5f5f5';
menuItem.style.border = '1px solid transparent';
menuItem.style.whiteSpace = 'nowrap';
menuItem.style.overflow = 'hidden';
menuItem.style.textOverflow = 'ellipsis';
menuItem.dataset.url = link.url;
menuItem.title = link.url; // Show full URL on hover

menuItem.addEventListener('click', function() {
window.location.href = link.url;
});

// Show the input box when "/" is pressed
menu.appendChild(menuItem);
menuItems.push(menuItem);
});
}

function updateSelection() {
// Reset all styles
inputBox.style.borderColor = '#007acc';
menuItems.forEach(item => {
item.style.backgroundColor = '#f5f5f5';
item.style.borderColor = 'transparent';
item.style.color = 'black';
});

// Highlight current selection
if (currentSelection === 0) {
inputBox.style.borderColor = '#0056b3';
inputBox.focus();
} else if (currentSelection > 0 && currentSelection <= menuItems.length) {
const selectedItem = menuItems[currentSelection - 1];
selectedItem.style.backgroundColor = '#007acc';
selectedItem.style.borderColor = '#0056b3';
selectedItem.style.color = 'white';
inputBox.blur();

// Scroll into view if needed
selectedItem.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
}

function hideContainer() {
container.style.display = 'none';
inputBox.value = '';
currentSelection = 0;
updateSelection();
}

function showContainer() {
// Update placeholder text based on current language
inputBox.placeholder = t('searchPlaceholder');

createMenu(); // Refresh menu each time
container.style.display = 'block';
currentSelection = 0;
updateSelection();
}

// Show the container when Ctrl+Shift+F is pressed
document.addEventListener('keydown', function(event) {
if ((event.altKey || event.metaKey) && event.shiftKey && event.code === 'Digit7') {
if (event.ctrlKey && event.shiftKey && event.key === 'F') {
event.preventDefault();
inputBox.style.display = 'block';
inputBox.focus();
showContainer();
}
});

// Handle navigation and actions
document.addEventListener('keydown', function(event) {
// Only handle keys when container is visible
if (container.style.display === 'none') return;

switch(event.key) {
case 'ArrowDown':
event.preventDefault();
currentSelection++;
if (currentSelection > menuItems.length) {
currentSelection = 0; // Cycle back to search box
}
updateSelection();
break;

case 'ArrowUp':
event.preventDefault();
currentSelection--;
if (currentSelection < 0) {
currentSelection = menuItems.length; // Cycle to last menu item
}
updateSelection();
break;

case 'Enter':
event.preventDefault();
if (currentSelection === 0) {
// Search on Innsida
const searchQuery = inputBox.value.trim();
if (searchQuery) {
const url = `https://innsida.ntnu.no/sok?q=${encodeURIComponent(searchQuery)}&pageSize=10&curPage=1`;
window.location.href = url;
}
} else if (currentSelection > 0 && currentSelection <= menuItems.length) {
// Navigate to selected link
const selectedUrl = menuItems[currentSelection - 1].dataset.url;
window.location.href = selectedUrl;
}
break;

case 'Escape':
event.preventDefault();
hideContainer();
break;
}
});

// Redirect to the search URL when Enter is pressed
inputBox.addEventListener('keydown', function(event) {
if (event.key === 'Enter') {
const searchQuery = inputBox.value.trim();
const url = `https://innsida.ntnu.no/sok?q=${encodeURIComponent(searchQuery)}&pageSize=10&curPage=1`;
window.location.href = url;
// Hide container when clicking outside
document.addEventListener('click', function(event) {
if (!container.contains(event.target)) {
hideContainer();
}
});

// Hide the input box when it loses focus
inputBox.addEventListener('blur', function() {
inputBox.style.display = 'none';
// Prevent container from losing focus when clicking inside
container.addEventListener('click', function(event) {
event.stopPropagation();
});
})();
})();

0 comments on commit 0a1b853

Please sign in to comment.