-
-
Save ljwrites/45216a154b6c6f245de16f8bc7414855 to your computer and use it in GitHub Desktop.
Dreamwidth signal boost bookmarklet that works on most pages, with username processing for additional sites
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
var postURL = "https://www.dreamwidth.org/update.bml?event="; | |
var curURL = window.location.href; | |
// get the currently selected text (no longer used in boost) | |
function getSelectionText() { | |
var text = ""; | |
if (window.getSelection) { | |
text = window.getSelection().toString(); | |
} else if (document.selection && document.selection.type != "Control") { | |
text = document.selection.createRange().text; | |
} | |
return text; | |
} | |
// updated, get currently selected html | |
function getSelectionHtml() { | |
var html = ""; | |
if (typeof window.getSelection != "undefined") { | |
var sel = window.getSelection(); | |
if (sel.rangeCount) { | |
var container = document.createElement("div"); | |
for (var i = 0, len = sel.rangeCount; i < len; ++i) { | |
container.appendChild(sel.getRangeAt(i).cloneContents()); | |
} | |
html = container.innerHTML; | |
} | |
} else if (typeof document.selection != "undefined") { | |
if (document.selection.type == "Text") { | |
html = document.selection.createRange().htmlText; | |
} | |
} | |
return html; | |
} | |
// check if it's locked. this checks for a different element now because the previous one inexplicably failed weirdly for a few people. ¯\_(ツ)_/¯ | |
function isLocked() { | |
return document.getElementsByClassName("security-protected").length > 0; | |
} | |
function confirmBoost() { | |
var doPost = !isLocked(); | |
if (!doPost) { | |
doPost = confirm("Post is access-locked. Continue?"); | |
} | |
return doPost; | |
} | |
function userLink(tag,attr,attrV,match,usrS) { | |
if(match=='exact'){var y='=';} | |
else if(match=='start'){var y='^=';} | |
else{var y='^=';} | |
try { | |
var a=document.querySelector(tag+'['+attr+y+'"'+attrV+'"]').getAttribute('href'); | |
} catch(err) {return [];} //try returning blank array instead? | |
if(!Boolean(usrS)){usrS=0;} | |
return a.substr(usrS).split('/'); | |
} | |
function cleanUp(s,c,p){ //until() function incorporated | |
if(Boolean(c) && s.includes(c)) { | |
if(p=='until') {return s.substr(0,s.indexOf(c));} | |
else{return s.substr(c.length);} | |
} | |
else { | |
return s; | |
} | |
} | |
function getUserName(sD,sN,fU,sFU,sSFU) { | |
//text by page type | |
var accT="'s account"; | |
var arcT="'s archive"; | |
var bloT="'s blog"; | |
var commT="'s recent comments"; | |
var evnT="'s events"; | |
var favT="'s favorites"; | |
var folgT="'s following page"; | |
var folrT="'s followers page"; | |
var frndT="'s friends page"; | |
var galT="'s gallery"; | |
var jourT="'s journal"; | |
var libT="'s library"; | |
var lovT="'s loved tracks"; | |
var memT="'s memories"; | |
var neiT="'s neighbors"; | |
var neT="'s network"; | |
var posT=" posted"; // or this could be just the default | |
var prnT="'s prints"; | |
var proT="'s profile"; | |
var rdT="'s reading page"; | |
var rprT="'s report"; | |
var shT="'s shouts"; | |
var tagT="'s tags"; | |
// sites known to DW for the user tag | |
var ao3={sn:'archiveofourown.com',usrF:['users'],posF:['works'],usr:sFU,usrS:1,usrL:1,tag:'a',attr:'rel',match:'exact',attrV:'author'}; | |
var blo={sn:'blogspot.com',usrF:'.',usr:sD}; | |
var dj={sn:'deadjournal.com',usrF:'.',usr:sD}; | |
var dw={sn:'dreamwidth.org',usrF:'.',usr:sD,ty:[['profile',proT],['read',rdT],['comments',commT],['archive',arcT],['network',neT],['tag',tagT]]}; | |
var da={sn:'deviantart.com',usrF:'/',usr:fU,ty:[['gallery',galT],['prints',prnT],['favourites',favT],['journal',jourT]],noUsr:['join']}; | |
var etsy={sn:'etsy.com',usrF:['shop'],posF:['listing'],usr:sFU,usrS:8,usrL:2,tag:'link',attr:'href',match:'start',attrV:'https://www.etsy.com/shop/',clean:'?',clPos:'until'}; | |
var fb={sn:'facebook.com',usrF:'/',usr:fU} | |
var ffn={sn:'fanfiction.net',usrF:['u'],posF:['s'],usr:sSFU,usrS:1,usrL:2,tag:'a',attr:'href',match:'start',attrV:'/u/'}; | |
var ij={sn:'insanejournal.com',usrF:'.',usr:sD}; | |
var ig={sn:'instagram.com',usrF:'/',usr:fU,usrS:8,usrL:1,tag:'link',attr:'rel',match:'exact',attrV:'canonical'}; | |
var jf={sn:'journalfen.com',usrF:['users'],usr:sFU,ty:[['profile',proT],['read',rdT],['archive',arcT],['tag',tagT]]}; | |
var lf={sn:'last.fm',usrF:['user'],usr:sFU,ty:[['listening-report',rprT],['library',libT],['following',folgT],['followers',folrT],['loved',lovT],['events',evnT],['neighbours',neiT],['tags',tagT],['shoutbox',shT]]}; | |
var lj={sn:'livejournal.com',usrF:'.',usr:sD,ty:[['profile',proT],['friends',frndT],['calendar',arcT],['memories',memT]]}; | |
var lro={sn:'rossia.org',usrF:['users','community'],usr:sFU,ty:[['friends',frndT],['calendar',arcT],['tag',tagT]]}; | |
var med={sn:'medium.com',usrF:'/',usr:fU,usrS:8,usrL:1,tag:'link',attr:'rel',match:'exact',attrV:'author',clean:'@',clPos:'start'}; | |
var pin={sn:'pinboard.in',usrF:'/',usr:fU,clean:'u:',clPos:'start'}; | |
var plrk={sn:'plurk.com',usrF:'/',usr:fU}; | |
var rav={sn:'ravelry.com',usrF:['designers'],posF:['patterns'],usr:sFU,usrS:8,usrL:2,tag:'a',attr:'href',match:'start',attrV:'https://www.ravelry.com/designers/'}; | |
var tum={sn:'tumblr.com',usrF:'.',usr:sD}; | |
var wp={sn:'wordpress.com',usrF:'.',usr:sD}; | |
var yt={sn:'youtube.com',usrF:['user'],usr:sFU}; | |
var s=[ao3,blo,dj,dw,da,etsy,fb,ffn,lj,ig,jf,lf,lj,lro,med,pin,plrk,rav,tum,wp,yt]; | |
var i=0; | |
while(i<s.length){ | |
if(sN==s[i].sn) { | |
var c=s[i]; | |
break; | |
} | |
i++; | |
} | |
//debug | |
alert(c.sn); | |
if(!Boolean(c)){return;} // no match | |
if(c.usrF=='.'){ // subdomain username site | |
if(!Boolean(sD)||sD=='www'){return;}// no username | |
else{ | |
var r=[sD]; | |
if(!Boolean(fU)) {// root folder | |
r.push(bloT); // push blog text onto array | |
return r; | |
} | |
if(Boolean(c.ty)) { | |
var i=0; | |
while(i<c.ty.length) { | |
if(c.ty[0]==fU) { | |
r.push(c.ty[1]); // add the corresponding text onto array | |
return r; | |
} | |
i++; | |
} | |
} | |
r.push(posT); //if no page type, make it a post | |
return r; | |
} | |
} else if(c.usrF=='/'){ //folder username | |
if(!Boolean(fU)){return;} //no username | |
if(Boolean(c.noUsr)) { | |
i=0; | |
while(i<c.noUsr){ | |
if(fU==c.noUser[i]){return;} //no username | |
i++; | |
} | |
} | |
if(c.sn=="medium.com" && fU.includes('@')){ | |
var r=[cleanUp(fU,c.clean,c.clPos)]; | |
} | |
if(!Boolean(r) && Boolean(c.tag)) { //if tag for extracting username is defined | |
var u=userLink(c.tag,c.attr,c.attrV,c.match,c.usrS); | |
if(Boolean(u) && Boolean(u[c.usrL])){ //if there is a folder in the href of link rel="canonical", "author" etc. | |
var r=[cleanUp(u[c.usrL],c.clean,c.clPos)]; | |
if(Boolean(u[c.usrL+1])){ //If there is a subfolder in the canonical link | |
r.push(posT); | |
return r; | |
} else if(c.sn=="instagram.com"||c.sn=="medium.com") { //Instagram | |
r.push(accT); | |
return r; | |
} | |
} | |
} else if (!Boolean(r)) { | |
var r=[cleanUp(fU,c.clean,c.clPos)]; | |
} | |
if(!Boolean(sFU)) { //account page | |
r.push(accT); | |
return r; | |
} else { // posting | |
r.push(posT); | |
return r; | |
} | |
} else { // subfolder username | |
if(!Boolean(fU)){return;} //no user name | |
var i=0; | |
while(i<c.usrF.length) { | |
if(fU==c.usrF[i] && Boolean(sFU)) { | |
if(c.sn=="fanfiction.net" && Boolean(sSFU)) { //ffn exception | |
var r=[cleanUp(sSFU,c.clean,c.clPos)]; | |
} else { | |
var r=[cleanUp(sFU,c.clean,c.clPos)]; //got user name from URL | |
} | |
} | |
i++; | |
} | |
if(Boolean(r)) { //if we are in a username folder | |
if(Boolean(c.posF)) { //and there is a separate folder structure for posts | |
r.push(accT); | |
return r; | |
} else if(Boolean(c.ty)) { //instead, content is under username folders & there are defined types under username folders | |
var i=0; | |
while(i<c.ty.length) { | |
if(c.ty[i][0]==sSFU) { | |
r.push(c.ty[i][1]); | |
return r; | |
} | |
i++; | |
} | |
// if none of those types fits, it's a post | |
r.push(posT); | |
return r; | |
} | |
} else if(Boolean(c.posF) && Boolean(c.tag)) { //not in a user folder, but there is a contents folder & method for extracting creator accounts | |
var i=0; | |
while(i<c.posF.length) { | |
if(fU==c.posF[i]) { //extract user name from work link | |
var u=userLink(c.tag,c.attr,c.attrV,c.match,c.usrS); | |
var r=[cleanUp(u[c.usrL],c.clean,c.clPos),posT]; | |
return r; | |
} | |
i++; | |
} | |
} else {return;} //I'm out of ideas | |
} | |
return; | |
} | |
// set up the post | |
function boost() { | |
var selectedText = getSelectionHtml(); | |
var subjectText; | |
// parsing url to break down into components for later processing | |
var strippedURL=curURL.substr(8); | |
// split the stripped URL string by slashes | |
// first part is server and domain name | |
var serverDomain = strippedURL.split('/')[0]; | |
var fU = strippedURL.split('/')[1]; | |
var sFU = strippedURL.split('/')[2]; | |
var sSFU = strippedURL.split('/')[3]; | |
//split the server and domain name parts by periods | |
var serverDomainParts = serverDomain.split('.'); | |
//if array serverDomainParts has only one element, it's not a valid URL and the script should be aborted | |
if (serverDomainParts.length <= 1) | |
{return; } | |
// if array serverDomainParts has two elements, give empty string for subdomain | |
// sN(siteName) is top & second level domain | |
else if (serverDomainParts.length == 2){ | |
var sD = ''; | |
var sN = serverDomainParts[0] + '.' + serverDomainParts[1]; | |
} | |
//if array serverDomainParts has three or (generally for non-U.S. domain names like co.uk) more elements, | |
//first element is subdomain, sN(siteName) is top & second level domain | |
else if (serverDomainParts.length >=3){ | |
var sD = serverDomainParts[0]; | |
var sN = serverDomainParts[1] + '.' + serverDomainParts[2]; | |
} | |
if(sN.includes('blogspot.co')) { | |
sN = 'blogspot.com'; | |
} | |
// title of current post | |
var curTitle = document.title; | |
if (sN=="dreamwidth.org" && curTitle.includes(' | ')) | |
{curTitle = curTitle.substr(curTitle.lastIndexOf(' | ')+3);} | |
// build up the content of signal boost optionally using selected text as an excerpt | |
// Removed <p> formatting and starting with a blank string | |
var linkText = ""; | |
var uN=getUserName(sD,sN,fU,sFU,sSFU); | |
// commented out alternate 'From' text in case of no username | |
//if(!userName) | |
//{linkText = linkText + 'From <strong><a href="http://' + sD + (sD=='')?'':'.' + sN + '">' + sD + (sD=='')?'':'.' + sN + '</a>:</strong> ';} | |
if (Boolean(uN) && uN.length > 0) { | |
var userTagSiteAttribute = sN; | |
//exception for BlogSpot | |
if (sN=='blogspot.com') { | |
var userTagSiteAttribute = 'blogger.com'; | |
} | |
//if you have a username, add user tag | |
var linkText = linkText + '<user name="' + uN[0] + '" site=' + userTagSiteAttribute + '>' + uN[1] + ': '; | |
} | |
//builds rest of boost | |
linkText = linkText + '<strong><a href="' + curURL + '">' + curTitle.replace('@','@') + '</a></strong>'; | |
//linkText = linkText ; //what is this? | |
if (selectedText.length > 0) { | |
linkText = linkText + "\n<blockquote> " + selectedText + "</blockquote>"; | |
} | |
// got rid of <p> formatting | |
// checks if you are signalboosting a SignalBoost and prevents dangerous vortices from forming | |
if (!curTitle.includes("Signal Boost: ")){ | |
subjectText = "Signal Boost: " + curTitle;} | |
else {subjectText = curTitle;} | |
postURL = postURL + encodeURIComponent(linkText) + "&subject=" + encodeURIComponent(subjectText); | |
window.location = postURL; | |
} | |
if (confirmBoost()) { | |
boost(); | |
} |
This is so lovely.
I wish DW let us host a draggable button, tho. ( I know less about coding than you do).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Won't work on Pinterest, Twitter, or GitHub (irony!) since these sites cut off inline JavaScript
Changes:
Issues/todo:
Deployment: