From ba50f36c58517bcbe2bc8e5a25d8036142b1b4f3 Mon Sep 17 00:00:00 2001
From: ezsh <ezsh.junk@gmail.com>
Date: Wed, 29 May 2019 01:39:10 +0200
Subject: [PATCH] Add a function to create links with functional handlers

---
 src/js/utilJS.js | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/js/utilJS.js b/src/js/utilJS.js
index a83c254ee3a..53449638be8 100644
--- a/src/js/utilJS.js
+++ b/src/js/utilJS.js
@@ -2293,6 +2293,46 @@ App.UI.passageLink = function(linkText, passage, setter, elementType = 'a') {
 	return res;
 };
 
+App.UI.link = function() {
+	let counter = 0;
+
+	// reset all handlers for each passage
+	$(document).on(':passageinit', function() {
+		State.temporary.linkHandlers = {};
+	});
+
+	return makeLink;
+
+	/**
+	 * Creates a markup for a SugarCube link which executes given function with given arguments
+	 *
+	 * @param {string} linkText link text
+	 * @param {*} handler callable object
+	 * @param {*} args arguments
+	 * @param {string} [passage] the passage name to link to
+	 * @returns {string} link in SC markup
+	 */
+	function makeLink(linkText, handler, args = [], passage = '') {
+		// pack handler and data
+		State.temporary.linkHandlers[counter] = {
+			f: handler,
+			args: Array.isArray(args) ? args : [args]
+		};
+
+		// can't say _linkHandlers here becasue SC does not recognize its own notation in "..._varName"
+		let SCHandlerText =
+			`State.temporary.linkHandlers[${counter}].f(...State.temporary.linkHandlers[${counter}].args);`;
+		++counter;
+
+		if (passage) {
+			return App.UI.passageLink(linkText, passage, SCHandlerText);
+		} else {
+			// data-passage scheme does not work with empty passage name
+			return `<<link "${linkText}">><<run ${SCHandlerText}>><</link>>`;
+		}
+	}
+}();
+
 /**
  * Replaces contents of the element, identified by the given selector, with wiki'ed new content
  *
-- 
GitLab