{"version":3,"file":"js/application-324fa9f15a060d5b6449.js","mappings":"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","sources":["webpack://cfforum//tmp/build/app/javascript/channels|sync|/_channel\\.js$/","webpack://cfforum/./app/javascript/channels/index.js","webpack://cfforum/./app/javascript/controllers/application.js","webpack://cfforum/./app/javascript/controllers/hello_controller.js","webpack://cfforum/./app/javascript/controllers/index.js","webpack://cfforum/./app/javascript/packs/adm/config/colors.js","webpack://cfforum/./app/javascript/packs/application.js","webpack://cfforum/./app/javascript/packs/categoryTags.js","webpack://cfforum/./app/javascript/packs/ctrlEnter.js","webpack://cfforum/./app/javascript/packs/markdown.js","webpack://cfforum/./app/javascript/packs/nested-forms/addFields.js","webpack://cfforum/./app/javascript/packs/nested-forms/removeFields.js","webpack://cfforum/./app/javascript/packs/tabs.js"],"sourcesContent":["function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nwebpackEmptyContext.id = 6463;\nmodule.exports = webpackEmptyContext;","// Load all the channels within this directory and all subdirectories.\n// Channel files must be named *_channel.js.\n\nconst channels = require.context('.', true, /_channel\\.js$/)\nchannels.keys().forEach(channels)\n","import { Application } from \"@hotwired/stimulus\"\n\nconst application = Application.start()\n\n// Configure Stimulus development experience\napplication.debug = false\nwindow.Stimulus = application\n\nexport { application }\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n connect() {\n this.element.textContent = \"Hello World!\"\n }\n}\n","// This file is auto-generated by ./bin/rails stimulus:manifest:update\n// Run that command whenever you add a new controller or create them with\n// ./bin/rails generate stimulus controllerName\n\nimport { application } from \"./application\"\n\nimport HelloController from \"./hello_controller\"\napplication.register(\"hello\", HelloController)\n","function getElsForCfgKey(cfgKey) {\n const hidden_el = $(`input[type=hidden]#forum_config_${cfgKey}`)[0];\n const picker_el = $(`input[type=color]#${cfgKey}_picker`)[0];\n const hex_el = $(`input[type=text]#${cfgKey}_hex`)[0];\n const default_el = $(`input[type=color]#${cfgKey}_default`)[0];\n return { hidden_el, picker_el, hex_el, default_el };\n}\n\nexport function _forumConfigSyncColors(el, cfgKey) {\n const { hidden_el, picker_el, hex_el } = getElsForCfgKey(cfgKey);\n const form_els = [hidden_el, picker_el, hex_el];\n const newVal = el.value;\n // test validity of hex value, otherwise do nothing\n if (/^#[0-9a-fA-F]{6}$/.test(newVal)) {\n form_els.filter(_el => _el.id != el.id).forEach(_el => _el.value = newVal);\n }\n}\n\nwindow._forumConfigSyncColors = _forumConfigSyncColors;\n\nwindow._resetColorFieldToDefault = (cfgKey) => {\n const form_els = getElsForCfgKey(cfgKey);\n const default_el = form_els.default_el;\n Object.keys(form_els).map(k => form_els[k]).filter(el => el != default_el).forEach(el => el.value = default_el.value);\n}\n","// This file is automatically compiled by Webpack, along with any other files\n// present in this directory. You're encouraged to place your actual application logic in\n// a relevant structure within app/javascript and only use these pack files to reference\n// that code so it'll be compiled.\n\nimport Rails from \"@rails/ujs\"\n// import * as Turbo from \"@hotwired/turbo\";\nimport \"@hotwired/turbo-rails\"\nimport * as ActiveStorage from \"@rails/activestorage\"\nimport \"@primer/octicons/build/build.css\"\nimport Alpine from \"alpinejs\"\nimport \"channels\"\nimport \"stylesheets/application.scss\"\nimport \"controllers\"\n\nwindow.Rails = Rails;\nRails.start()\nActiveStorage.start()\nwindow.Alpine = Alpine;\nwindow.addEventListener('load', () => Alpine.start());\nrequire(\"jquery\")\n\nimport './adm';\nimport './tabs';\nrequire('./nested-forms/addFields');\nrequire('./nested-forms/removeFields');\nrequire('./ctrlEnter');\nrequire('./markdown');\nrequire('./categoryTags');\n","/*\n\nThe objects stored in selectedTags are of the format:\n{\n id: id of the tagdecl if it exists (i.e. if you're editing a post with existing cat tags)\n targetId: id of the category tag\n text: name of the category tag\n tag: establishing the relationship of the tagdecl, in this case: category\n _destroy: boolean that is passed to the backend to handle deletions of existing tags\n}\nThese objects represent TagDecls and are designed so that processing is minimal in the back end.\nTagDecl attrs include: id, target_id, tag, and _destroy.\nThe text attr in this case is used for rendering the ui components.\n\n*/\n\nwindow.categoryTags = function (selectedCtds, cts) {\n return {\n selectedId: \"\",\n selectedTags: selectedCtds,\n categoryTags: cts,\n newTag: \"\",\n\n init() {\n // add all the existing hidden inputs\n this.selectedTags.forEach((el, i) => addHiddenTagInputs(i, el))\n },\n\n addExistingTag(selectedCategoryEl) {\n const text = selectedCategoryEl.options[selectedCategoryEl.selectedIndex].text\n if (text === \"Select a tag\") return\n\n var tagObj = this.selectedTags.find(t => t.text === text)\n if (tagObj != null) {\n // if the _destroy attr is \"1\", the tag has been removed before\n // otherwise the user is selecting a tag that is alr selected, which in that case, do nothing\n if (tagObj._destroy == \"1\") {\n tagObj._destroy = false\n }\n } else {\n const st = {\n targetId: this.selectedId,\n text: text,\n tag: \"category\",\n _destroy: false\n }\n this.selectedTags.push(st)\n addHiddenTagInputs(this.selectedTags.length-1, st)\n }\n },\n\n removeTag(el) {\n const text = el.parentElement.textContent.trim()\n this.selectedTags.find(t => t.text === text)._destroy = \"1\"\n },\n\n addNewTag() {\n const tagObj = this.categoryTags.find(t => t.text === this.newTag)\n const selectedTagObj = this.selectedTags.find(t => t.text === this.newTag)\n if (selectedTagObj != null) {\n // tag has already been selected by the user\n this.newTag = \"\"\n return\n }\n\n if (tagObj == null) {\n // tag is new\n st = {\n text: this.newTag,\n tag: \"category\",\n _destroy: false\n }\n } else {\n // tag exists but hasn't been selected yet\n st = {\n targetId: tagObj.id,\n text: tagObj.tag,\n tag: \"category\",\n _destroy: false\n }\n }\n this.selectedTags.push(st)\n this.newTag = \"\"\n addHiddenTagInputs(this.selectedTags.length-1, st)\n },\n };\n};\n\nfunction mkElementWOpts(elName, options) {\n const el = document.createElement(elName);\n if (!! options.type) { el.type = options.type }\n if (!! options.name) { el.name = options.name }\n if (!! options.value) { el.value = options.value }\n if (!! options.ix || options.ix == 0) { el.setAttribute('x-model', `selectedTags[${options.ix}]._destroy`) }\n return el;\n}\n\nfunction tagInputName(ix, attr) {\n return `node[anchoring_category_tags_attributes][${ix}][${attr}]`\n}\n\nfunction addHiddenTagInputs(ix, el) {\n const tagEl = mkElementWOpts('input', { type: 'hidden', name: tagInputName(ix, \"tag\"), value: el.tag })\n const destroyEl = mkElementWOpts('input', { type: 'hidden', name: tagInputName(ix, \"_destroy\"), value: el._destroy, ix: ix })\n var els = [tagEl, destroyEl]\n\n // targetId only exists if the category tag is an existing user tag\n if (!! el.targetId) {\n els.push(mkElementWOpts('input', { type: 'hidden', name: tagInputName(ix, \"target_id\"), value: el.targetId }))\n } else {\n els.push(mkElementWOpts('input', { type: 'hidden', name: tagInputName(ix, \"name\"), value: el.text }))\n }\n // id only exists for tagDecls that have already been created (i.e. editing a node)\n if (!! el.id) {\n els.push(mkElementWOpts('input', { type: 'hidden', name: tagInputName(ix, \"id\"), value: el.id }))\n }\n\n var form = document.getElementById('cat-tags-form')\n els.forEach(el => form.appendChild(el))\n}\n","window.addEventListener('load', () => {\n const handler = e => {\n const form = $(e.target).parents(\"form\");\n if (form.length) {\n if (e.key === \"Enter\" && e.ctrlKey) {\n form.trigger(\"submit\");\n }\n }\n };\n $(document).on(\"keydown\", handler)\n})\n","import showdown from \"showdown\";\nimport showdownHighlight from \"showdown-highlight\";\n\n\nclass MarkdownHandler {\n // showdown options documented at: https://github.com/showdownjs/showdown#valid-options\n converter = new showdown.Converter({\n tables: true, tasklists: true, smoothLivePreview: true, splitAdjacentBlockquotes: true, simpleLineBreaks: false,\n extensions: [\n showdownHighlight({ pre: true })\n ]\n });\n\n constructor() {\n this.converter.setFlavor('github');\n }\n\n doMarkdownOnLoadEvents() {\n $('#editor').on('click', (event) => this.openTab(event, 'editor-content'))\n $('#preview').on('click', (event) => this.previewMarkdown(event))\n\n const toMarkdown = this.toMarkdown.bind(this)\n // test for elements with [x-convert-markdown] and set their .innerHTML\n $('[x-convert-markdown]').each(function () {\n // use innerText to prevent chars like > and & being escaped.\n this.innerHTML = toMarkdown(this.innerText)\n // prevent triggering this again (e.g., because of turbo)\n this.removeAttribute('x-convert-markdown')\n })\n }\n\n openTab(event, tabName) {\n const x = Array.from(document.getElementsByClassName(\"content-tab\"));\n x.map(el => el.style.display = \"none\");\n const tabLinks = Array.from(document.getElementsByClassName(\"tab\"));\n tabLinks.map(el => el.classList.remove(\"is-active\"));\n document.getElementById(tabName).style.display = \"block\";\n event.currentTarget.classList.add(\"is-active\");\n }\n\n // if we need this to be globally available we can do so like this:\n // window.toMarkdown = this.toMarkdown.bind(this);\n toMarkdown(text) {\n return this.converter.makeHtml(text);\n }\n\n previewMarkdown(event){\n const raw = document.getElementById('node_body').value;\n const data = {\n parent_id: document.getElementById('node_parent_id').value,\n body: raw\n }\n Rails.ajax({\n type: \"POST\",\n url: \"/markdown\",\n dataType: \"application/json\",\n data: new URLSearchParams(data).toString()\n })\n this.openTab(event, \"preview-content\")\n }\n}\n\n// singleton instance\nconst markdownHandler = new MarkdownHandler()\n\n$(window).on(\"load\", () => markdownHandler.doMarkdownOnLoadEvents())\n$(window).on(\"turbo:load\", () => markdownHandler.doMarkdownOnLoadEvents())\n","class addFields {\n // This executes when the function is instantiated.\n constructor() {\n this.iterateLinks()\n }\n\n iterateLinks() {\n $(\".add_fields\").on(\"click\", evt => this.handleClick(evt.currentTarget, evt))\n // document.addEventListener('click', e => {\n // console.debug(`addFields click listener triggered.`, e)\n // if (e.target && e.target.classList.contains('add_fields')) {\n // this.handleClick(e.target, e)\n // }\n // })\n }\n\n handleClick(link, e) {\n // Stop the function from executing if a link or event were not passed into the function.\n if (!link) return\n // Prevent the browser from following the URL.\n e.preventDefault()\n // Save a unique timestamp to ensure the key of the associated array is unique.\n let time = new Date().getTime()\n // Save the data id attribute into a variable. This corresponds to `new_object.object_id`.\n let linkId = link.dataset.id\n // Create a new regular expression needed to find any instance of the `new_object.object_id` used in the fields data attribute if there's a value in `linkId`.\n let regexp = linkId ? new RegExp(linkId, 'g') : null\n // Replace all instances of the `new_object.object_id` with `time`, and save markup into a variable if there's a value in `regexp`.\n let newFields = regexp ? link.dataset.fields.replace(regexp, time) : null\n // Add the new markup to the form if there are fields to add.\n newFields ? this.handleInsert(link, newFields) : null;\n // link.insertAdjacentHTML('beforebegin', newFields) : null\n }\n\n handleInsert(link, newFields) {\n console.assert(link.dataset.insertTarget, \"missing: link.dataset.insertTarget\", link.dataset)\n const insertTg = link.dataset.insertTarget\n // legal values for insertPosition: \"afterbegin\", \"afterend\", \"beforebegin\", \"beforeend\"\n // https://www.w3schools.com/jsref/met_node_insertadjacenthtml.asp\n const insertPosition = link.dataset.insertPosition\n if (insertTg) {\n console.debug(`[addFields.handleInsert] Inserting fields '${insertPosition}' for element '${insertTg}'`)\n $(insertTg)[0].insertAdjacentHTML(insertPosition || 'beforeend', newFields)\n } else {\n // default\n link.insertAdjacentHTML('beforebegin', newFields);\n }\n }\n}\n\n// window.addEventListener('load', () => new addFields())\nwindow.addEventListener('turbo:load', () => new addFields())\n// Wait for turbolinks to load, otherwise `document.querySelectorAll()` won't work\n// NB: couldn't get turbolinks event to work :/\n// -> `document.addEventListener('turbolinks:load', () => new addFields())`\n","class removeFields {\n // This executes when the function is instantiated.\n constructor() {\n this.iterateLinks()\n }\n\n iterateLinks() {\n // Use event delegation to ensure any fields added after the page loads are captured.\n document.addEventListener('click', e => {\n console.debug(`removeFields click listener triggered.`, e)\n if (e.target && e.target.classList.contains('remove_fields')) {\n this.handleClick(e.target, e)\n }\n })\n }\n\n handleClick(link, e) {\n // Stop the function from executing if a link or event were not passed into the function.\n if (!link || !e) return\n // Prevent the browser from following the URL.\n e.preventDefault()\n // Find the parent wrapper for the set of nested fields.\n let fieldParent = link.closest('.nested-fields')\n // If there is a parent wrapper, find the hidden delete field.\n let deleteField = fieldParent\n ? fieldParent.querySelector('input[type=\"hidden\"]')\n : null\n // If there is a delete field, update the value to `1` and hide the corresponding nested fields.\n if (deleteField) {\n deleteField.value = 1\n fieldParent.style.display = 'none'\n }\n }\n}\n\nwindow.addEventListener('load', () => new removeFields())\n// Wait for turbolinks to load, otherwise `document.querySelectorAll()` won't work\n// NB: couldn't get turbolinks event to work :/\n// -> `window.addEventListener('turbolinks:load', () => new removeFields())`\n","/*\n * # Tabs using data attrs\n *\n * ## Usage\n *\n * You should add data attrs to three types of elements:\n *\n * 1. things you click to change tab (buttons, the \"tabs\" themselves)\n * - currently .is-active is only set on the one you click, but you could have multiple redundant buttons.\n * 2. tab content\n * - you can have more than one thing for this, like many elements that appear when someone clicks the tab\n * 3. an element that is a parent of all tabs and tab-content\n *\n * The root element MUST be a parent to _all_ tab elements that you want to interact with.\n *\n * set `data-tab-group=some_name` on the root element.\n *\n * set `data-tab=this_tab_id` on the tab buttons (the tab id is how content is filtered for show/hide)\n *\n * set `data-tab-content` and `data-tab-id=this_tab_id` on tab content elements.\n *\n * The .is-active class is set on active tabs.\n *\n * that's it.\n *\n */\n\nconst tabEventHandlerSetup = () => {\n\n $(\"[data-tab]\").on(\"click\", (event) => {\n const el = event.currentTarget;\n const tabId = el.dataset.tab;\n const tabGroupEl = $(el).parents(\"[data-tab-group]\")[0];\n const tabGroup = tabGroupEl.dataset.tabGroup;\n const lastTab = $(`[data-tab-group=${tabGroup}] [data-tab-content]:not(.hidden)`)[0].dataset.tabId;\n const allTabs = $(`[data-tab-group=${tabGroup}] [data-tab-content]`);\n const newActiveTabEls = $(`[data-tab-group=${tabGroup}] [data-tab-content][data-tab-id=${tabId}]`);\n const allTabClickers = $(`[data-tab-group=${tabGroup}] [data-tab]`);\n const activeTabClickers = $(`[data-tab-group=${tabGroup}] [data-tab=${tabId}]`);\n\n allTabs.toArray().forEach(t => t.classList.add(\"hidden\"));\n newActiveTabEls.toArray().forEach(t => t.classList.remove(\"hidden\"));\n allTabClickers.toArray().forEach(tabBtn => tabBtn.classList.remove(\"is-active\"));\n activeTabClickers.toArray().forEach(tc => tc.classList.add(\"is-active\"));\n\n const ltSlug = lastTab.replaceAll('-', '_');\n let newPathname;\n const newFragment = tabId.replaceAll('-', '_');\n if (window.location.pathname.endsWith(`/${ltSlug}`)) {\n newPathname = window.location.pathname.replace(new RegExp(`${ltSlug}$`), newFragment);\n } else {\n newPathname = [window.location.pathname, newFragment].join('/')\n }\n history.pushState({}, '', newPathname)\n })\n}\n\nObject.values({}).filter(v => v == null).length == 0\n\n$(window).on(\"load\", tabEventHandlerSetup)\n$(window).on(\"turbo:load\", tabEventHandlerSetup)\n"],"names":["webpackEmptyContext","req","e","Error","code","keys","resolve","id","module","exports","channels","require","forEach","application","Application","debug","window","Stimulus","connect","this","element","textContent","Controller","register","HelloController","getElsForCfgKey","cfgKey","hidden_el","$","picker_el","hex_el","default_el","_forumConfigSyncColors","el","form_els","newVal","value","test","filter","_el","_resetColorFieldToDefault","Object","map","k","Rails","ActiveStorage","Alpine","addEventListener","mkElementWOpts","elName","options","document","createElement","type","name","ix","setAttribute","tagInputName","attr","addHiddenTagInputs","els","tag","_destroy","targetId","push","text","form","getElementById","appendChild","categoryTags","selectedCtds","cts","selectedId","selectedTags","newTag","init","i","addExistingTag","selectedCategoryEl","selectedIndex","tagObj","find","t","st","length","removeTag","parentElement","trim","addNewTag","on","target","parents","key","ctrlKey","trigger","markdownHandler","MarkdownHandler","converter","showdown","tables","tasklists","smoothLivePreview","splitAdjacentBlockquotes","simpleLineBreaks","extensions","showdownHighlight","pre","setFlavor","doMarkdownOnLoadEvents","event","openTab","previewMarkdown","toMarkdown","bind","each","innerHTML","innerText","removeAttribute","tabName","Array","from","getElementsByClassName","style","display","classList","remove","currentTarget","add","makeHtml","raw","data","parent_id","body","ajax","url","dataType","URLSearchParams","toString","addFields","iterateLinks","evt","handleClick","link","preventDefault","time","Date","getTime","linkId","dataset","regexp","RegExp","newFields","fields","replace","handleInsert","console","assert","insertTarget","insertTg","insertPosition","insertAdjacentHTML","removeFields","contains","fieldParent","closest","deleteField","querySelector","tabEventHandlerSetup","tabId","tab","tabGroup","lastTab","allTabs","newActiveTabEls","allTabClickers","activeTabClickers","toArray","tabBtn","tc","newPathname","ltSlug","replaceAll","newFragment","location","pathname","endsWith","join","history","pushState","values","v"],"sourceRoot":""}