Kanka Jump to Post

Adds a dropdown to Kanka entity headers to quickly scroll to the selected post.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Kanka Jump to Post
// @namespace    http://tampermonkey.net/
// @version      5
// @description  Adds a dropdown to Kanka entity headers to quickly scroll to the selected post.
// @author       Salvatos
// @match        https://app.kanka.io/*
// @exclude      */html-export
// @icon         https://www.google.com/s2/favicons?domain=kanka.io
// @grant        GM_addStyle
// ==/UserScript==

// Run only on entity Story pages
if (document.getElementById('app').parentNode.classList.contains("entity-story")) {
	/* Preferences */
	const addTopLink = false;

    /* Set arrays*/
    var hasPosts = 0;
    var posts = [];
    $("article.post-block").each(function(){
        posts.push($(this));
    });

	/* Start dropdown */
	var postList= `
	<div class="btn-group jump-to-post">
		<button type="button" class="btn2 btn-sm join-item dropdown-toggle" tabindex="-1" data-toggle="dropdown" title="Entity posts" aria-expanded="false">
			<i class="fa fa-book" aria-hidden="true"></i>
		</button>
		<ul class="note-dropdown-menu dropdown-menu dropdown-posts" aria-label="Jump to an entity post">
	`;

    /* Insert each item name and ID */
	$.each( posts, function( key, value ) {
        hasPosts++;
        postList+= `
		    <li><a href="#` + $(this).attr('id') + `">` + $.trim($(this).find("h3.post-title").text()) + `</a></li>
    	`;
    });

    /* If there is no post, add a notice (won’t be necessary once Entries are treated like posts) */
    if (hasPosts < 1) {
        postList+= `<li><a><i>No post</i></a></li>`;
    }

    /* Close dropdown */
    postList+= `
		</ul>
	</div>
	`;

	/* Insert element after post expand/collapse buttons */
    $(postList).appendTo(".header-buttons > .join");

    /* Add "top" link to box headings, but don’t let it toggle post visibility */
    if (addTopLink) {
        $("<a class='to-top' href='#app' onclick='event.stopPropagation();'>&nbsp;^&nbsp;top</a>").appendTo(".post-title");
    }

    /* Listener: If the target is a collapsed post, expand it first */
    $(".jump-to-post a").click(function() {
        let targetPost = $(this).attr('href');
        if (targetPost != "undefined" && $(targetPost + " .element-toggle")[0].classList.contains("animate-collapsed")) {
            $(targetPost + " .element-toggle")[0].click();
        }
    });

    GM_addStyle(`
    .jump-to-post .fa-book:after {
		content: " ▼";
        vertical-align: middle;
        font-size: 8px;
	}
    .jump-to-post li a:hover {
    	color: var(--theme-input-text);
    }
    /* preserving necessary bootstrap classes */
    .btn-group {
    	position: relative;
    	display: inline-block;
    	vertical-align: middle;
    }
    .dropdown-menu {
		position: absolute;
		z-index: 1000;
		display: none;
		min-width: 160px;
		padding: 5px 0;
		margin: 2px 0 0;
		font-size: 14px;
		text-align: left;
		list-style: none;
		background-color: hsl(var(--b2)/1);
		background-clip: padding-box;
		border: 1px solid rgba(0,0,0,.15);
		border-radius: 4px;
		box-shadow: 0 6px 12px rgba(0,0,0,.175);
	}
    .open > .dropdown-menu {
		display: block;
	}
    .dropdown-menu > li > a {
		display: block;
		padding: 3px 20px;
		clear: both;
		white-space: nowrap;
	}
	`);
}