diff --git a/.DS_Store b/.DS_Store
index f30f425..ca9a239 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/test/script.js b/test/script.js
new file mode 100644
index 0000000..ce6c585
--- /dev/null
+++ b/test/script.js
@@ -0,0 +1,272 @@
+document.addEventListener('DOMContentLoaded', function() {
+ // Elementer for å vise artikler
+ const itavisenArticlesContainer = document.getElementById('itavisen-articles');
+ const teknoArticlesContainer = document.getElementById('tekno-articles');
+
+ // CORS Proxyer for å omgå CORS-begrensninger
+ const corsProxies = [
+ 'https://corsproxy.io/?',
+ 'https://cors-anywhere.herokuapp.com/',
+ 'https://api.codetabs.com/v1/proxy/?quest=',
+ 'https://api.allorigins.win/raw?url='
+ ];
+ let currentProxyIndex = 0;
+ const corsProxy = corsProxies[currentProxyIndex];
+
+ // RSS-feed URLs
+ const itavisenRSSUrl = 'https://itavisen.no/feed/';
+ const teknoRSSUrl = 'https://www.tek.no/feed/'; // Oppdatert til korrekt RSS-feed URL for Tek.no
+
+ // Vis lasteindikatorer
+ itavisenArticlesContainer.innerHTML = '
Laster inn artikler...
';
+ teknoArticlesContainer.innerHTML = 'Laster inn artikler...
';
+
+ // Funksjon for å hente og parse RSS-feed
+ // Funksjon for å prøve alternative proxyer hvis den første feiler
+ async function fetchWithFallbackProxy(url) {
+ let lastError;
+
+ // Prøv hver proxy i rekkefølge
+ for (let i = 0; i < corsProxies.length; i++) {
+ try {
+ const proxyUrl = corsProxies[i] + encodeURIComponent(url);
+ console.log(`Forsøker proxy ${i+1}/${corsProxies.length}: ${corsProxies[i]}`);
+
+ // Legg til timeout for å unngå at forespørselen henger for lenge
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 sekunder timeout
+
+ const response = await fetch(proxyUrl, {
+ signal: controller.signal
+ });
+
+ clearTimeout(timeoutId); // Fjern timeout hvis forespørselen lykkes
+ if (!response.ok) {
+ throw new Error(`HTTP feil! status: ${response.status}`);
+ }
+
+ const text = await response.text();
+
+ // Sjekk om responsen er tom eller ikke inneholder XML
+ if (!text || text.trim() === '') {
+ throw new Error('Mottok tomt dokument fra serveren');
+ }
+
+ // Enkel validering for å sjekke om responsen ser ut som XML
+ if (!text.includes('<') || !text.includes('>')) {
+ throw new Error('Responsen ser ikke ut til å være gyldig XML');
+ }
+
+ return text;
+ } catch (error) {
+ // Spesifikk håndtering av timeout
+ if (error.name === 'AbortError') {
+ console.warn(`Proxy ${i+1} timeout: Forespørselen tok for lang tid`);
+ lastError = new Error('Timeout - forespørselen tok for lang tid');
+ } else {
+ console.warn(`Proxy ${i+1} feilet:`, error.message);
+ lastError = error;
+ }
+ // Fortsett til neste proxy
+ }
+ }
+
+ // Hvis vi kommer hit, har alle proxyer feilet
+ throw new Error(`Alle proxyer feilet. Siste feil: ${lastError.message}`);
+ }
+
+ async function fetchRSSFeed(url, container) {
+ try {
+ console.log(`Forsøker å hente RSS fra: ${url}`);
+
+ // Bruk fallback-mekanismen for å hente data
+ const data = await fetchWithFallbackProxy(url);
+
+ // Sjekk om responsen er tom
+ if (!data || data.trim() === '') {
+ throw new Error('Mottok tomt dokument fra serveren');
+ }
+
+ console.log(`Mottatt data lengde: ${data.length} tegn`);
+ // Logg de første 100 tegnene for debugging
+ console.log(`Første 100 tegn av responsen: ${data.substring(0, 100)}...`);
+
+ const parser = new DOMParser();
+ const xmlDoc = parser.parseFromString(data, 'text/xml');
+
+ // Sjekk om parsing var vellykket
+ const parserError = xmlDoc.querySelector('parsererror');
+ if (parserError) {
+ console.error('XML parsing feilet, detaljer:', parserError.textContent);
+ console.error('Mottatt XML data:', data.substring(0, 500)); // Logg de første 500 tegnene
+ throw new Error('XML parsing feilet: ' + parserError.textContent);
+ }
+
+ // Sjekk om dokumentet har root element
+ const rootElement = xmlDoc.documentElement;
+ if (!rootElement || rootElement.nodeName === 'html') {
+ console.error('Ugyldig XML-dokument mottatt:', data.substring(0, 500));
+ throw new Error('Ugyldig XML-dokument: Mangler root element eller feil format');
+ }
+
+ // Hent artikler fra XML
+ const items = xmlDoc.querySelectorAll('item');
+
+ // Fjern lasteindikatoren
+ container.innerHTML = '';
+
+ // Sjekk om vi har artikler
+ if (items.length === 0) {
+ container.innerHTML = 'Ingen artikler funnet i RSS-feeden.
';
+ return;
+ }
+
+ // Begrens til 10 artikler
+ const maxArticles = Math.min(items.length, 10);
+
+ for (let i = 0; i < maxArticles; i++) {
+ const item = items[i];
+ // Håndterer CDATA-seksjoner i tittel og beskrivelse
+ let title = item.querySelector('title')?.textContent || 'Ingen tittel';
+ title = title.replace(/^\s*\s*$/g, ''); // Fjerner CDATA-markører
+
+ const link = item.querySelector('link')?.textContent || '#';
+ const pubDate = item.querySelector('pubDate')?.textContent || '';
+
+ let description = item.querySelector('description')?.textContent || 'Ingen beskrivelse';
+ description = description.replace(/^\s*\s*$/g, ''); // Fjerner CDATA-markører
+
+ // Formater dato
+ const date = pubDate ? new Date(pubDate) : new Date();
+ const formattedDate = date.toLocaleString('no-NO', {
+ day: '2-digit',
+ month: '2-digit',
+ year: 'numeric',
+ hour: '2-digit',
+ minute: '2-digit'
+ });
+
+ // Sjekk om artikkelen har et bilde (enclosure)
+ let imageUrl = '';
+ const enclosure = item.querySelector('enclosure');
+ if (enclosure && enclosure.getAttribute('url') && enclosure.getAttribute('type')?.startsWith('image/')) {
+ imageUrl = enclosure.getAttribute('url');
+ }
+
+ // Opprett artikkel-element
+ const articleElement = document.createElement('div');
+ articleElement.className = 'article';
+
+ // Legg til bilde hvis tilgjengelig
+ let imageHtml = '';
+ if (imageUrl) {
+ imageHtml = ``;
+ }
+
+ articleElement.innerHTML = `
+
+ ${formattedDate}
+ ${imageHtml}
+ ${stripHtml(description).substring(0, 150)}...
+ `;
+
+ container.appendChild(articleElement);
+ }
+
+ } catch (error) {
+ console.error('Feil ved henting av RSS feed:', error);
+ container.innerHTML = `
+
Kunne ikke laste inn artikler.
+
Feilmelding: ${error.message}
+
Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.
+
`;
+
+ // Logg mer detaljert feilinformasjon til konsollen for debugging
+ if (error.stack) {
+ console.error('Stack trace:', error.stack);
+ }
+ }
+ }
+
+ // Hjelpefunksjon for å fjerne HTML-tags fra tekst
+ function stripHtml(html) {
+ const temp = document.createElement('div');
+ temp.innerHTML = html;
+ return temp.textContent || temp.innerText || '';
+ }
+
+ // Hjelpefunksjon for å forsøke å hente RSS med retry
+ async function fetchWithRetry(url, container, maxRetries = 2) {
+ let retryCount = 0;
+ let lastError;
+
+ while (retryCount <= maxRetries) {
+ try {
+ if (retryCount > 0) {
+ console.log(`Forsøker på nytt (${retryCount}/${maxRetries}) for ${url}`);
+ // Vis melding om at vi prøver på nytt
+ container.innerHTML = `Forsøker på nytt (${retryCount}/${maxRetries})...
`;
+ // Vent litt før neste forsøk
+ await new Promise(resolve => setTimeout(resolve, 1500));
+ }
+
+ await fetchRSSFeed(url, container);
+ return; // Vellykket, avslutt retry-løkken
+ } catch (error) {
+ lastError = error;
+ console.warn(`Forsøk ${retryCount + 1}/${maxRetries + 1} feilet for ${url}:`, error.message);
+ retryCount++;
+ }
+ }
+
+ // Hvis vi kommer hit, har alle forsøk feilet
+ console.error(`Alle forsøk feilet for ${url}:`, lastError);
+ container.innerHTML = `
+
Kunne ikke laste inn artikler etter flere forsøk.
+
Feilmelding: ${lastError.message}
+
Prøv å oppdatere siden eller sjekk nettverkstilkoblingen din.
+
`;
+ }
+
+ // Hent artikler fra begge kilder med retry-mekanisme
+ fetchWithRetry(itavisenRSSUrl, itavisenArticlesContainer);
+ fetchWithRetry(teknoRSSUrl, teknoArticlesContainer);
+
+ // Legg til knapp for å oppdatere feeds
+ const header = document.querySelector('header');
+ const refreshButton = document.createElement('button');
+ refreshButton.textContent = 'Oppdater nyheter';
+ refreshButton.className = 'refresh-button';
+ refreshButton.addEventListener('click', function() {
+ // Vis lasteindikatorer igjen
+ itavisenArticlesContainer.innerHTML = 'Laster inn artikler...
';
+ teknoArticlesContainer.innerHTML = 'Laster inn artikler...
';
+
+ // Hent artikler på nytt
+ fetchRSSFeed(itavisenRSSUrl, itavisenArticlesContainer);
+ fetchRSSFeed(teknoRSSUrl, teknoArticlesContainer);
+ });
+
+ header.appendChild(refreshButton);
+
+ // Legg til stil for oppdateringsknappen
+ const style = document.createElement('style');
+ style.textContent = `
+ .refresh-button {
+ background-color: #3498db;
+ color: white;
+ border: none;
+ padding: 10px 15px;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ margin-top: 15px;
+ transition: background-color 0.3s;
+ }
+
+ .refresh-button:hover {
+ background-color: #2980b9;
+ }
+ `;
+ document.head.appendChild(style);
+});