/* app.js - fetch only when Refresh is pressed */ (function () { function $(id) { return document.getElementById(id); } function parseQuery() { var out = {}; var qs = window.location.search || ""; if (qs.indexOf("?") === 0) qs = qs.substring(1); if (!qs) return out; var parts = qs.split("&"); for (var i = 0; i < parts.length; i++) { var kv = parts[i].split("="); var k = decodeURIComponent(kv[0] || "").trim(); var v = decodeURIComponent(kv.slice(1).join("=") || "").trim(); if (k) out[k] = v; } return out; } function setQuery(params) { var keys = []; for (var k in params) { if (params.hasOwnProperty(k) && params[k] !== "" && params[k] != null) { keys.push(encodeURIComponent(k) + "=" + encodeURIComponent(params[k])); } } var qs = keys.length ? ("?" + keys.join("&")) : ""; if (window.history && window.history.replaceState) { window.history.replaceState(null, "", window.location.pathname + qs); } } function findById(arr, id, fallback) { for (var i = 0; i < arr.length; i++) if (arr[i].id === id) return arr[i]; return fallback || null; } function buildFeedUrl(feed, region) { var base; if (feed.type === "top") { base = "https://news.google.com/rss"; } else if (feed.type === "topic" && feed.topic) { base = "https://news.google.com/rss/headlines/section/topic/" + encodeURIComponent(feed.topic); } else { base = "https://news.google.com/rss"; } var q = []; q.push("hl=" + encodeURIComponent(region.hl)); q.push("gl=" + encodeURIComponent(region.gl)); q.push("ceid=" + encodeURIComponent(region.ceid)); return base + "?" + q.join("&"); } function fetchText(url, cb) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.timeout = 15000; xhr.onreadystatechange = function () { if (xhr.readyState !== 4) return; if (xhr.status >= 200 && xhr.status < 300) return cb(null, xhr.responseText); cb(new Error("HTTP " + xhr.status + " while fetching feed")); }; xhr.ontimeout = function () { cb(new Error("Timed out while fetching feed")); }; xhr.onerror = function () { cb(new Error("Network error while fetching feed")); }; xhr.send(null); } function safeText(s) { if (s == null) return ""; return String(s); } function escapeHtml(s) { s = safeText(s); return s .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function escapeAttr(s) { return escapeHtml(s); } function stripHtml(s) { return safeText(s).replace(/<[^>]*>/g, ""); } function parseRss(xmlText) { var items = []; var doc = null; if (window.DOMParser) { try { doc = new DOMParser().parseFromString(xmlText, "text/xml"); } catch (e) { doc = null; } } if (!doc || !doc.getElementsByTagName) return items; var nodes = doc.getElementsByTagName("item"); for (var i = 0; i < nodes.length; i++) { var it = nodes[i]; function get(tag) { var n = it.getElementsByTagName(tag); if (!n || !n[0] || !n[0].textContent) return ""; return n[0].textContent; } var title = get("title"); var link = get("link"); var pubDate = get("pubDate"); var desc = get("description"); var source = ""; if (title.indexOf(" - ") !== -1) { var parts = title.split(" - "); source = parts[parts.length - 1]; } items.push({ title: title, link: link, pubDate: pubDate, source: source, description: desc }); } return items; } function showError(msg, show) { var el = $("error"); if (!el) return; if (show) { el.style.display = "block"; el.textContent = msg; } else { el.style.display = "none"; el.textContent = ""; } } function renderItems(items) { var host = $("items"); host.innerHTML = ""; if (!items || !items.length) { host.innerHTML = "