(function() { // switch: v1.2 "use strict"; var versionsFileUrl = "https://docs.blender.org/PROD/versions.json" var all_versions; var Popover = function() { function Popover(id) { this.isOpen = false; this.type = (id === "version-popover"); this.$btn = $('#' + id); this.$dialog = this.$btn.next(); this.$list = this.$dialog.children("ul"); this.sel = null; this.beforeInit(); } Popover.prototype = { beforeInit : function() { var that = this; this.$btn.on("click", function(e) { that.init(); e.preventDefault(); e.stopPropagation(); }); this.$btn.on("keydown", function(e) { if (that.btnKeyFilter(e)) { that.init(); e.preventDefault(); e.stopPropagation(); } }); }, init : function() { this.$btn.off("click"); this.$btn.off("keydown"); if (all_versions === undefined) { this.$btn.addClass("wait"); this.loadVL(this); } else { this.afterLoad(); } }, loadVL : function(that) { $.getJSON(versionsFileUrl, function(data) { all_versions = data; that.afterLoad(); return true; }).fail(function() { console.log("Version Switch Error: versions.json could not be loaded."); that.$btn.addClass("disabled"); return false; }); }, afterLoad : function() { var release = DOCUMENTATION_OPTIONS.VERSION; const m = release.match(/\d\.\d+/g); if (m) { release = m[0]; } this.warnOld(release, all_versions); var version = this.getNamed(release); var list = this.buildList(version); this.$list.children(":first-child").remove(); this.$list.append(list); var that = this; this.$list.on("keydown", function(e) { that.keyMove(e); }); this.$btn.removeClass("wait"); this.btnOpenHandler(); this.$btn.on("mousedown", function(e) { that.btnOpenHandler(); e.preventDefault() }); this.$btn.on("keydown", function(e) { if (that.btnKeyFilter(e)) { that.btnOpenHandler(); } }); }, warnOld : function(release, all_versions) { // Note this is effectively disabled now, two issues must fixed: // * versions.js does not contain a current entry, because that leads to // duplicate version numbers in the menu. These need to be deduplicated. // * It only shows the warning after opening the menu to switch version // when versions.js is loaded. This is too late to be useful. var current = all_versions.current if (!current) { // console.log("Version Switch Error: no 'current' in version.json."); return; } const m = current.match(/\d\.\d+/g); if (m) { current = parseFloat(m[0]); } if (release < current) { var currentURL = window.location.pathname.replace(release, current); var warning = $('
' + '

Note

' + '

' + 'You are not using the most up to date version of the documentation. ' + ' is the newest version.' + '

' + '
'); warning.find('a').attr('href', currentURL).text(current); var body = $("div.body"); if (!body.length) { body = $("div.document"); } body.prepend(warning); } }, buildList : function(v) { var url = new URL(window.location.href); let pathSplit = [ "", "api", v ]; if (url.pathname.startsWith("/api/")) { pathSplit.push(url.pathname.split('/').slice(3).join('/')); } else { pathSplit.push(url.pathname.substring(1)); } if (this.type) { var dyn = all_versions; var cur = v; } var buf = []; var that = this; $.each(dyn, function(ix, title) { buf.push("' + title + ''); } else { pathSplit[2 + that.type] = ix; var href = new URL(url); href.pathname = pathSplit.join('/'); buf.push(' tabindex="-1" role="presentation">' + title + ''); } }); return buf.join(''); }, getNamed : function(v) { $.each(all_versions, function(ix, title) { if (ix === "master" || ix === "latest") { var m = title.match(/\d\.\d[\w\d\.]*/)[0]; if (parseFloat(m) == v) { v = ix; return false; } } }); return v; }, dialogToggle : function(speed) { var wasClose = !this.isOpen; var that = this; if (!this.isOpen) { this.$btn.addClass("version-btn-open"); this.$btn.attr("aria-pressed", true); this.$dialog.attr("aria-hidden", false); this.$dialog.fadeIn(speed, function() { that.$btn.parent().on("focusout", function(e) { that.focusoutHandler(); e.stopImmediatePropagation(); }) that.$btn.parent().on("mouseleave", function(e) { that.mouseoutHandler(); e.stopImmediatePropagation(); }); }); this.isOpen = true; } else { this.$btn.removeClass("version-btn-open"); this.$btn.attr("aria-pressed", false); this.$dialog.attr("aria-hidden", true); this.$btn.parent().off("focusout"); this.$btn.parent().off("mouseleave"); this.$dialog.fadeOut(speed, function() { if (this.$sel) { this.$sel.attr("tabindex", -1); } that.$btn.attr("tabindex", 0); if (document.activeElement !== null && document.activeElement !== document && document.activeElement !== document.body) { that.$btn.focus(); } }); this.isOpen = false; } if (wasClose) { if (this.$sel) { this.$sel.attr("tabindex", -1); } if (document.activeElement !== null && document.activeElement !== document && document.activeElement !== document.body) { var $nw = this.listEnter(); $nw.attr("tabindex", 0); $nw.focus(); this.$sel = $nw; } } }, btnOpenHandler : function() { this.dialogToggle(300); }, focusoutHandler : function() { var list = this.$list; var that = this; setTimeout(function() { if (list.find(":focus").length === 0) { that.dialogToggle(200); } }, 200); }, mouseoutHandler : function() { this.dialogToggle(200); }, btnKeyFilter : function(e) { if (e.ctrlKey || e.shiftKey) { return false; } if (e.key === " " || e.key === "Enter" || (e.key === "ArrowDown" && e.altKey) || e.key === "ArrowDown" || e.key === "ArrowUp") { return true; } return false; }, keyMove : function(e) { if (e.ctrlKey || e.shiftKey) { return true; } var p = true; var $nw = $(e.target); switch (e.key) { case "ArrowUp": $nw = this.listPrev($nw); break; case "ArrowDown": $nw = this.listNext($nw); break; case "Home": $nw = this.listFirst(); break; case "End": $nw = this.listLast(); break; case "Escape": $nw = this.listExit(); break; case "ArrowLeft": $nw = this.listExit(); break; case "ArrowRight": $nw = this.listExit(); break; default: p = false; } if (p) { $nw.attr("tabindex", 0); $nw.focus(); if (this.$sel) { this.$sel.attr("tabindex", -1); } this.$sel = $nw; e.preventDefault(); e.stopPropagation(); } }, listPrev : function($nw) { if ($nw.parent().prev().length !== 0) { return $nw.parent().prev().children(":first-child"); } else { return this.listLast(); } }, listNext : function($nw) { if ($nw.parent().next().length !== 0) { return $nw.parent().next().children(":first-child"); } else { return this.listFirst(); } }, listFirst : function() { return this.$list.children(":first-child").children(":first-child"); }, listLast : function() { return this.$list.children(":last-child").children(":first-child"); }, listExit : function() { this.mouseoutHandler(); return this.$btn; }, listEnter : function() { return this.$list.children(":first-child").children(":first-child"); } }; return Popover }(); $(document).ready(function() { var lng_popover = new Popover("version-popover"); }); })();