{"version":3,"file":"tutorials-4fO81Uh2.js","sources":["../../../frontend/views/tutorials/modules/normalise.js","../../../frontend/views/tutorials/modules/labelObject.js","../../../frontend/views/tutorials/modules/extractMetadata.js","../../../frontend/views/tutorials/modules/handleLanguageFilter.js","../../../frontend/views/tutorials/modules/renderLanguageFilter.js","../../../frontend/views/tutorials/modules/handleTabClick.js","../../../frontend/views/tutorials/modules/activateTabContent.js","../../../frontend/views/tutorials/modules/regexFromObject.js","../../../frontend/views/tutorials/modules/filterDomElements.js","../../../frontend/views/tutorials/modules/updateDomContent.js","../../../frontend/views/tutorials/modules/removeTagLabel.js","../../../frontend/views/tutorials/modules/updatePlaceholder.js","../../../frontend/views/tutorials/modules/appendTagLabel.js","../../../frontend/views/tutorials/modules/initializeContext.js","../../../frontend/views/tutorials/modules/getLabels.js","../../../frontend/views/tutorials/modules/renderTagsFilter.js","../../../frontend/views/tutorials/modules/generateFilterDictionary.js","../../../frontend/views/tutorials/index.js","../../../frontend/entrypoints/controllers/documentation/tutorials.js"],"sourcesContent":["/*\n * normalise(string)\n *\n * returns a sanitized @string to use as a key\n * and attempt to minimise inconsistent metadata\n * that will cause duplication in the tag filter\n *\n * This method strips plurals, grammar, whitespace.\n * and restores trailing \"s\" for certain exceptions:\n *\n * NOTE: iOS, NestJS and SMS are examples of *not* plurals\n *\n * normalise(\"alpha betas\"); //? alphabeta\n * normalise(\"Alpha Betas\"); //? alphabeta\n *\n * normalise(\"Node.js\"); //? nodejs\n * normalise(\"NodeJS\"); //? nodejs\n * normalise(\"NodeJSS\"); //? nodejs\n *\n * normalise(\"SMS\"); //? sms\n *\n */\n\nexport default function normalise(string) {\n return `${string}`\n .trim()\n .toLowerCase()\n .replace(/(\\W+|s+$)/g, '') // strip plurals and non-word\n .replace(/(\\wo|\\wj|^sm)$/, '$1s'); // add \"s\" for iOS or NestJS\n}\n","import normalise from './normalise';\n/*\n * labelObject(string)\n *\n * return a keyed Object with a sanitized id key\n *\n * @string: \"kilroy was here\"\n *\n * returns: {\n * \"kilroywashere\": {\n * id: \"kilroywashere\",\n * label: \"Kilroy was here\",\n * count: 1\n * }\n * }\n *\n */\nexport default function labelObject(string) {\n const label = `${string}`.trim();\n const id = normalise(label);\n return { [id]: { id, label, count: 1 } };\n}\n","import labelObject from './labelObject';\n\n/**\n * Extract metadata from DOM articles\n * returns a collection of all metadata\n * and the DOM article element with a description array\n * as a metadata helper for searching for matches\n *\n * Reminder:\n * The no-results article cards use the same markup and\n * need to be excluded from this metadata return so that\n * filtering does not affect them.\n */\n\nexport default function extractMetadata(container = '#all-tutorials') {\n const selector = '.c-card--article';\n const section = document.querySelector(container);\n const articles = section.querySelectorAll(selector);\n return Array.from(articles)\n .map(el => {\n const { dataset, id } = el;\n\n // Ignore the loading placeholder DOM elements\n if (!id) return null;\n\n const parent = el.closest('section');\n const { category } = dataset;\n let { languages = null, tags = null } = dataset;\n\n // Parse lists to Array, or if not available return null\n languages = languages ? JSON.parse(languages) : null;\n tags = tags ? JSON.parse(tags) : null;\n\n if (!languages || !tags || !languages.length || !tags.length) {\n // eslint-disable-next-line no-console\n console.warn('Malformed! tags: %s languages: %s', tags, languages, el);\n return null;\n }\n\n // Metadata helpers\n const filters = {\n languages: { ...Object.assign.apply({}, languages.map(labelObject)) },\n tags: { ...Object.assign.apply({}, tags.map(labelObject)) },\n };\n\n // Create a String description for filtering\n const description = [].concat([category], languages, tags).filter(s => s);\n\n // Catenate the description as TSV (tab delimited values)\n const tsv = ['', ...description, ''].join('\\t');\n\n return {\n ...dataset,\n languages,\n filters,\n tsv,\n tags,\n id,\n el,\n parent,\n description,\n };\n })\n .filter(a => a);\n}\n","/*\n * Manages click event to set state of the filter Object\n * returns Object (and sets global state.filter)\n * */\nexport default function handleLanguageFilter(e) {\n const { state } = this;\n const { current, tabs } = state.context;\n const tabsCurrent = tabs[current];\n let { languages } = tabsCurrent;\n\n const a = e.target.closest('a');\n const { href, classList } = a;\n const lang = href.match(/#(\\w+)$/i)[1];\n\n if (classList.contains('is-inactive')) return;\n\n const selected = classList.toggle('selected');\n const reset = /all/i.test(lang);\n\n // reset or append. \"all\" resets, the rest append to filter list\n languages = reset ? { all: true } : { ...languages, [lang]: selected, all: false };\n\n const hasActiveFilter = Object.entries(languages).some(arr => arr[1]);\n\n // ensure there is always one language filter active\n // if there are no filters reset by flagging \"all\"\n tabsCurrent.languages = hasActiveFilter ? { ...languages } : { all: true };\n\n // return tabsCurrent.languages;\n}\n","/*\n * manages the UI view state for the language toggle buttons\n * adds or removes the .selected classname\n */\n\nexport default async function renderLanguageFilter() {\n const { state } = this;\n const { languages } = state.$;\n\n const { current, tabs } = state.context;\n const tabsCurrent = tabs[current];\n const currentLanguages = tabsCurrent.languages;\n\n const children = languages.querySelectorAll('a');\n const showAll = currentLanguages.all;\n const reAll = /all/i; // case insensitive\n const reKey = /#(\\w+)$/i; // extract key from A href (hash)\n\n let available = {};\n\n // Collate the dictionary of available langs:\n // Ignore other tab content and hidden Elements\n\n state.$.tutorials\n .filter(item => item.category === current)\n .forEach(item => {\n if (!item.languages || !item.languages.length) return;\n if (/hidden/gi.test(item.el.parentNode.className)) return;\n\n const objs = item.languages.map(s => ({ [s]: true }));\n available = {\n ...available,\n ...Object.assign.apply({}, objs),\n };\n });\n\n Array.prototype.forEach.call(children, el => {\n const key = el.href.match(reKey)[1];\n const exists = available[key] ? 'remove' : 'add';\n const isAll = reAll.test(key);\n let method = currentLanguages[key] ? 'add' : 'remove';\n\n // the ALL filter does not toggle itself\n method = showAll && isAll ? 'add' : method;\n el.classList[method]('selected');\n\n // Ghost inactive tabs unless it is the ALL button\n if (!isAll) el.classList[exists]('is-inactive');\n });\n}\n","/**\n * Set the new active tab and reset the filters\n */\nexport default function handleTabClick(e) {\n const { state } = this;\n\n const button = e.target.closest('button');\n const { platformTarget = null } = button.dataset;\n\n // Clear previous tab state and elect new one\n const previous = state.$.tabs.querySelectorAll('.is-selected')[0];\n previous.classList.remove('is-selected');\n button.classList.add('is-selected');\n\n state.context.current = platformTarget;\n}\n","export default function activateTabContent() {\n const { state } = this;\n const { current } = state.context;\n\n // un-hide the section blocks\n state.$.sections.forEach(section => section.classList[section.id !== current ? 'add' : 'remove']('u-hidden'));\n}\n","function safeRegex(string = '') {\n // escape hyphens\n const esc = /([-]+)/g;\n return `${string}`.replace(esc, '\\\\$1');\n}\n\n/*\n * regexFromObject(object, switch, boundary)\n *\n * Given a key value pair as Object literal\n * return a RegularExpression to matche the truthful key(s)\n * and ignore the key \"all\" which is basically .*\n *\n * @object: {\n * swift: false,\n * javascript: true,\n * nodejs: true\n * }\n *\n * @switch: \"i\" - case insensitive\n * @boundary: \"\\t\" - word boundary like TAB for a tsv\n *\n * returns {\n * rex: /(javascript|nodejs)\\t/i,\n * count: 2,\n * entries: [\"javascript\", \"nodejs\"]\n * }\n *\n */\n\nexport default function regexFromObject(object, switches = 'i', boundary = '\\\\t') {\n const entries = Object.entries(object);\n const patterns = entries.filter(([key, value]) => key !== 'all' && value).map(([key]) => safeRegex(key));\n\n const count = patterns.length;\n const rex = !count ? /(.*)/ : new RegExp(`(${patterns.join('|')})${boundary}`, switches);\n\n return { rex, count, entries };\n}\n","import regexFromObject from './regexFromObject';\n\nexport default function filterDomElements() {\n const { state } = this;\n const { current, tabs } = state.context;\n const { languages, tags } = tabs[current];\n\n let elements = state.$.tutorials;\n\n // Active tab content\n elements = elements.filter(item => item.category === current);\n\n // Selected languages\n elements = elements.filter(item => {\n const { rex, count } = regexFromObject(languages, 'g');\n const match = item.tsv.match(rex) || [];\n const show = count ? match.length === count : true;\n const method = show ? 'remove' : 'add';\n\n item.el.parentNode.classList[method]('u-hidden');\n return show;\n });\n // Selected tags\n if (!tags.all) {\n delete tags.all;\n const activeTags = Object.keys(tags);\n\n elements = elements.filter(item => {\n const tagArray = Object.keys(item.filters.tags);\n const and = activeTags.every(id => tagArray.indexOf(id) + 1);\n const method = and ? 'remove' : 'add';\n\n item.el.parentNode.classList[method]('u-hidden');\n return and;\n });\n }\n // return state.$.tutorials;\n return elements;\n}\n","// import regexFromObject from './regexFromObject';\nimport filterDomElements from './filterDomElements';\n\nexport default async function updateDomContent() {\n const { state } = this;\n const elements = filterDomElements.call({ state });\n\n // Reset the group visibility counter\n state.$.groups.forEach(el => (el.dataset.visibleCount = 0));\n\n // Count the population of articles per group\n const visibleGroups = {};\n elements.forEach(row => {\n const group = row.el.closest('[data-group-id]');\n if (!group) return;\n\n const id = group.dataset.groupId;\n const visibleCount = Number(group.dataset.visibleCount);\n group.dataset.visibleCount = visibleCount + 1;\n group.classList.remove('hide-divider');\n visibleGroups[id] = visibleCount + 1;\n });\n\n // Toggle the un-populated groups\n const totalCount = state.$.groups.reduce((acc, el) => {\n const { visibleCount = 0 } = el.dataset;\n const method = Number(visibleCount) ? 'remove' : 'add';\n el.classList[method]('u-hidden');\n return acc + Number(visibleCount);\n }, 0);\n\n // Edge cases: after filtering hide the HR in the very last group\n Object.entries(visibleGroups)\n .slice(-1)\n .forEach(([id]) => {\n document.querySelector(`[data-group-id=\"${id}\"]`).classList.add('hide-divider');\n });\n\n // Toggle the no-results banner block\n if (state.$.noresults && state.$.noresults.classList) {\n state.$.noresults.classList[totalCount ? 'add' : 'remove']('u-hidden');\n }\n}\n","export default function removeTagLabel(el) {\n const { state } = this;\n const { current, tabs } = state.context;\n const { tags } = tabs[current];\n\n if (!el || !el.parentNode) return false;\n\n const popular = el.classList.contains('is-popular');\n el.parentNode.removeChild(el);\n\n // Return this element to its correct container\n state.$.tags[popular ? 'popular' : 'list'].append(el);\n\n // Remove key from the filter collection\n delete tags[el.dataset.tagsId];\n\n if (!Object.keys(tags).length) tags.all = true;\n\n return el;\n}\n","export default async function updatePlaceholder() {\n const { state } = this;\n const { input } = state.$.tags;\n input.classList[input.childElementCount ? 'add' : 'remove']('hide-placeholder');\n}\n","export default function appendTagLabel(e) {\n const { state } = this;\n const { current, tabs } = state.context;\n const { tags } = tabs[current];\n const el = e.target.closest('[data-tags-id]');\n\n if (!el) return;\n\n // Update context filters\n tags[el.dataset.tagsId] = true;\n delete tags.all;\n\n tabs[current].tags = { ...tags };\n}\n","/*\n * tagFilterFromHash(defaults, target, hash, glossary, defaultTab)\n *\n * if there is an incoming hash set the tags filter\n *\n * @defaults Object generic filter defaults\n * @target String the target tab id eg. channels, OR api-hub\n * @hash String (optional) filter id eg. #webrtc OR #api-hub--protocoladapter\n * @glossary Object dictionary of valid tags\n * @current String (optional) default tab id\n *\n * WARNING!!! jQuery is throwing errors with \"/\" in hash\n * so resorted to use \"--\" for path deliminator\n *\n * If there is no path separator \"--\"\n * the path value is @current or \"channels\"\n *\n * Usage: (window.location.hash)\n * #protocoladapter >> tab: channels tag: protocoladapter\n * #channels--webtrc >> tab: channels tag: webtrc\n * #api-hub--bitcoin >> tab: api-hub tag: bitcoin\n *\n */\n\nfunction tagFilterFromHash(defaults, target, hash, glossary, defaultTab = 'channels') {\n const reHashMatch = /^#([a-z\\-]*-+)?([a-z]+)$/; // eslint-disable-line no-useless-escape\n\n if (!hash || !reHashMatch.test(hash)) return defaults;\n\n const parts = hash.match(reHashMatch);\n let [tabId = defaultTab, tagId = ''] = parts.slice(1);\n\n tabId = tabId.replace(/-+$/g, '');\n tagId = tagId.replace(/-+$/g, '');\n\n // Out of context OR hash value does not exist in glossary\n if (tabId !== target || !glossary[tagId]) return defaults;\n\n delete defaults.tags.all;\n defaults.tags[tagId] = true;\n\n return { ...defaults };\n}\n\nexport default function initializeContext() {\n let current = null;\n const { hash = '' } = window.location;\n const { state } = this;\n const glossary = this.state.filterGlossary;\n const targets = state.$.tabs.querySelectorAll('[data-platform-target]');\n const tabs = Object.assign.apply(\n {},\n Array.from(targets).map(el => {\n const { classList, dataset } = el;\n const { platformTarget } = dataset;\n let defaults = { languages: { all: true }, tags: { all: true } };\n\n current = current || (classList.contains('is-selected') && platformTarget);\n defaults = tagFilterFromHash(defaults, platformTarget, hash, glossary);\n\n return { [platformTarget]: { ...defaults } };\n }),\n );\n\n if (hash) window.location.hash = '';\n state.context = { current, tabs };\n}\n","export default function getLabels(array, minCount = 1, maxLength = null) {\n return [...array]\n .map((row, i) => {\n const { id, label, count, hidden } = row;\n\n if (typeof maxLength === 'number' && i >= maxLength) return null;\n\n const counter = count ? `${count}` : '';\n\n return count >= minCount\n ? `${label}${counter}`\n : null;\n })\n .filter(s => s);\n}\n","import filterDomElements from './filterDomElements';\nimport getLabels from './getLabels';\n\nfunction getAvailableTags(collection) {\n const countedTags = collection\n .map(item => ({ ...item.filters.tags }))\n .reduce((acc = {}, curr) => {\n Object.keys(curr).forEach(id => (acc[id] ? (curr[id].count = acc[id].count + 1) : null));\n return { ...acc, ...curr };\n }, {});\n\n return Object.values(countedTags).sort((a, b) => b.count - a.count);\n}\n\nexport default async function renderTagsFilter() {\n const { state } = this;\n const emptyText = state.tagFilterEmptyText;\n const articleCount = state.popularTagMinArticleCount;\n const maxItems = state.popularTagMaxItems;\n const { current, tabs } = state.context;\n const { tags } = tabs[current];\n const $ = state.$.tags;\n\n const collection = filterDomElements.call({ state });\n const available = getAvailableTags(collection);\n\n const inputTags = available.filter(item => (item.hidden = tags[item.id] || false));\n\n let popular = [];\n let remainder = [];\n\n popular = available.length > maxItems ? getLabels(available, articleCount, maxItems) : [];\n\n remainder = available.slice(popular.length);\n remainder = getLabels(remainder.filter(n => !n.hidden));\n remainder = remainder.length ? remainder : [`${emptyText}`];\n\n $.list.innerHTML = remainder.join('');\n $.popular.innerHTML = popular.join('');\n $.input.innerHTML = getLabels(inputTags).join('');\n $.popular.parentNode.classList[popular.length ? 'add' : 'remove']('reveal-list');\n}\n","/*\n * generateFilterDictionary()\n *\n * Creates a dictionary of valid tags and languages\n * derived from the languages & tags that appear\n * in the DOM this is required to mitigate the risk\n * of applying a non-existent filter\n *\n */\n\nexport default function generateFilterDictionary() {\n const { $, filterGlossary } = this.state;\n const { tutorials } = $;\n\n // Use existing cache if possible\n if (filterGlossary) return filterGlossary;\n\n const filters = tutorials.map(el => {\n return [...Object.keys(el.filters.languages || {}), ...Object.keys(el.filters.tags || {})];\n });\n\n // Flatten into Object literals\n // eslint-disable-next-line prefer-spread\n let keys = [].concat.apply([], filters).map(key => ({ [key]: true }));\n\n // Collapse into uniquely keyed collection\n // eslint-disable-next-line prefer-spread\n keys = Object.assign.apply({}, keys);\n\n this.state.filterGlossary = keys;\n return keys;\n}\n","import { select, selectAll } from 'global/utils/dom';\nimport extractMetadata from './modules/extractMetadata';\nimport handleLanguageFilter from './modules/handleLanguageFilter';\nimport renderLanguageFilter from './modules/renderLanguageFilter';\nimport handleTabClick from './modules/handleTabClick';\nimport activateTabContent from './modules/activateTabContent';\nimport updateDomContent from './modules/updateDomContent';\nimport removeTagLabel from './modules/removeTagLabel';\nimport updatePlaceholder from './modules/updatePlaceholder';\nimport appendTagLabel from './modules/appendTagLabel';\nimport initializeContext from './modules/initializeContext';\nimport renderTagsFilter from './modules/renderTagsFilter';\nimport generateFilterDictionary from './modules/generateFilterDictionary';\n\nexport default function initFilters() {\n const state = {\n // Optional UI behaviours\n popularTagMinArticleCount: 3,\n popularTagMaxItems: 4,\n tagFilterEmptyText: 'No filter tags available',\n\n // Default state reference\n context: null,\n filterGlossary: null,\n\n $: {\n // The DOM is the dataset, extract the data.\n tutorials: extractMetadata(),\n\n // DOM Entities\n languages: select('.c-lang-filter-list'),\n noresults: select('#tutorials-noresults'),\n sections: selectAll('.c-section.c-cards-container'),\n groups: selectAll('[data-group-id]'),\n tabs: select('[data-Tutorials-platforms-filter]'),\n tags: {\n input: select('[data-tags-input]'),\n list: select('[data-tags-list]'),\n popular: select('[data-tags-popular]'),\n },\n },\n };\n\n // Async operators\n async function render() {\n updateDomContent.call({ state });\n renderLanguageFilter.call({ state });\n renderTagsFilter.call({ state });\n updatePlaceholder.call({ state });\n }\n\n const { $ } = state;\n // Delegated event handlers\n $.languages.onclick = e => {\n e.preventDefault();\n handleLanguageFilter.call({ state }, e);\n render();\n };\n\n $.tabs.onclick = e => {\n e.preventDefault();\n handleTabClick.call({ state }, e);\n activateTabContent.call({ state });\n render();\n };\n\n $.tags.popular.onclick = e => {\n e.preventDefault();\n appendTagLabel.call({ state }, e);\n render();\n };\n\n $.tags.input.onclick = e => {\n // opens/closes the menu -or-\n // removes an active tag\n\n e.preventDefault();\n const el = e.target;\n const toggle = el.closest('.c-filter-tags');\n const tag = el.closest('a');\n\n // exit if a tag has been removed\n if (removeTagLabel.call({ state }, tag)) return render();\n\n // exit if the toggled menu is closed\n if (!toggle.classList.toggle('show-tags')) return null;\n\n // the menu is now open so bind the next click to close it\n // and prevent this click event from bubbeling\n\n e.preventDefault();\n e.stopImmediatePropagation();\n\n return document.addEventListener(\n 'click',\n ev => {\n ev.preventDefault();\n toggle.classList.remove('show-tags');\n appendTagLabel.call({ state }, ev);\n render();\n },\n { once: true },\n );\n };\n\n // With the DOM metadata ...\n generateFilterDictionary.call({ state });\n initializeContext.call({ state });\n render();\n}\n","/**\n * this code will run on all tutorials action pages\n * pages_controller\n * @see [1] - documentation_controller.rb\n */\nimport './show'; // [1]\nimport 'views/tutorials/tutorials.scss';\nimport initFilters from 'views/tutorials/index';\n\ndocument.addEventListener('DOMContentLoaded', function tutorialsContentLoaded() {\n initFilters();\n});\n"],"names":["normalise","string","labelObject","label","id","extractMetadata","container","articles","el","dataset","parent","category","languages","tags","filters","description","s","tsv","a","handleLanguageFilter","e","state","current","tabs","tabsCurrent","href","classList","lang","selected","hasActiveFilter","arr","renderLanguageFilter","currentLanguages","children","showAll","reAll","reKey","available","item","objs","key","exists","isAll","method","handleTabClick","button","platformTarget","activateTabContent","section","safeRegex","esc","regexFromObject","object","switches","boundary","entries","patterns","value","count","filterDomElements","elements","rex","match","show","activeTags","tagArray","and","updateDomContent","visibleGroups","row","group","visibleCount","totalCount","acc","removeTagLabel","popular","updatePlaceholder","input","appendTagLabel","tagFilterFromHash","defaults","target","hash","glossary","defaultTab","reHashMatch","parts","tabId","tagId","initializeContext","targets","getLabels","array","minCount","maxLength","i","hidden","counter","getAvailableTags","collection","countedTags","curr","b","renderTagsFilter","emptyText","articleCount","maxItems","$","inputTags","remainder","n","generateFilterDictionary","filterGlossary","tutorials","keys","initFilters","select","selectAll","render","toggle","tag","ev"],"mappings":"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"}