xref: /template/readthedokus/js/readthedokus.js (revision 214d19542acf1cda61cd3cc26a703935eb77df57)
1function ReadtheDokus()
2{
3
4	this._currentPage;
5	this._currentPageIndex;
6	this._pages;
7	this._toc = document.getElementById("dw__toc");
8	this._sidebar =document.querySelector("#dokuwiki__aside");
9	this._delimiter = ( window.location.search.indexOf(":") > -1 ? ":" : "/");
10	this._id = ( this._delimiter == ":" ? JSINFO["id"] : JSINFO["id"].replaceAll(":", "/"));
11	this._startPage;
12
13}
14
15ReadtheDokus.prototype.run = function()
16{
17
18	var isFound = false;
19	this._pages = [];
20
21	// Enum sidebar items to
22	//   - embed toc in the corresponding sidebar item
23	//   - collect all page links
24	if (JSINFO["ACT"] == "show")
25	{
26		this._enumSidebarLinks(function(elem) {
27			// Embed toc
28			if (elem.href.indexOf(this._id) > -1)
29			{
30				this._embedToc(elem);
31				if (this._toc)
32				{
33					this._toc.scrollIntoView(true);
34				}
35				isFound = true;
36			}
37
38			// Collect page links
39			this._pages.push(elem.href);
40		}.bind(this));
41	}
42
43	var re = new RegExp("\\" + this._delimiter + "[^\\" + this._delimiter + "]*[^\\" + this._delimiter + "]*$");
44	this._startPage = this._pages[0].replace(re, "").replace(re, "") + this._delimiter + "start";
45	this._pages.unshift(this._startPage);
46
47	// Show toc on top of sidebar if item was not found in sidebar
48	if (!isFound)
49	{
50		if (this._toc)
51		{
52			this._showToc();
53			this._toc.scrollIntoView(true);
54		}
55	}
56
57	if (this._toc)
58	{
59		this._initToc();
60	}
61	this._initMobileHeader();
62	this._initPageButtons();
63	this._sidebar.querySelector("#sidebarheader #qsearch__in").setAttribute("placeholder", "Search docs");
64
65};
66
67ReadtheDokus.prototype._enumSidebarLinks = function(callback)
68{
69
70	callback = ( typeof callback === "function" ? callback : function(){} );
71	var links = this._sidebar.querySelectorAll(".aside > ul .level1 a");
72
73	links.forEach(function(elem) {
74		callback(elem);
75	});
76
77};
78
79ReadtheDokus.prototype._embedToc = function(target)
80{
81
82	if (target && this._toc)
83	{
84		target.parentNode.parentNode.appendChild(this._toc);
85		target.parentNode.style.display = "none";
86	}
87
88};
89
90ReadtheDokus.prototype._showToc = function()
91{
92
93	if (this._toc)
94	{
95		this._toc.parentNode.style.display = "block";
96	}
97
98};
99
100ReadtheDokus.prototype._initToc = function()
101{
102
103	this._installTocSelectHandler();
104	this._installTocMenuHandler();
105
106};
107
108ReadtheDokus.prototype._installTocSelectHandler = function()
109{
110
111	this._toc.querySelectorAll(".level2 a").forEach(function(elem) {
112		elem.addEventListener("click", function() {
113			this._toc.querySelectorAll(".current").forEach(function(elem) {
114				elem.classList.remove("current");
115			});
116			elem.parentNode.parentNode.classList.add("current");
117			elem.classList.add("current");
118			elem.scrollIntoView(true);
119		}.bind(this));
120	}.bind(this));
121
122};
123
124ReadtheDokus.prototype._installTocMenuHandler = function()
125{
126
127	this._toc.querySelectorAll(".level1 a").forEach(function(elem) {
128		if (elem.parentNode.parentNode.querySelector(".toc"))
129		{
130			elem.insertAdjacentHTML("afterbegin", '<div class="btn-expand"><i class="far fa-minus-square"></i><img class="minus" src="/docs/lib/images/minus.gif" alt="−"></div>');
131
132			var i = elem.childNodes[0].querySelector("i");
133			i.addEventListener("click", function(e) {
134				this._toggleTocMenu(i);
135
136				e.stopPropagation();
137				e.preventDefault();
138			}.bind(this));
139
140			/*
141			var img = elem.childNodes[0].querySelector("img");
142			img.addEventListener("click", function(e) {
143				this._toggleTocMenu(i);
144
145				e.stopPropagation();
146				e.preventDefault();
147			}.bind(this));
148			*/
149		}
150
151		elem.addEventListener("click", function() {
152			elem.scrollIntoView(true);
153		});
154	}.bind(this));
155
156};
157
158ReadtheDokus.prototype._toggleTocMenu = function(elem)
159{
160
161	elem.parentNode.parentNode.parentNode.parentNode.querySelector(".toc").classList.toggle("invisible");
162
163	if (elem.classList.contains("fa-minus-square"))
164	{
165		elem.classList.remove("fa-minus-square");
166		elem.classList.add("fa-plus-square");
167	}
168	else
169	{
170		elem.classList.remove("fa-plus-square");
171		elem.classList.add("fa-minus-square");
172	}
173
174}
175
176ReadtheDokus.prototype._foldMenu = function(elem, foldAllChildren)
177{
178}
179
180ReadtheDokus.prototype._initMobileHeader = function()
181{
182
183	// Add click event handler for mobile menu
184	document.getElementById("btn-mobilemenu").addEventListener("click", function(){
185		this._sidebar.classList.toggle("visible");
186		document.querySelector("#dokuwiki__content").classList.toggle("shift");
187	}.bind(this));
188
189};
190
191ReadtheDokus.prototype._initPageButtons = function()
192{
193
194	// Get current page (remove hash)
195	this._currentPage = window.location.href.replace(/#.*$/, "");
196
197	// Get current page index
198	this._currentPageIndex = this._pages.indexOf(this._currentPage);
199
200	// Show prev button
201	if (this._currentPageIndex > 0)
202	{
203		document.getElementById("btn-prevpage").classList.add("visible");
204		document.getElementById("btn-prevpage").href = this._pages[this._currentPageIndex - 1];
205	}
206
207	// Show next button
208	if (this._currentPageIndex < this._pages.length - 1)
209	{
210		document.getElementById("btn-nextpage").classList.add("visible");
211		document.getElementById("btn-nextpage").href = this._pages[this._currentPageIndex + 1];
212	}
213
214};
215