diff --git a/qutebrowser/html/history.html b/qutebrowser/html/history.html
index 75925f546..33244896c 100644
--- a/qutebrowser/html/history.html
+++ b/qutebrowser/html/history.html
@@ -65,16 +65,22 @@ table {
end
-Show more
+Show more
{% endblock %}
diff --git a/qutebrowser/javascript/history.js b/qutebrowser/javascript/history.js
index b4e584bb0..3ff9f09db 100644
--- a/qutebrowser/javascript/history.js
+++ b/qutebrowser/javascript/history.js
@@ -1,138 +1,194 @@
/**
- * Container for global stuff
- */
-var global = {
- // The last history item that was seen.
- lastItem: null,
- // The next time to load
- nextTime: null,
- // The cutoff interval for session-separator (30 minutes)
- SESSION_CUTOFF: 30*60
-};
-
-/**
- * Finds or creates the session table>tbody to which item with given date
- * should be added.
+ * Copyright 2017 Imran Sobir
*
- * @param {Date} date - the date of the item being added.
+ * This file is part of qutebrowser.
+ *
+ * qutebrowser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * qutebrowser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with qutebrowser. If not, see .
*/
-var getSessionNode = function(date) {
- var histContainer = document.getElementById('hist-container');
- // Find/create table
- var tableId = "hist-" + date.getDate() + date.getMonth() + date.getYear();
- var table = document.getElementById(tableId);
- if (table === null) {
- table = document.createElement("table");
- table.id = tableId;
+"use strict";
- caption = document.createElement("caption");
- caption.className = "date";
- var options = {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'};
- caption.innerHTML = date.toLocaleDateString('en-US', options);
- table.appendChild(caption);
+window.loadHistory = (function() {
+ // The time of last history item.
+ var lastTime = null;
- // Add table to page
- histContainer.appendChild(table);
- }
+ // The time to load next.
+ var nextTime = null;
- // Find/create tbody
- var tbody = table.lastChild;
- if (tbody.tagName !== "TBODY") { // this is the caption
- tbody = document.createElement("tbody");
- table.appendChild(tbody);
- }
+ // The cutoff interval for session-separator (30 minutes)
+ var SESSION_CUTOFF = 30 * 60;
- // Create session-separator and new tbody if necessary
- if (tbody.lastChild !== null && global.lastItem !== null) {
- lastItemDate = new Date(parseInt(global.lastItem.time)*1000);
- var interval = (lastItemDate.getTime() - date.getTime())/1000.00;
- if (interval > global.SESSION_CUTOFF) {
- // Add session-separator
- var sessionSeparator = document.createElement('td');
- sessionSeparator.className = "session-separator";
- sessionSeparator.colSpan = 2;
- sessionSeparator.innerHTML = "§";
- table.appendChild(document.createElement('tr'));
- table.lastChild.appendChild(sessionSeparator);
+ // The URL to fetch data from.
+ var DATA_URL = "qute://history/data";
- // Create new tbody
+ // Various fixed elements
+ var EOF_MESSAGE = document.getElementById("eof");
+ var LOAD_LINK = document.getElementById("load");
+ var HIST_CONTAINER = document.getElementById("hist-container");
+
+ /**
+ * Finds or creates the session table>tbody to which item with given date
+ * should be added.
+ *
+ * @param {Date} date - the date of the item being added.
+ * @returns {Element} the element to which new rows should be added.
+ */
+ function getSessionNode(date) {
+ // Find/create table
+ var tableId = "hist-".concat(date.getDate(), date.getMonth(),
+ date.getYear());
+ var table = document.getElementById(tableId);
+ if (table === null) {
+ table = document.createElement("table");
+ table.id = tableId;
+
+ // Caption contains human-readable date
+ var caption = document.createElement("caption");
+ caption.className = "date";
+ var options = {
+ "weekday": "long",
+ "year": "numeric",
+ "month": "long",
+ "day": "numeric",
+ };
+ caption.innerHTML = date.toLocaleDateString("en-US", options);
+ table.appendChild(caption);
+
+ // Add table to page
+ HIST_CONTAINER.appendChild(table);
+ }
+
+ // Find/create tbody
+ var tbody = table.lastChild;
+ if (tbody.tagName !== "TBODY") {
tbody = document.createElement("tbody");
table.appendChild(tbody);
}
- }
- return tbody;
-}
+ // Create session-separator and new tbody if necessary
+ if (tbody.lastChild !== null && lastTime !== null) {
+ var lastItemDate = new Date(lastTime * 1000);
+ var interval = (lastItemDate.getTime() - date.getTime()) / 1000.00;
+ if (interval > SESSION_CUTOFF) {
+ // Add session-separator
+ var sessionSeparator = document.createElement("td");
+ sessionSeparator.className = "session-separator";
+ sessionSeparator.colSpan = 2;
+ sessionSeparator.innerHTML = "§";
+ table.appendChild(document.createElement("tr"));
+ table.lastChild.appendChild(sessionSeparator);
-/**
- * Given a history item, create and return for it.
- * param {string} itemUrl - The url for this item
- * param {string} itemTitle - The title for this item
- * param {string} itemTime - The formatted time for this item
- */
-var makeHistoryRow = function(itemUrl, itemTitle, itemTime) {
- var row = document.createElement('tr');
-
- var title = document.createElement('td');
- title.className = "title";
- var link = document.createElement('a');
- link.href = itemUrl;
- link.innerHTML = itemTitle;
- title.appendChild(link);
-
- var time = document.createElement('td');
- time.className = "time";
- time.innerHTML = itemTime;
-
- row.appendChild(title);
- row.appendChild(time);
-
- return row;
-}
-
-var getJSON = function(url, callback) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, true);
- xhr.responseType = 'json';
- xhr.onload = function() {
- var status = xhr.status;
- callback(status, xhr.response);
- };
- xhr.send();
-};
-
-/**
- * Load new history.
- */
-var loadHistory = function() {
- url = "qute://history/data";
- if (global.nextTime !== null) {
- startTime = global.nextTime;
- url = "qute://history/data?start_time=" + startTime.toString();
- }
-
- getJSON(url, function(status, history) {
- if (history !== undefined) {
- for (item of history) {
- if (item.next === -1) {
- // Reached end of history
- window.onscroll = null;
- document.getElementById('eof').style.display = "block";
- document.getElementById('load').style.display = "none";
- continue;
- } else if (item.next !== undefined) {
- global.nextTime = parseInt(item.next);
- continue;
- }
-
- atime = new Date(parseInt(item.time)*1000);
- var session = getSessionNode(atime);
- var row = makeHistoryRow(item.url, item.title, atime.toLocaleTimeString());
- session.appendChild(row);
- global.lastItem = item;
+ // Create new tbody
+ tbody = document.createElement("tbody");
+ table.appendChild(tbody);
}
}
- });
-}
+ return tbody;
+ }
+
+ /**
+ * Given a history item, create and return
for it.
+ *
+ * @param {string} itemUrl - The url for this item.
+ * @param {string} itemTitle - The title for this item.
+ * @param {string} itemTime - The formatted time for this item.
+ * @returns {Element} the completed tr.
+ */
+ function makeHistoryRow(itemUrl, itemTitle, itemTime) {
+ var row = document.createElement("tr");
+
+ var title = document.createElement("td");
+ title.className = "title";
+ var link = document.createElement("a");
+ link.href = itemUrl;
+ link.innerHTML = itemTitle;
+ title.appendChild(link);
+
+ var time = document.createElement("td");
+ time.className = "time";
+ time.innerHTML = itemTime;
+
+ row.appendChild(title);
+ row.appendChild(time);
+
+ return row;
+ }
+
+ /**
+ * Get JSON from given URL.
+ *
+ * @param {string} url - the url to fetch data from.
+ * @param {function} callback - the function to callback with data.
+ * @returns {void}
+ */
+ function getJSON(url, callback) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true);
+ xhr.responseType = "json";
+ xhr.onload = function() {
+ var status = xhr.status;
+ callback(status, xhr.response);
+ };
+ xhr.send();
+ }
+
+ /**
+ * Receive history data from qute://history/data.
+ *
+ * @param {Number} status - The status of the query.
+ * @param {Array} history - History data.
+ * @returns {void}
+ */
+ function receiveHistory(status, history) {
+ if (history === undefined) {
+ return;
+ }
+
+ for (var i = 0, len = history.length - 1; i < len; i++) {
+ var item = history[i];
+ var atime = new Date(item.time * 1000);
+ var session = getSessionNode(atime);
+ var row = makeHistoryRow(item.url, item.title,
+ atime.toLocaleTimeString());
+ session.appendChild(row);
+ lastTime = item.time;
+ }
+
+ var next = history[history.length - 1].next;
+ if (next === -1) {
+ // Reached end of history
+ window.onscroll = null;
+ EOF_MESSAGE.style.display = "block";
+ LOAD_LINK.style.display = "none";
+ } else {
+ nextTime = next;
+ }
+ }
+
+ /**
+ * Load new history.
+ * @return {void}
+ */
+ function loadHistory() {
+ if (nextTime === null) {
+ getJSON(DATA_URL, receiveHistory);
+ } else {
+ var url = DATA_URL.concat("?start_time=", nextTime.toString());
+ getJSON(url, receiveHistory);
+ }
+ }
+
+ return loadHistory;
+})();