dejalicious ++
By LucasR
—
Last update May 23, 2007
—
Installed
519 times.
// ==UserScript==
// @name dejalicious ++
// @namespace http://web.aanet.com.au/richters
// @description Dejalicious with a little bit of GUI stuff. Bottom corner shows whether or not you've got the current page bookmarked, and lets you mark it if you haven't.
// @includes *
// @excludes http://del.icio.us/*
// @excludes *.txt
// @excludes *.js
// ==/UserScript==
/*
Author: Lucas Richter
License: Creative Commons Attribution-ShareAlike 2.5 (http://creativecommons.org/licenses/by-sa/2.5/)
*/
var debug = true;
const MINUTES_BETWEEN_GET_ALL = 60;
const USER_AGENT = '/dejalicious_plus_plus.user.js';
function GML(s) {
if (debug) {
GM_log(s);
}
}
GML('dejalicious: ' + window.location.href);
var nothing;
var now = (new Date() + 0);
// Ensure consistent use of names with setValue/getValue and element IDs
var kUser = 'username';
var kPass = 'password';
var kFamiliar = 'familiar';
var kStrange = 'strange';
var kCache = 'cache';
var kHit = 'hittime';
var kUpdated = 'DeliciousLastUpdated';
var idConfig = 'dejalicious_config';
var kPoll = 'poll';
var urlPrefix = 'https://api.del.icio.us/v1/';
var urlLastUpdate = urlPrefix + 'posts/update';
var urlFetchAll = urlPrefix + 'posts/all?';
var urlCurrent = window.location.href;
var user = GM_getValue(kUser, nothing);
var pass = GM_getValue(kPass, nothing);
var familiar = GM_getValue(kFamiliar, "Tagged");
var strange = GM_getValue(kStrange, "Tag...");
var timeLastHit = GM_getValue(kHit, 0);
var LastUpdated = GM_getValue(kUpdated, nothing);
var timeLastPolled= GM_getValue(kPoll, nothing);
var idUser = 'dejalicious_username';
var idPass = 'dejalicious_password';
var idStrange = 'dejalicious_strange';
var idFamiliar = 'dejalicious_familiar';
if (! GM_xmlhttpRequest) {
alert('dejalicious++ greasemonkey script cannot function without a modern release of Firefox. (No xmlhttprequest.)');
return;
}
function SaveConfig() {
var usr = document.getElementById(idUser).value;
var pwd = document.getElementById(idPass).value;
var familiar= document.getElementById(idFamiliar).value;
var strange = document.getElementById(idStrange).value;
GM_setValue(kUser, usr);
GM_setValue(kPass, pwd);
GM_setValue(kFamiliar, familiar);
GM_setValue(kStrange, strange);
GM_setValue(kHit, 0); // force a refresh after saving preferences
var win = document.getElementById(idConfig);
win.style.display = 'none';
}
function ShowConfig() {
var tUser = user;
var tPass = pass;
var tFamiliar = familiar;
var tStrange = strange;
if (!tUser) tUser = '';
if (!tPass) tPass = '';
if (!tFamiliar) tFamiliar = '';
if (!tStrange) tStrange = '';
var c = document.createElement("div");
c.setAttribute("style", "margin: 3em 15%; width: 20em; position: fixed; top: 0; left: 0; border: thin solid black; color: black; background: #ACF; opacity: 0.9; " +
"font-size: 12pt; " +
"z-index: 99999; padding: 6px; display: none; " +
"font-family: Arial, sans-serif;");
c.setAttribute("id", idConfig);
// Start with a top-level form and table.
var form = document.createElement("form");
form.setAttribute("method", "get");
form.setAttribute("action", "");
form.setAttribute("id", idConfig + 'Form');
form.setAttribute("style", "padding: 0; margin: 0;");
var table = document.createElement("table");
table.setAttribute("style",
"width: 100%; margin: 5px; padding: 5px; " +
"border-spacing: 0;");
table.setAttribute("id", "ft_config_table");
form.appendChild(table);
var caption = document.createElement("caption");
caption.setAttribute("style", "width: 100%; text-align: left");
strong = document.createElement("strong");
strong.appendChild(document.createTextNode("Dejalicious Configuration:"));
caption.appendChild(strong);
table.appendChild(caption);
table.appendChild(make_config_row("username", "ID:", tUser, "Your del.icio.us user-ID"));
table.appendChild(make_config_row("password", "Password:", tPass, "Your del.icio.us password" ));
table.appendChild(make_config_row("familiar", "Bookmarked Suffix:", tFamiliar, "Add this after the title of saved pages" ));
table.appendChild(make_config_row("strange", "Unbookmarked Suffix:", tStrange, "Add this after the title of UN-saved pages" ));
CreateButton(form, 'Save', SaveConfig);
c.appendChild(form);
var b = document.getElementsByTagName("body");
b[0].appendChild(c);
c.style.display = 'block';
}
function CreateButton(aParent, aCaption, aFunction) {
var b = document.createElement("BUTTON");
var btext = document.createTextNode(aCaption);
b.appendChild(btext);
b.addEventListener('click', aFunction, true);
aParent.appendChild(b);
}
function make_config_row(name, label, value, help) {
var row = document.createElement("tr");
var cell = document.createElement("td");
cell.setAttribute("style",
"width: 50%; text-align: right; padding-right: 3px");
cell.appendChild(document.createTextNode(label));
row.appendChild(cell);
cell = document.createElement("td");
cell.setAttribute("style", "width: 50%; text-align: left; padding-left: 3px");
var ctl;
ctl = document.createElement("input");
ctl.setAttribute("id", "dejalicious_" + name);
ctl.setAttribute("type", "text");
ctl.setAttribute("size", 30);
ctl.setAttribute("title", help);
ctl.setAttribute("name", name);
ctl.setAttribute("value", value);
cell.appendChild(ctl);
row.appendChild(cell);
return row;
}
function minutesSincePoll() {
var age = (new Date(now) - new Date(timeLastHit)) / 1000; // timestamps are milliseconds since the epoch
age = age / 60; // convert seconds to minutes
return age;
}
function hitAgeInSeconds() {
var age = (new Date(now) - new Date(timeLastHit)) / 1000; // timestamps are milliseconds since the epoch
return age;
}
// It is time to refresh the cache when ALL of the following are true:
// * Cache is more than an hour old
// * Last AJAX hit is at least a minute old (prevents multi-fetching on pages with included content)
function timeToRefreshCache() {
if (minutesSincePoll() < MINUTES_BETWEEN_GET_ALL) {
GML('no refresh because cache is from current hour');
return false;
}
if (hitAgeInSeconds() < 60) {
GML('no refresh because double-fetch');
return false;
}
return true;
}
function canonicalUrl(url) {
url = url + ""; // make sure it is a string
url = url.toLowerCase();
// Delete protocol from the URL
url = url.replace(/^http:\/\//, '');
url = url.replace(/^https:\/\//, '');
// Delete leading "www."
url = url.replace(/^www\./, '');
// Delete trailing slash
url = url.replace(/\/$/, '');
return url;
}
function urlInCache(aUrl) {
aUrl = " " + canonicalUrl(aUrl) + " ";
var cache = GM_getValue(kCache, " ");
if (cache.indexOf(aUrl) < 0) {
return false;
}
return true;
}
function showIndicator(url) {
if (urlInCache(url)) {
showTaste(url, true);
} else {
showTaste(url, false);
}
}
function receiveFetchAll(response, pageUrl) {
GML('received response to GET ALL, from url:' + pageUrl);
var r = response.replace(/<[^>]*>/,''); // remove the initial <?xml .... ?> tag
var xmlDoc = new XML(r); // this XML object was added in Firefox 1.5.0.
var temp = " ";
// I have no idea how the following for loop works. I lifted it from
// http://weblog.infoworld.com/udell/2004/09/29.html#a1085
for each (p in xmlDoc..post.@href) {
temp += canonicalUrl(p) + " ";
}
temp += " ";
GM_setValue(kCache, temp);
showIndicator(pageUrl);
}
function saveTimeHit() {
GM_setValue(kHit, (new Date() + 0));
}
function receiveLastUpdate(response, urlCurrent) {
var start;
var tmp;
GML('received response to GET-LAST-UPDATED');
timeLastPolled = new Date() + 0;
GM_setValue(kPoll, timeLastPolled);
start = response.indexOf('time=');
if (start < 0) {
return;
}
tmp = response.substr(start + 6); // Skip 'time="'
timestamp = tmp.substr(0, 20);
if (timestamp == LastUpdated) {
// use the cache, since it is up to date
GML("using cache because no newer data at delicious; urlCurrent is " + urlCurrent);
showIndicator(urlCurrent);
return;
}
LastUpdated = timestamp;
GM_setValue(kUpdated, LastUpdated);
// Cache is out of date -- refresh it.
GML('Newer data at delicious -- calling xmlhttprequest with:' + urlFetchAll);
saveTimeHit();
GM_xmlhttpRequest({
method: "GET",
url: urlFetchAll,
headers: {
'User-agent':
'Mozilla/4.0 (compatible) Greasemonkey' + USER_AGENT,
'Accept': 'text/xml,application/xml',
'Authorization':
'Basic ' + btoa(user + ":" + pass),
},
onload: function(response) {
receiveFetchAll(response.responseText, urlCurrent);
}
});
}
function refreshCache(currentUrl) {
var d = new Date();
var atime = d.getHours() * 3600 + d.getMinutes() * 60;
GML('calling xmlhttprequest with:' + urlLastUpdate);
saveTimeHit();
GM_xmlhttpRequest({
method: "GET",
url: urlLastUpdate,
headers: {
'User-agent':
'Mozilla/4.0 (compatible) Greasemonkey' +
'/abc123good_taste.user.js',
'Accept': 'text/xml,application/xml',
'Authorization':
'Basic ' + btoa(user + ":" + pass),
},
onload: function(response) {
receiveLastUpdate(response.responseText, currentUrl);
}
});
}
function showTaste(aUrl, found) {
var tagUrl = "javascript:location.href='http://del.icio.us/post?v=4;url='+encodeURIComponent(location.href)+';title='+encodeURIComponent(document.title)";
GM_addStyle('#taste {background: url(http://images.del.icio.us/static/img/delicious.gif) no-repeat top left transparent; position: fixed; z-index: 32766; bottom: 2px; right: 0; padding: 0 0 0 20px; height: 16px; font-family: Arial, Verdana, sans; font-size: 14px; padding-right: 2px; padding-top: 2px;}');
GM_addStyle('#taste a {color: #00f; text-decoration: underline; font: Arial,Verdana,sans 16pt; font-weight: normal; font-style: normal;}');
GM_addStyle('#taste a:hover {text-decoration: none;}');
var myDiv = document.createElement('div');
myDiv.setAttribute('id', 'taste');
document.body.appendChild(myDiv);
var t = document.getElementById('taste');
if (found) {
t.innerHTML = familiar;
} else {
t.innerHTML = '<a href="' + tagUrl + '">' + strange + '</a>';
}
}
function main() {
GM_registerMenuCommand('Dejalicious setup', ShowConfig);
if (!user || !pass) {
ShowConfig();
return;
}
if (timeToRefreshCache()) {
refreshCache(urlCurrent);
return;
}
showIndicator(urlCurrent);
}
// Don't process child frames -- just the root window, because that is all
// the user can bookmark.
if (top == self) {
main();
} else {
}