Last active
April 26, 2024 10:18
-
-
Save saitamanodoruji/5690960 to your computer and use it in GitHub Desktop.
Tumblr Bookmarker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Tumblr Bookmarker | |
// @description Bookmark posts on your dash to return to later | |
// @namespace http://userscripts.org/users/113977 | |
// @include http://www.tumblr.com/blog/* | |
// @include http://www.tumblr.com/drafts* | |
// @include http://www.tumblr.com/queue* | |
// @include http://www.tumblr.com/likes* | |
// @include http://www.tumblr.com/messages* | |
// @include http://www.tumblr.com/dashboard* | |
// @include http://www.tumblr.com/tagged* | |
// @version 0.2.10.4 | |
// @date 2013-09-07 | |
// @creator Jeremy Cutler | |
// @contributer saitamanodoruji | |
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js | |
// ==/UserScript== | |
(function() { | |
var bmi = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAANCAYAAAB2HjRBAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAABASURBVDhPY2CgNvj///9mdEy0HaOaIYFH9wDLhIU8qTZnyho4gpwMNoAUzWCNQGwEM4BozTCNIA0wA4jWTKxCAEx4sLT85fObAAAAAElFTkSuQmCC'; | |
GM_addStyle('#right_column .dashboard_nav_item ul.dashboard_subpages li a .icon.dashboard_controls_bookmark { background-image:url("' + bmi + '") !important; }'); | |
jQuery.noConflict(); | |
var mimg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAAC0SURBVDhP7ZIxCsJAFETXPUWEVFZ7CyE30lIQ77EQfmy021oPYWPlCbzBdgtxZvkhKX5nmw8PhoGZ4jOb4f4cnXHvz9ey3Wt3Mn3HIovjRUaL/XU7WqxF87/WH82b+mdHBcMkdaCLogJNqrd4doEm1ZsGmRFOCvVUlBFOCvVUlBFOCnUtysPtISAoQg+hfDj3AoIi9BDK3dAICIrQcwhH0AKvUEeESQu8Qh0RJm3XN75CDe8HWZs6UiUIC2gAAAAASUVORK5CYII='; | |
function LS_getValue(key,defVal) { | |
var retval = window.localStorage.getItem(key); | |
if (retval == undefined || retval == null || retval == "") { | |
return defVal; | |
} | |
else | |
return retval; | |
} | |
function LS_setValue(key,val) { | |
window.localStorage.setItem(key,val); | |
} | |
function serializeMarks(a) { | |
var s = ""; | |
a.sort().reverse(); | |
for (i=0; i<a.length; i++) { | |
s = a[i][0] + ";" + a[i][1] + (a[i][2] ? ";" + a[i][2] : "") | |
+ (i>0 ? "," : "") + s; | |
} | |
return s; | |
} | |
function parseMarks(s) { | |
var arr = new Array(); | |
var ms = s.split(","); | |
for (i=0; i<ms.length; i++) { | |
var cm = ms[i].split(";"); | |
if (cm.length == 2) { | |
arr.push([cm[0],cm[1]]); | |
} else if (cm.length == 3) { | |
arr.push([cm[0],cm[1],cm[2]]); | |
} | |
} | |
arr.sort().reverse(); | |
return arr; | |
} | |
function markOver() { | |
var bp = jQuery(this).css("background-position"); | |
if (bp == "" || bp.charAt(0) == "0") | |
jQuery(this).css("background-position","-6px 0px"); | |
} | |
function markOut() { | |
var bp = jQuery(this).css("background-position"); | |
if (bp == "" || bp.charAt(1) == "6") | |
jQuery(this).css("background-position","0px 0px"); | |
} | |
function markClick(e) { | |
if (e.which == 1) { | |
if (jQuery(this).hasClass("s113977_ismarked")) { | |
removeMark(this.id.match(/[0-9]*$/)[0]); | |
} | |
else { | |
addMark(this.id.match(/[0-9]*$/)[0], this.getAttribute('data-dsbd-timestamp')); | |
} | |
return false; | |
} | |
} | |
function addMark(postID, dsbd_timestamp) { | |
var timestamp = new Date().toLocaleFormat('%Y-%m-%d %H:%M:%S'); | |
var marks = parseMarks(LS_getValue("tbr_Bookmarks","")); | |
marks.push([timestamp,postID,dsbd_timestamp]); | |
LS_setValue("tbr_Bookmarks",serializeMarks(marks)); | |
generateList(); | |
} | |
function removeMark(post) { | |
var marks = parseMarks(LS_getValue("tbr_Bookmarks","")); | |
for (i=0; i<marks.length; i++) { | |
if (marks[i][1] == post) { | |
break; | |
} | |
} | |
marks.splice(i,1); | |
LS_setValue("tbr_Bookmarks",serializeMarks(marks)); | |
generateList(); | |
} | |
function doMarks() { | |
var posts = jQuery('div[id^="post_"]:not(.bookmarkAdded):not(.post_tab_switching)'); | |
posts.addClass('bookmarkAdded'); | |
posts.each(function(i){ | |
var post_controls_inner = jQuery(this).find('div.post_controls_inner'); | |
var post_id = jQuery(this).attr('id').match(/[0-9]*$/)[0]; | |
var dsbd_date_str = jQuery(this).find('.post_permalink').attr('title').toString(); | |
var dsbd_unixtime = getUnixTimeFromDsbdDateString(dsbd_date_str, post_id); | |
var dsbd_timestamp = new Date(dsbd_unixtime).toLocaleFormat('%Y-%m-%d %H:%M:%S'); | |
var node = jQuery('<a class="s113977_mark" id="bookmark_' + post_id + '" title="Bookmark" href="#" style="border-width:0;height:14px;width:6px;vertical-align:16px;display:inline-block;background-image:url(' + mimg + ');background-repeat:no-repeat;background-attachment:scroll;background-position:0 0;margin:0 5px 0 16px" onclick="return false;" data-dsbd-timestamp="' + dsbd_timestamp + '"></a>'); | |
node.appendTo(post_controls_inner).click(markClick).mouseover(markOver).mouseout(markOut); | |
}); | |
} | |
function getMarkText(timestamp, post_id, dsbd_timestamp) { | |
var mark_text = [ | |
'<li id="mark_' + post_id + '">', | |
'<a href="/dashboard/2/' + (Number(post_id) + 1) + '" target="_blank">', | |
'<span class="icon dashboard_controls_bookmark"></span>', | |
'<span class="mark_date">' + timestamp + '</span>', | |
dsbd_timestamp ? '<br />' : '', | |
'<span class="mark_dsbd_date">' + (dsbd_timestamp ? ' └' + dsbd_timestamp : '') + '</span>', | |
'</a>', | |
'<a id="unmark_' + post_id + '" class="s113977_unmarker tracked_tag_control" onclick="return false;" href="#">x</a>', | |
'</li>' | |
].join(''); | |
return mark_text; | |
} | |
function marklistClick(e) { | |
if (/s113977_unmarker/.test(e.target.className) && e.which == 1) { | |
removeMark(e.target.id.match(/[0-9]*$/)[0]); | |
return false; | |
} | |
} | |
function generateList() { | |
var marks = parseMarks(LS_getValue("tbr_Bookmarks","")); | |
var marklist = jQuery('#s113977_marklist'); | |
if (marks.length == 0) { | |
jQuery('#posts a.s113977_ismarked').css("background-position","0px 0px").removeClass("s113977_ismarked"); | |
marklist.empty().parent().hide(); | |
return true; | |
} | |
marklist.parent().show(); | |
var markitems = marklist.find('li'); | |
if (markitems.length > 0) { | |
var idx = 0; | |
markitems.each(function(i) { | |
var cd = jQuery(this).find('span.mark_date').html(); | |
if (idx > marks.length-1 || | |
cd > marks[idx][0]) { | |
jQuery("#bookmark_" + this.id.match(/[0-9]*$/)[0]).css("background-position","0px 0px").removeClass("s113977_ismarked"); | |
jQuery(this).remove(); | |
} | |
else if (cd < marks[idx][0]) { | |
while (idx < marks.length && cd <= marks[idx][0]) { | |
jQuery("#bookmark_" + marks[idx][1]).css("background-position","-12px 0px").addClass("s113977_ismarked"); | |
if (cd != marks[idx][0]) { | |
jQuery(this).before(getMarkText(marks[idx][0],marks[idx][1],marks[idx][2] ? marks[idx][2] : undefined)); | |
} | |
idx++; | |
} | |
} | |
else { | |
jQuery("#bookmark_" + marks[idx][1]).css("background-position","-12px 0px").addClass("s113977_ismarked"); | |
idx++; | |
} | |
}); | |
for(; idx<marks.length; idx++) { | |
jQuery("#bookmark_" + marks[idx][1]).css("background-position","-12px 0px").addClass("s113977_ismarked"); | |
marklist.append(getMarkText(marks[idx][0],marks[idx][1],marks[idx][2] ? marks[idx][2] : undefined)); | |
} | |
} | |
else { | |
for (i=0; i<marks.length; i++) { | |
jQuery("#bookmark_" + marks[i][1]).css("background-position","-12px 0px").addClass("s113977_ismarked"); | |
marklist.append(getMarkText(marks[i][0],marks[i][1],marks[i][2] ? marks[i][2] : undefined)); | |
} | |
} | |
} | |
if (document.body.id != "tinymce" && | |
document.body.id != "dashboard_edit_post") { | |
if (/drafts$/.test(location) == false && | |
/queue$/.test(location) == false && | |
/messages$/.test(location) == false) | |
doMarks(); | |
var list = jQuery('<div class="dashboard_nav_item" style="padding-left:0;position:relative;"><div class="dashboard_nav_title">Bookmarks</div><ul id="s113977_marklist" class="dashboard_subpages"></ul></div>'); | |
var pos = jQuery("#dashboard_controls_radar_buttons"); | |
if (pos.length > 0) { | |
pos.parent().before(list); | |
} | |
else { | |
jQuery("#right_column").append(list); | |
} | |
list.click(marklistClick); | |
generateList(); | |
} | |
function refreshMarks() { | |
var marks = parseMarks(LS_getValue("tbr_Bookmarks","")); | |
jQuery("#posts a.s113977_ismarked").each(function(){ | |
var remove = true; | |
for (i=0; i<marks.length; i++) { | |
if (this.id == "bookmark_" + marks[i][1]) { | |
remove = false; | |
break; | |
} | |
} | |
if (remove) jQuery(this).css("background-position","0px 0px").removeClass("s113977_ismarked"); | |
}); | |
for (i=0; i<marks.length; i++) { | |
jQuery("#bookmark_" + marks[i][1]).css("background-position","-12px 0px").addClass("s113977_ismarked"); | |
} | |
generateList(); | |
} | |
function tbr_113977() { | |
if (/drafts$/.test(location) == false && | |
/queue$/.test(location) == false && | |
/messages$/.test(location) == false) | |
doMarks(); | |
refreshMarks(); | |
} | |
if (document.body.id != "tinymce" && | |
document.body.id != "dashboard_edit_post") { | |
tbr_113977(); | |
document.addEventListener('DOMNodeInserted', tbr_113977, false); | |
window.addEventListener('storage', tbr_113977, false); | |
} | |
// ======== Utilities for Date Correction ======== | |
// a.post_permalink の title に入っている日付文字列と Post ID を元に | |
// ポストが作られた Unix time を求める | |
function getUnixTimeFromDsbdDateString(dsbdDateStr, dsbdPostNo) { | |
var utime; | |
var dateArr = dsbdDateStr.replace(/(?:View post|投稿を確認する) - /, '').split(' '); | |
var type = dateArr.length; | |
var curDate = new Date(); | |
if (type == 1) { | |
// View post - 5:17am | |
var formattedTime = getFormattedTime(dsbdDateStr.replace('View post - ', '')); | |
var timestamp = curDate.toString().replace(/\d\d:\d\d:\d\d/, formattedTime); | |
utime = new Date(timestamp).getTime(); | |
} else if (type == 2) { | |
// View post - Thursday, 11:53pm | |
var diffInWeek; | |
var day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; | |
day.forEach(function(e, i) { | |
if( e == dateArr[0].replace(',', '') ) { | |
diffInWeek = curDate.getDay() - i > 0 ? | |
curDate.getDay() - i : | |
curDate.getDay() - i + 7; | |
} | |
}); | |
var formattedTime = getFormattedTime(dsbdDateStr.replace(/^[^,]+, /, '')); | |
var timestamp = curDate.toString().replace(/\d\d:\d\d:\d\d/, formattedTime); | |
utime = new Date(timestamp).getTime() - diffInWeek * 86400000; | |
} else if (type == 3) { | |
// View post - June 8th, 8:46pm | |
var formattedDateStr = [ | |
curDate.getFullYear(), | |
dateArr[0], | |
dateArr[1].replace(/(?:st|nd|rd|th)/, ''), | |
getFormattedTime(dateArr[2]) | |
].join(' '); | |
utime = new Date(formattedDateStr).getTime(); | |
} else if (type == 4) { | |
// View post - March 29th 2007, 8:38pm | |
var formattedDateStr = [ | |
dateArr[0], | |
dateArr[1].replace(/(?:st|nd|rd|th)/, ''), | |
dateArr[2], | |
getFormattedTime(dateArr[3]) | |
].join(' '); | |
utime = new Date(formattedDateStr).getTime(); | |
} | |
return correctDsbdUTime(utime, type, dsbdPostNo); | |
} | |
// いくつかの日付で日付文字列が間違っているので修正する | |
function correctDsbdUTime(utime, type, dsbdPostNo) { | |
var cUTime; //corrected Unix time | |
var timestamp = new Date(utime).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'); | |
if (1230649200000 <= utime && utime < 1230735600000 | |
&& dsbdPostNo < 31818629) { | |
// 2007-12-31 is displayed as 2008 by mistake | |
cUTime = new Date(timestamp.replace(/^2008/, '2007')).getTime(); | |
} else if (1262012400000 <= utime && utime < 1262271600000 | |
&& dsbdPostNo < 175958681) { | |
// 2008-12-29, 2008-12-30, 2008-12-31 are displayed as 2009 by mistake | |
cUTime = new Date(timestamp.replace(/^2009/, '2008')).getTime(); | |
} else if (1230735600000 <= utime && utime < 1230994800000 | |
&& dsbdPostNo > 175958681) { | |
// 2010-01-01, 2010-01-02, 2010-01-03 are displayed as 2009 by mistake | |
cUTime = new Date(timestamp.replace(/^2009/, '2010')).getTime(); | |
} else if (1262271600000 <= utime && utime < 1262444400000 | |
&& dsbdPostNo > 973060715) { | |
// 2011-01-01, 2011-01-02 are displayed as 2010 by mistake | |
cUTime = new Date(timestamp.replace(/^2010/, '2011')).getTime(); | |
} else if (1293807600000 <= utime && utime < 1293894000000 | |
&& dsbdPostNo > 5381076679) { | |
// 2012-01-01 is displayed as 2011 by mistake | |
cUTime = new Date(timestamp.replace(/^2011/, '2012')).getTime(); | |
} | |
// same day of previous years displayed as current year | |
if (type == 1) { | |
var currentYear = new Date().getFullYear(); | |
if (dsbdPostNo < 22717143) { | |
// to 2007 | |
cUTime = rewindYear(utime, currentYear - 2007); | |
} else if (dsbdPostNo < 67667869) { | |
// to 2008 | |
cUTime = rewindYear(utime, currentYear - 2008); | |
} else if (dsbdPostNo < 309781747) { | |
// to 2009 | |
cUTime = rewindYear(utime, currentYear - 2009); | |
} else if (dsbdPostNo < 2542286951) { | |
// to 2010 | |
cUTime = rewindYear(utime, currentYear - 2010); | |
} else if (dsbdPostNo < 15082228675) { | |
// to 2011 | |
cUTime = rewindYear(utime, currentYear - 2011); | |
} else if (dsbdPostNo < 39306789337) { | |
// to 2012 | |
cUTime = rewindYear(utime, currentYear - 2012); | |
} | |
} | |
// for 2012-12-31 | |
if (type == 2 && 39217020996 < dsbdPostNo && dsbdPostNo < 39306789337) { | |
cUTime = new Date(timestamp.replace(/\d{4}-\d{2}-\d{2}/, '2012-12-31')).getTime(); | |
} | |
return cUTime || utime; | |
} | |
// n 年前の同日の Unix time を求める | |
function rewindYear(utime, n) { | |
var utimeDateStr = new Date(utime).toISOString(); | |
var utimeYear = Number(utimeDateStr.match(/^\d{4}/)[0]); | |
var rewindedYear = utimeYear - n; | |
var rewindedDateStr = utimeDateStr.replace(/^\d{4}/, rewindedYear); | |
var rewindedUTime = new Date(rewindedDateStr).getTime(); | |
return rewindedUTime; | |
} | |
// 時刻文字列を 24 h 形式にする | |
// ex. 1) '9:17am' -> '09:17' | |
// ex. 2) '5:36pm' -> '17:36' | |
function getFormattedTime(timeStr) { | |
var timeArr = timeStr.split(':'); | |
timeArr[0] = Number(timeArr[0]); | |
if (/pm/.test(timeArr[1])) { | |
timeArr[0] = (timeArr[0] + 12).toString(); | |
} else if (timeArr[0].toString().length == 1) { | |
timeArr[0] = '0' + timeArr[0]; | |
} else { | |
timeArr[0] = timeArr[0].toString().replace('12', '00'); | |
} | |
timeArr[1] = timeArr[1].replace(/(?:am|pm)/, ''); | |
return timeArr.join(':'); | |
} | |
function update(t, s){ | |
for(var p in s) | |
t[p] = s[p] | |
return t | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment