repos
/ newtab master

newtab

mirror archived upstream

A clean new tab page extension for Chrome, easy to grab and customize yourself.

browser-extensionchromechrome-extensioncsshandcodedhtmljavascriptnewtab

9.2 KB · 281 lines · JavaScript Raw History
  1/* ---------------------------------------------------------------------------*/
  2/* 01 Time                                                                    */
  3/* ---------------------------------------------------------------------------*/
  4
  5let currentTimeElement = document.getElementById("currentTime");
  6
  7const updateTime = () => {
  8  const currentTime = new Date();
  9
 10  let hours = currentTime.getHours();
 11  if (hours > 12) {
 12    hours -= 12;
 13  }
 14  if (hours === 0) {
 15    hours = 12;
 16  }
 17
 18  let minutes = currentTime.getMinutes();
 19  if (minutes < 10) {
 20    minutes = "0" + minutes;
 21  }
 22
 23  const timeString = `${hours}:${minutes}`;
 24  currentTimeElement.innerHTML = timeString;
 25};
 26
 27updateTime();
 28setInterval(updateTime, 1000);
 29
 30/* ---------------------------------------------------------------------------*/
 31/* 02 Date                                                                    */
 32/* ---------------------------------------------------------------------------*/
 33
 34let currentDateElement = document.getElementById("currentDate");
 35
 36const updateDate = () => {
 37  const currentDate = new Date();
 38
 39  let day = currentDate.getDay();
 40  let month = currentDate.getMonth();
 41  let dayOfMonth = currentDate.getDate();
 42
 43  const monthNames = [
 44    "January",
 45    "February",
 46    "March",
 47    "April",
 48    "May",
 49    "June",
 50    "July",
 51    "August",
 52    "September",
 53    "October",
 54    "November",
 55    "December",
 56  ];
 57
 58  const dayNames = [
 59    "Sunday",
 60    "Monday",
 61    "Tuesday",
 62    "Wednesday",
 63    "Thursday",
 64    "Friday",
 65    "Saturday",
 66  ];
 67
 68  const dateString = `${dayNames[day]}, ${monthNames[month]} ${dayOfMonth}`;
 69  currentDateElement.innerHTML = dateString;
 70};
 71
 72updateDate();
 73setInterval(updateDate, 1000);
 74
 75/* ---------------------------------------------------------------------------*/
 76/* 03 Weather                                                                 */
 77/* ---------------------------------------------------------------------------*/
 78
 79const currentWeatherElement = document.getElementById("currentWeather");
 80
 81const fetchWeather = () => {
 82  fetch(
 83    "https://www.accuweather.com/en/us/morganton/28655/weather-forecast/334823"
 84  )
 85    .then((response) => response.text())
 86    .then((html) => {
 87      const parser = new DOMParser();
 88      const doc = parser.parseFromString(html, "text/html");
 89      const currentWeather = doc.querySelector(".forecast-container");
 90
 91      const weatherIcon = currentWeather.querySelector(".weather-icon");
 92      weatherIcon.style.width = "128";
 93      weatherIcon.style.height = "128";
 94
 95      const realFeel = currentWeather.querySelector(".real-feel");
 96      realFeel.remove();
 97
 98      currentWeatherElement.innerHTML = currentWeather.innerHTML;
 99
100      const currentWeatherString = currentWeather.innerHTML;
101      const currentWeatherObject = {
102        timestamp: Date.now(),
103        weather: currentWeatherString,
104      };
105      chrome.storage.local.set({ currentWeather: currentWeatherObject });
106    });
107};
108
109const getCurrentWeather = () => {
110  chrome.storage.local.get("currentWeather", (result) => {
111    const currentTimestamp = new Date();
112    if (result.currentWeather) {
113      if (currentTimestamp - result.currentWeather.timestamp < 1000 * 60 * 60) {
114        currentWeatherElement.innerHTML = result.currentWeather.weather;
115        return;
116      }
117    }
118    fetchWeather();
119  });
120};
121
122getCurrentWeather();
123setInterval(getCurrentWeather, 1000 * 60 * 60);
124
125/* ---------------------------------------------------------------------------*/
126/* 04 Posts                                                                   */
127/* ---------------------------------------------------------------------------*/
128
129const currentPostsElement = document.getElementById("currentPosts");
130
131const getTopPosts = () => {
132  const currentPostsList = document.createElement("ul");
133  currentPostsElement.innerHTML = "";
134
135  fetch("https://hacker-news.firebaseio.com/v0/topstories.json")
136    .then((response) => response.json())
137    .then((json) => {
138      const topPosts = json.slice(0, 5);
139      const topPostsPromises = topPosts.map((id) => {
140        return fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)
141          .then((response) => response.json())
142          .then((json) => {
143            return json;
144          });
145      });
146      return Promise.all(topPostsPromises);
147    })
148    .then((topPosts) => {
149      topPosts.forEach((post) => {
150        const postElement = document.createElement("li");
151        const postLink = document.createElement("a");
152        postLink.href = `https://news.ycombinator.com/item?id=${post.id}`;
153
154        const postExtras = document.createElement("span");
155        postExtras.innerHTML = `<span>${post.score}</span>`;
156        postLink.appendChild(postExtras);
157
158        postLink.innerHTML += post.title;
159
160        postElement.appendChild(postLink);
161        currentPostsList.appendChild(postElement);
162      });
163    });
164
165  currentPostsElement.innerHTML = "";
166  currentPostsElement.appendChild(currentPostsList);
167};
168
169getTopPosts();
170
171/* ---------------------------------------------------------------------------*/
172/* 05 Bookmarks                                                               */
173/* ---------------------------------------------------------------------------*/
174
175const currentBookmarksElement = document.getElementById("currentBookmarks");
176
177const faviconFolder = `\
178<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="white" viewBox="0 0 16 16">
179  <path d="M9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.825a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3zm-8.322.12C1.72 3.042 1.95 3 2.19 3h5.396l-.707-.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139z"/>
180</svg>`;
181const faviconEdit = `\
182<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="white" viewBox="0 0 16 16">
183  <path d="M2 15.5a.5.5 0 0 0 .74.439L8 13.069l5.26 2.87A.5.5 0 0 0 14 15.5V2a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13.5zM8 4.41c1.387-1.425 4.854 1.07 0 4.277C3.146 5.48 6.613 2.986 8 4.412z"/>
184</svg>`;
185const faviconDocument = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgZmlsbD0id2hpdGUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTkuMjkzIDBINGEyIDIgMCAwIDAtMiAydjEyYTIgMiAwIDAgMCAyIDJoOGEyIDIgMCAwIDAgMi0yVjQuNzA3QTEgMSAwIDAgMCAxMy43MDcgNEwxMCAuMjkzQTEgMSAwIDAgMCA5LjI5MyAwek05LjUgMy41di0ybDMgM2gtMmExIDEgMCAwIDEtMS0xek00LjUgOWEuNS41IDAgMCAxIDAtMWg3YS41LjUgMCAwIDEgMCAxaC03ek00IDEwLjVhLjUuNSAwIDAgMSAuNS0uNWg3YS41LjUgMCAwIDEgMCAxaC03YS41LjUgMCAwIDEtLjUtLjV6bS41IDIuNWEuNS41IDAgMCAxIDAtMWg0YS41LjUgMCAwIDEgMCAxaC00eiIvPgo8L3N2Zz4K`;
186
187const getBookmarks = () => {
188  try {
189    return chrome.bookmarks.getTree().then((bookmarks) => {
190      const children = bookmarks[0].children;
191      for (let i = 0; i < children.length; i++) {
192        if (children[i].title === "Bookmarks bar") {
193          return children[i].children;
194        }
195      }
196    });
197  } catch (e) {
198    console.log(e);
199  }
200};
201
202const addFavicon = (el, url) => {
203  const image = new Image();
204  image.src = url;
205  image.width = 14;
206  image.height = 14;
207  image.onload = () => {
208    el.prepend(image);
209  };
210  image.onerror = () => {
211    image.src = faviconDocument;
212    el.prepend(image);
213  };
214};
215
216const createBookmarksList = (bookmarks) => {
217  const bookmarksList = document.createElement("ul");
218  bookmarks.forEach((bookmark) => {
219    const bookmarkElement = document.createElement("li");
220    const bookmarkLink = document.createElement("a");
221
222    if (bookmark.url) {
223      const faviconUrl = new URL(bookmark.url).origin + "/favicon.ico";
224      addFavicon(bookmarkLink, faviconUrl);
225      bookmarkLink.href = bookmark.url;
226    } else {
227      bookmarkLink.href = "#";
228      const folderIcon = document.createElement("span");
229      folderIcon.innerHTML = faviconFolder;
230      bookmarkLink.appendChild(folderIcon);
231    }
232
233    bookmarkLink.innerHTML += bookmark.title;
234    bookmarkElement.appendChild(bookmarkLink);
235    bookmarksList.appendChild(bookmarkElement);
236    if (bookmark.children) {
237      const childrenList = createBookmarksList(bookmark.children);
238      bookmarkElement.appendChild(childrenList);
239    }
240  });
241  return bookmarksList;
242};
243
244const createBookmarksEditLink = () => {
245  const bookmarksList = document.createElement("ul");
246  const bookmarksListItem = document.createElement("li");
247  const bookmarksEditItemLink = document.createElement("a");
248  const bookmarksEditLinkIcon = document.createElement("span");
249
250  bookmarksEditItemLink.target = "_blank";
251  bookmarksEditItemLink.href = "chrome://bookmarks";
252  bookmarksEditItemLink.addEventListener("click", (e) => {
253    e.preventDefault();
254    chrome.tabs.create({ url: "chrome://bookmarks" });
255  });
256
257  bookmarksEditLinkIcon.innerHTML = faviconEdit;
258  bookmarksEditItemLink.appendChild(bookmarksEditLinkIcon);
259
260  bookmarksEditItemLink.innerHTML += "Edit";
261
262  bookmarksListItem.appendChild(bookmarksEditItemLink);
263  bookmarksList.appendChild(bookmarksListItem);
264
265  return bookmarksList;
266};
267
268const updateCurrentBookmarks = () => {
269  try {
270    getBookmarks().then((bookmarks) => {
271      currentBookmarksElement.innerHTML = "";
272      currentBookmarksElement.appendChild(createBookmarksList(bookmarks));
273      currentBookmarksElement.appendChild(createBookmarksEditLink());
274    });
275  } catch (e) {
276    console.log(e);
277  }
278};
279
280updateCurrentBookmarks();