Skip to content

Instantly share code, notes, and snippets.

@ljwrites
Forked from melannen/signal_boost.js
Last active February 18, 2019 10:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ljwrites/45216a154b6c6f245de16f8bc7414855 to your computer and use it in GitHub Desktop.
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
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('@','&commat;') + '</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();
}
@JesseTheK
Copy link

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