static/js/page/code-blocks.js (194 lines of code) (raw):
import $ from 'jquery';
// Ensure preferred DSL is valid, defaulting to Groovy DSL
const gradleKey = "preferred-gradle-dsl";
const osKey = "preferred-os";
///the order is used for presentation
const allOsNames = [
"macos",
"linux",
"windows"
];
///the order is used for presentation
const allGradleNames = [
"groovy",
"kotlin"
];
const sortAsListedToSet = (fullList, names) => {
const result = [];
fullList.forEach(name => {
if (name === '') {
return;
}
if(names.indexOf(name) === -1) {
console.log("Unknown language " + name + " for " + JSON.stringify(fullList) + " will be ignored");
return;
}
if (result.indexOf(name) === -1) {
result.push(name);
}
});
return result;
};
const loadInitialState = () => {
function initPreferredBuildScriptLanguage() {
let lang = window.localStorage.getItem(gradleKey) || 'nan';
if (allGradleNames.indexOf(lang) === -1) {
lang = "kotlin";
}
return lang;
}
function initPreferredOSLanguage() {
let osName = window.localStorage.getItem(osKey) || 'nan';
if (allOsNames.indexOf(osName) === -1) {
osName = "macos";
const appVersion = (navigator || {}).appVersion || '';
if (appVersion.indexOf("Win") !== -1) osName = "windows";
if (appVersion.indexOf("Mac") !== -1) osName = "macos";
if (appVersion.indexOf("X11") !== -1) osName = "linux";
if (appVersion.indexOf("Linux") !== -1) osName = "linux";
}
return osName;
}
return {
gradleValue: initPreferredBuildScriptLanguage(),
osValue: initPreferredOSLanguage()
};
};
const saveState = ({osValue = '', gradleValue = ''} = {}) => {
if (osValue !== '') window.localStorage.setItem(osKey, osValue);
if (gradleValue !== '') window.localStorage.setItem(gradleKey, gradleValue);
return loadInitialState();
};
const multiLanguageSampleClass = 'multi-language-sample';
const dataSelectedGroupId = 'data-selector-group';
const newGroup = (tabsAnchor) => {
const r = {tabsAnchor: null, snippets: [], gradleOptions: [], osOptions: [], gradleTabs: [], osTabs: []};
if (tabsAnchor) r.tabsAnchor = tabsAnchor;
return r;
};
const createSnippetInfo = ($, divElement) => {
const osValue = (divElement.getAttribute("data-os") || '').toLowerCase();
const gradleValue = (divElement.getAttribute("data-lang") || '').toLowerCase();
return {
osValue,
gradleValue,
updateSelected : state => {
const selectedOs = osValue === '' || osValue === state.osValue;
const selectedGradle = gradleValue === '' || gradleValue === state.gradleValue;
if (selectedOs && selectedGradle) {
divElement.classList.remove("hide")
} else {
divElement.classList.add("hide")
}
}
};
};
const locateCodeElements = ($) => {
const selectorGroups = {};
[].slice.call(document.querySelectorAll("." + multiLanguageSampleClass)).forEach((divElement, index) => {
const prevSibling = divElement.previousElementSibling;
let groupId;
if (prevSibling !== null && prevSibling.classList.contains(multiLanguageSampleClass)) {
groupId = prevSibling.getAttribute(dataSelectedGroupId);
} else {
groupId = "snippet-" + index;
}
divElement.setAttribute(dataSelectedGroupId, groupId);
const groupMembers = (selectorGroups[groupId] || newGroup(divElement) );
selectorGroups[groupId] = groupMembers;
const info = createSnippetInfo($, divElement);
const {osValue, gradleValue} = info;
groupMembers.osOptions.push(osValue);
groupMembers.gradleOptions.push(gradleValue);
groupMembers.snippets.push(info);
});
[].slice.call(document.querySelectorAll(".multi-language-span[data-os], .multi-language-span[data-lang]")).forEach((divElement, index) => {
const groupMembers = newGroup();
selectorGroups["span-" + index] = groupMembers;
const info = createSnippetInfo($, divElement);
groupMembers.snippets.push(info);
});
return selectorGroups;
};
const generateTabs = ($, selectorGroups, updateState) => {
//generate tabs section
for (const groupKey in selectorGroups) {
if (!selectorGroups.hasOwnProperty(groupKey)) continue;
const group = selectorGroups[groupKey];
//in-line code snippets do not have tabs
const firstCodeBlockNode = group.tabsAnchor;
if (!firstCodeBlockNode) continue;
const languageSelectorFragment = document.createDocumentFragment();
const multiLanguageSelectorElement = document.createElement("div");
multiLanguageSelectorElement.classList.add("multi-language-selector");
languageSelectorFragment.appendChild(multiLanguageSelectorElement);
sortAsListedToSet(allGradleNames, group.gradleOptions).forEach(opt => {
const optionEl = document.createElement("code");
optionEl.setAttribute("data-lang", opt);
optionEl.setAttribute("role", "button");
optionEl.classList.add("language-option");
optionEl.innerText = opt.charAt(0).toUpperCase() + opt.slice(1);
group.gradleTabs.push({
updateSelected: state => {
if (state.gradleValue === opt) {
optionEl.classList.add("selected");
} else {
optionEl.classList.remove("selected");
}
}
});
optionEl.addEventListener("click", () => {
updateState({gradleValue: opt})
});
multiLanguageSelectorElement.appendChild(optionEl);
});
sortAsListedToSet(allOsNames, group.osOptions).reverse().forEach(opt => {
const optionEl = document.createElement("code");
optionEl.setAttribute("data-os", opt);
optionEl.setAttribute("role", "button");
optionEl.classList.add("os-option");
optionEl.innerText = " ";
group.osTabs.push({
updateSelected: state => {
if (state.osValue === opt) {
optionEl.classList.add("selected");
} else {
optionEl.classList.remove("selected");
}
}
});
optionEl.addEventListener("click", () => {
updateState({osValue: opt})
});
multiLanguageSelectorElement.appendChild(optionEl);
});
const clearDiv = document.createElement("div");
clearDiv.setAttribute("clear", "both");
languageSelectorFragment.appendChild(clearDiv);
firstCodeBlockNode.parentNode.insertBefore(languageSelectorFragment, firstCodeBlockNode);
}
};
$(document).ready(($) => {
// select code sections and group neighbours to same groups
const selectorGroups = locateCodeElements($);
const updateState = (newStatePatch) => {
//update local storage
const state = saveState(newStatePatch);
for (const groupKey in selectorGroups) {
if (!selectorGroups.hasOwnProperty(groupKey)) continue;
const group = selectorGroups[groupKey];
group.snippets.forEach(snippet => {
snippet.updateSelected(state);
});
group.gradleTabs.forEach(tab => {
tab.updateSelected(state);
});
group.osTabs.forEach(tab => {
tab.updateSelected(state);
});
}
};
generateTabs($, selectorGroups, updateState);
updateState();
if (!Object.keys || Object.keys(selectorGroups).length !== 0) {
///The page is updated white code elements are formatted or hidden,
///the code ensures the page is finally scrolled to the anchor/hash
setTimeout(() => {
const hash = window.location.hash;
if (hash) {
window.location.hash = hash;
}
}, 10);
}
});