Commit c98d59db authored by Histre Team's avatar Histre Team
Browse files

v2.11.3

parent 4dc06ee4
......@@ -9,6 +9,7 @@ if (ENV === 'local') {
} else if (ENV === 'stg') {
host = 'https://histre-dev01.appspot.com';
}
let histre_origins = [host+'/'];
const apiBase = `${host}/api/v1`;
......@@ -62,7 +63,6 @@ function doRequest(method, url, data, callback) {
});
}
function doGet(url, data, callback) {
return doRequest('GET', url, data, callback);
}
......@@ -96,19 +96,23 @@ function enableOrDisableHistory() {
}
}
function cleanFavicon(favicon) {
if (favicon && (favicon.indexOf('http') !== 0 || favicon.length > 255)) {
return null;
}
return favicon;
}
// ---- Handlers ----
function onInstalledHandler(object) {
setClientCookies();
addHistreContextMenu();
}
function onStartupHandler(object) {
setClientCookies();
addHistreContextMenu();
}
function histreContextMenuOnClickHandler(info, tab) {
chrome.tabs.executeScript(tab.id, {
file: "range.js"
......@@ -128,7 +132,6 @@ function histreContextMenuOnClickHandler(info, tab) {
});
}
function addHistreContextMenu() {
chrome.contextMenus.create({
"title": "Save highlight to histre",
......@@ -137,13 +140,16 @@ function addHistreContextMenu() {
});
}
function tabUpdatedHandler(tabId, changes, tab) {
// if hn page is reloaded
if (tab.url.indexOf('news.ycombinator.com') != -1) {
addHNContentScript(tab);
}
if (tab.url.indexOf('histre') != -1 && tab.url.indexOf('notebooks/') != -1) {
addTabsContentScript(tab);
}
if (changes.url) { //url of the tab changing for some reason
if (tab.active) { //start new click if its active tab and we are not already tracking it
if (clock.length > 0) {
......@@ -162,7 +168,7 @@ function tabUpdatedHandler(tabId, changes, tab) {
for (var l = clock.length - 1; l >= 0; l--) {
if (clock[l].tabId == tab.id) {
if (tab.favIconUrl) {
clock[l].favicon = tab.favIconUrl;
clock[l].favicon = cleanFavicon(tab.favIconUrl);
}
if (tab.title) {
clock[l].title = tab.title;
......@@ -189,7 +195,6 @@ function tabCreatedHandler(tab) { //left click that opens new tab, Ctrl/CMD-T
}
}
function focusChangedHandler(window) {
if (window == chrome.windows.WINDOW_ID_NONE) {
helper.llog('lost focus');
......@@ -201,7 +206,6 @@ function focusChangedHandler(window) {
}
}
function onCommittedHandler(e)
{ //checking if navigation happened in addressbar
for (var i = 0; i < e.transitionQualifiers.length; i++) {
......@@ -217,7 +221,6 @@ function onCommittedHandler(e)
}
}
function onBeforeNavigateHandler(e)
{ //new url, trying to get url of last open tab - it's current tab or tab that launched navigation in new tab
if (e.frameId != 0 || lastTabId == -1)
......@@ -229,6 +232,22 @@ function onBeforeNavigateHandler(e)
});
}
function addTabsContentScript(tab) {
chrome.permissions.contains({
origins: histre_origins
}, function(result) {
if (result) {
chrome.tabs.executeScript({
file: 'histre_tabs.js'
});
} else {
// we don't have the permission to do that
}
});
}
function addHNContentScript(tab) {
chrome.permissions.contains({
origins: ['https://news.ycombinator.com/']
......@@ -279,20 +298,18 @@ function startClock() {
end: null,
title: tab.title,
navfrom: navfrom[tab.id],
favicon: tab.favIconUrl,
favicon: cleanFavicon(tab.favIconUrl),
});
helper.llog(`startclock : ${tab.url}`);
});
}
function onActivatedHandler(activeInfo) {
lastTabId = activeInfo.tabId;
helper.llog("tab activated");
startClock();
}
function stopClock() {
if (clock.length > 0 && clock[clock.length - 1].end == null) {
clock[clock.length - 1].end = Date.now();
......@@ -339,7 +356,6 @@ function persist() {
});
}
function postHistory() {
chrome.history.search({ text: "" }, function callback(history) {
......@@ -372,7 +388,6 @@ function postHistory() {
});
}
function postBookmarks() {
chrome.bookmarks.getTree(
function (bookmarkTreeNodes) {
......@@ -406,7 +421,6 @@ function postBookmarks() {
});
}
function bookmarksOnCreatedHandler(id, bookmark) {
const data = {
url: bookmark.url,
......@@ -418,7 +432,6 @@ function bookmarksOnCreatedHandler(id, bookmark) {
doPost(bookmarksUrl, payload, function (result) { helper.llog("bookmarks create sent" + result); });
}
function bookmarksOnDeletedHandler(id, removeInfo) {
const payload = {
url: removeInfo.node.url,
......@@ -427,7 +440,6 @@ function bookmarksOnDeletedHandler(id, removeInfo) {
doDelete(bookmarksUrl, payload, function (result) { helper.llog("bookmarks del sent" + result); });
}
function enableHistory() {
helper.llog('enableHistory');
chrome.tabs.onUpdated.addListener(tabUpdatedHandler);
......@@ -455,20 +467,19 @@ function disableHistory() {
chrome.runtime.onInstalled.addListener(onInstalledHandler);
chrome.runtime.onStartup.addListener(onStartupHandler);
chrome.runtime.onMessage.addListener(onMessageHandler);
function setClientCookies() {
helper.setCookie(host, 'extn_browser', (isFirefox) ? 'firefox' : 'chrome');
helper.setCookie(host, 'extn_version', version);
const name = 'extn_uuid';
helper.getCookie(host, name, (v) => {
clientuuid = v;
if (!clientuuid) {
helper.setCookie(host, name, helper.uuid4(), (v) => {
clientuuid = v;
function onMessageHandler(request, sender, sendResponse) {
try{
if (sender.tab && request.type == 'open_tabs') {
chrome.windows.create({'url': request.urls}, (w) => {
helper.llog(w);
});
}
});
}
} catch(e) {
helper.llog(e);
}
};
// listen to changes from popup
chrome.storage.onChanged.addListener(() => {
......
......@@ -12,29 +12,6 @@ const helper = {
}
},
getCookie: (domain, name, callback) => {
chrome.cookies.get({"url": domain, "name": name}, function(cookie) {
if(callback) {
callback(cookie && cookie.value);
}
});
},
setCookie: (domain, name, value, callback, expiry) => {
expiry = expiry || 4733510400; // Jan 1 2120
chrome.cookies.set({
"url": domain,
"name": name,
"value": value,
"expirationDate": expiry
}, function(cookie) {
if(callback && typeof callback === "function") {
callback(cookie.value);
}
});
},
uuid4: () => {
// https://stackoverflow.com/a/2117523
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
......@@ -51,4 +28,71 @@ const helper = {
chrome.browserAction.setBadgeText({text:""});
},
// https://github.com/thdoan/strftime/blob/master/strftime.js
strftime: function strftime(sFormat, date) {
if (!(date instanceof Date)) date = new Date();
var nDay = date.getDay(),
nDate = date.getDate(),
nMonth = date.getMonth(),
nYear = date.getFullYear(),
nHour = date.getHours(),
aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
isLeapYear = function() {
return (nYear%4===0 && nYear%100!==0) || nYear%400===0;
},
getThursday = function() {
var target = new Date(date);
target.setDate(nDate - ((nDay+6)%7) + 3);
return target;
},
zeroPad = function(nNum, nPad) {
return ((Math.pow(10, nPad) + nNum) + '').slice(1);
};
return sFormat.replace(/%[a-z]/gi, function(sMatch) {
return (({
'%a': aDays[nDay].slice(0,3),
'%A': aDays[nDay],
'%b': aMonths[nMonth].slice(0,3),
'%B': aMonths[nMonth],
'%c': date.toUTCString(),
'%C': Math.floor(nYear/100),
'%d': zeroPad(nDate, 2),
'%e': nDate,
'%F': date.toISOString().slice(0,10),
'%G': getThursday().getFullYear(),
'%g': (getThursday().getFullYear() + '').slice(2),
'%H': zeroPad(nHour, 2),
'%I': zeroPad((nHour+11)%12 + 1, 2),
'%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth>1 && isLeapYear()) ? 1 : 0), 3),
'%k': nHour,
'%l': zeroPad((nHour+11)%12 + 1, 2), /* Modified */
'%m': zeroPad(nMonth + 1, 2),
'%n': nMonth + 1,
'%M': zeroPad(date.getMinutes(), 2),
'%p': (nHour<12) ? 'AM' : 'PM',
'%P': (nHour<12) ? 'am' : 'pm',
'%s': Math.round(date.getTime()/1000),
'%S': zeroPad(date.getSeconds(), 2),
'%u': nDay || 7,
'%V': (function() {
var target = getThursday(),
n1stThu = target.valueOf();
target.setMonth(0, 1);
var nJan1 = target.getDay();
if (nJan1!==4) target.setMonth(0, 1 + ((4-nJan1)+7)%7);
return zeroPad(1 + Math.ceil((n1stThu-target)/604800000), 2);
})(),
'%w': nDay,
'%x': date.toLocaleDateString(),
'%X': date.toLocaleTimeString(),
'%y': (nYear + '').slice(2),
'%Y': nYear,
'%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
'%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
}[sMatch] || '') + '') || sMatch;
});
}
};
// do not use console.log or helper.llog here
function initialize() {
if (!window.histre_tabs) {
var tabOpenerElement = document.getElementById('tab-opener');
if (!tabOpenerElement) { return; }
window.histre_tabs = true;
tabOpenerElement.classList.remove('hide');
tabOpenerElement.onclick = function() {
items = document.querySelectorAll(".book-notes .note-title");
urls = [];
var arrayLength = items.length;
for (var i = 0; i < arrayLength; i++) {
urls.push(items[i].href);
}
if (chrome.runtime) {
try {
chrome.runtime.sendMessage({type: "open_tabs", urls: urls});
} catch(e) {
/* TODO notify user */
}
}
};
}
}
initialize();
// do not use console.log or helper.llog here
function insertAfter(el, referenceNode) {
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}
......
......@@ -2,7 +2,7 @@
"name": "Histre",
"short_name": "Histre",
"description": "Effortless Knowledge Base",
"version": "2.10.0",
"version": "2.11.3",
"icons": {
"128": "assets/icon-128.png",
"48": "assets/icon-48.png",
......@@ -14,8 +14,8 @@
"webNavigation",
"tabs",
"storage",
"http://local.histre.com:8080/*",
"https://histre.com/*",
"http://local.histre.com:8080/",
"https://histre.com/",
"cookies"
],
"optional_permissions": [
......@@ -23,7 +23,7 @@
"bookmarks",
"history"
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"content_security_policy": "script-src 'self'; object-src 'self'",
"chrome_url_overrides": {
},
"browser_action": {
......
const settingsUrl = `${apiBase}/settings.json`;
let vueobj;
const settingsState = {};
function settingsVue () {
vueobj = new Vue({
el: '#settings',
data () {
return {
log_account: null,
log_browser: null,
loading: true,
errored: false,
enable_permissions: false,
};
},
mounted () {
axios
.get(settingsUrl)
.then(response => {
this.log_account = response.data.settings.history;
local_save_log_account(this.log_account);
this.errored = false;
})
.catch(error => {
this.errored = true;
})
.finally(() => this.loading = false);
const loadSettings = () => {
chrome.permissions.contains({
origins: ["<all_urls>"],
}, (enabled) => {
settingsState.enable_permissions = !!enabled;
$('#checkbox-enhance').prop('checked', settingsState.enable_permissions);
chrome.storage.local.get(['log_account', 'log_browser'], (result) => {
let log_account = result.log_account;
let log_browser = result.log_browser;
if (typeof log_account === "undefined") {log_account = true;}
if (typeof log_browser === "undefined") {log_browser = true;}
settingsState.log_account = !!log_account;
settingsState.log_browser = !!log_browser;
rerenderSettings();
});
});
};
const rerenderSettings = () => {
$('#checkbox-enhance').prop('checked', settingsState.enable_permissions);
$('#checkbox-all-browsers').prop('checked', settingsState.log_account);
$('#checkbox-this-browser').prop('checked', settingsState.log_browser && settingsState.log_account);
loggingmsg();
};
const updateStorage = (key, val, cb) => {
if (!cb) {
cb = loadSettings;
}
const kv = {};
kv[key] = val;
chrome.storage.local.set(kv, cb);
};
const loggingmsg = () => {
let msg = "";
if (!settingsState.log_account) {
msg = "disabled on all browsers";
} else if (settingsState.log_account && !settingsState.log_browser) {
msg = "disabled on this browser";
} else {
msg = "enabled";
}
$('#logging-status').html(`Status: Logging ${msg}`);
};
chrome.storage.local.get(['log_browser'], (result) => {
let log_browser = result.log_browser;
if (typeof log_browser === "undefined") {log_browser = true;}
this.log_browser = log_browser;
});
const enhanceWebsites = () => {
chrome.permissions.request({
origins: ["<all_urls>"],
permissions: ["bookmarks", "history"],
}, function(granted) {
updateStorage('enable_permissions', !!granted);
});
};
chrome.storage.local.get(['enable_permissions'], (result) => {
let enable_permissions = result.enable_permissions;
if (typeof enable_permissions === "undefined") {enable_permissions = false;}
this.enable_permissions = enable_permissions;
});
const setSettingsMsg = (msg) => {
if (msg === 'loading') {
$("#account-switch-loading").show();
$("#account-switch-errored").hide();
}
if (msg === 'error') {
$("#account-switch-loading").hide();
$("#account-switch-errored").show();
}
if (msg === 'success') {
$("#account-switch-errored").hide();
$("#account-switch-loading").hide();
}
};
},
computed: {
loggingmsg: function () {
let msg = "";
if (!this.log_account) {
msg = "disabled on all browsers";
} else if (this.log_account && !this.log_browser) {
msg = "disabled on this browser";
} else {
msg = "enabled";
}
return `Status: Logging ${msg}`;
},
},
methods: {
save_log_account: function (event) {
this.loading = true;
let log_account = this.log_account;
axios
.post(settingsUrl, {'history':log_account})
.then(response => {
this.log_account = response.data.settings.history;
local_save_log_account(this.log_account);
this.errored = false;
})
.catch(error => {
this.errored = true;
})
.finally(() => this.loading = false);
},
save_log_browser: function (event) {
this.loading = true;
let log_browser = this.log_browser;
chrome.storage.local.set({'log_browser':log_browser}, () => {
this.loading = false;
});
},
save_enable_permissions: function (event) {
let self = this;
if (self.enable_permissions) {
chrome.permissions.request({
origins: ["<all_urls>"],
permissions: ["bookmarks", "history"],
}, function(response) {
if (response) {
// handle yes
} else {
self.enable_permissions = false;
}
chrome.storage.local.set({'enable_permissions':self.enable_permissions}, () => {
});
});
}
},
const updateHistreSettings = (enable) => {
setSettingsMsg('loading');
axios
.post(settingsUrl, {'history':enable})
.then(response => {
setSettingsMsg('success');
updateStorage('log_account', response.data.settings.history);
if (response.data.settings.history) {
updateStorage('log_browser', true);
}
})
.catch(error => {
setSettingsMsg('error');
});
};
const handleSettingsClicks = () => {
$('#checkbox-enhance').on('click', function() {
if ($(this).is(':checked')) {
enhanceWebsites();
}
});
$('#checkbox-all-browsers').on('click', function() {
const checked = $(this).is(':checked');
updateHistreSettings(checked);
});
$('#checkbox-this-browser').on('click', function() {
const checked = $(this).is(':checked');
updateStorage('log_browser', checked);
});
};
settingsVue();
$(document).ready(() => {
loadSettings();
handleSettingsClicks();
});
html {
height: auto !important;
}
body {
overflow-x: hidden;
overflow-y: auto;
......@@ -8,8 +12,8 @@ body {
}
#popup-wrap {
width:400px;
padding:8px;
width:480px;
padding:16px;
}
.navbtn {
......@@ -19,11 +23,8 @@ body {
margin-right:16px;
}
a {color:#2c7be5; text-decoration: none;}
a:visited {color:#2c7be5; text-decoration: none;}
.topbar {