{"version":3,"file":"checklist.js","names":["define","_exports","_ajax","_ajaxError","_iconLibrary","_pluginApi","_discourseI18n","isWhitespaceNode","node","nodeType","nodeValue","match","addUlClasses","boxes","forEach","val","parent","parentElement","nodeName","firstElementChild","sibling","previousSibling","hasPrecedingContent","classList","add","nextSibling","insertAdjacentHTML","checklistSyntax","elem","postDecorator","getElementsByClassName","postWidget","widget","postModel","getModel","can_edit","idx","onclick","async","box","event","currentTarget","contains","newValue","template","document","createElement","innerHTML","iconHTML","class","insertAdjacentElement","content","firstChild","e","post","ajax","id","blocks","regex","exec","raw","push","index","length","nth","found","newRaw","replace","ignored","off","every","b","save","edit_reason","i18n","attrs","isSaving","scheduleRerender","popupAjaxError","remove","querySelector","Object","defineProperty","value","default","name","initialize","withPluginApi","api","container","lookup","checklist_enabled","decorateCookedElement","initializePlugin","setup","helper","registerOptions","opts","siteSettings","features","allowList","registerPlugin","md","core","ruler","processChecklist","REGEX","addCheckbox","result","state","classes","str","getClasses","checkOpenToken","Token","checkCloseToken","applyCheckboxes","pos","token","slice","i","j","l","tokens","blockTokens","nesting","type","children","processed","utils","arrayReplaceAt"],"sources":["discourse/plugins/checklist/discourse/initializers/checklist.js","discourse/plugins/checklist/lib/discourse-markdown/checklist.js"],"sourcesContent":["define(\"discourse/plugins/checklist/discourse/initializers/checklist\", [\"exports\", \"discourse/lib/ajax\", \"discourse/lib/ajax-error\", \"discourse/lib/icon-library\", \"discourse/lib/plugin-api\", \"discourse-i18n\"], function (_exports, _ajax, _ajaxError, _iconLibrary, _pluginApi, _discourseI18n) {\n \"use strict\";\n\n Object.defineProperty(_exports, \"__esModule\", {\n value: true\n });\n _exports.checklistSyntax = checklistSyntax;\n _exports.default = void 0;\n function initializePlugin(api) {\n const siteSettings = api.container.lookup(\"service:site-settings\");\n if (siteSettings.checklist_enabled) {\n api.decorateCookedElement(checklistSyntax);\n }\n }\n function isWhitespaceNode(node) {\n return node.nodeType === 3 && node.nodeValue.match(/^\\s*$/);\n }\n function hasPrecedingContent(node) {\n let sibling = node.previousSibling;\n while (sibling) {\n if (!isWhitespaceNode(sibling)) {\n return true;\n }\n sibling = sibling.previousSibling;\n }\n return false;\n }\n function addUlClasses(boxes) {\n boxes.forEach(val => {\n let parent = val.parentElement;\n if (parent.nodeName === \"P\" && parent.parentElement.firstElementChild === parent) {\n parent = parent.parentElement;\n }\n if (parent.nodeName === \"LI\" && parent.parentElement.nodeName === \"UL\" && !hasPrecedingContent(val)) {\n parent.classList.add(\"has-checkbox\");\n val.classList.add(\"list-item-checkbox\");\n if (!val.nextSibling) {\n val.insertAdjacentHTML(\"afterend\", \"​\"); // Ensure otherwise empty
  • does not collapse height\n }\n }\n });\n }\n function checklistSyntax(elem, postDecorator) {\n const boxes = [...elem.getElementsByClassName(\"chcklst-box\")];\n addUlClasses(boxes);\n if (!postDecorator) {\n return;\n }\n const postWidget = postDecorator.widget;\n const postModel = postDecorator.getModel();\n if (!postModel.can_edit) {\n return;\n }\n boxes.forEach((val, idx) => {\n val.onclick = async event => {\n const box = event.currentTarget;\n const classList = box.classList;\n if (classList.contains(\"permanent\") || classList.contains(\"readonly\")) {\n return;\n }\n const newValue = classList.contains(\"checked\") ? \"[ ]\" : \"[x]\";\n const template = document.createElement(\"template\");\n template.innerHTML = (0, _iconLibrary.iconHTML)(\"spinner\", {\n class: \"fa-spin list-item-checkbox\"\n });\n box.insertAdjacentElement(\"afterend\", template.content.firstChild);\n box.classList.add(\"hidden\");\n boxes.forEach(e => e.classList.add(\"readonly\"));\n try {\n const post = await (0, _ajax.ajax)(`/posts/${postModel.id}`);\n const blocks = [];\n\n // Computing offsets where checkbox are not evaluated (i.e. inside\n // code blocks).\n [\n // inline code\n /`[^`\\n]*\\n?[^`\\n]*`/gm,\n // multi-line code\n /^```[^]*?^```/gm,\n // bbcode\n /\\[code\\][^]*?\\[\\/code\\]/gm,\n // italic/bold\n /_(?=\\S).*?\\S_/gm,\n // strikethrough\n /~~(?=\\S).*?\\S~~/gm].forEach(regex => {\n let match;\n while ((match = regex.exec(post.raw)) != null) {\n blocks.push([match.index, match.index + match[0].length]);\n }\n });\n [\n // italic/bold\n /([^\\[\\n]|^)\\*\\S.+?\\S\\*(?=[^\\]\\n]|$)/gm].forEach(regex => {\n let match;\n while ((match = regex.exec(post.raw)) != null) {\n // Simulate lookbehind - skip the first character\n blocks.push([match.index + 1, match.index + match[0].length]);\n }\n });\n\n // make the first run go to index = 0\n let nth = -1;\n let found = false;\n const newRaw = post.raw.replace(/\\[( |x)?\\]/gi, (match, ignored, off) => {\n if (found) {\n return match;\n }\n\n // skip empty image URLs - \"![](https://example.com/image.jpg)\"\n if (off > 0 && post.raw[off - 1] === \"!\") {\n return match;\n }\n nth += blocks.every(b => b[0] >= off + match.length || off > b[1]);\n if (nth === idx) {\n found = true; // Do not replace any further matches\n return newValue;\n }\n return match;\n });\n await postModel.save({\n raw: newRaw,\n edit_reason: (0, _discourseI18n.i18n)(\"checklist.edit_reason\")\n });\n postWidget.attrs.isSaving = false;\n postWidget.scheduleRerender();\n } catch (e) {\n (0, _ajaxError.popupAjaxError)(e);\n } finally {\n boxes.forEach(e => e.classList.remove(\"readonly\"));\n box.classList.remove(\"hidden\");\n box.parentElement.querySelector(\".fa-spin\").remove();\n }\n };\n });\n }\n var _default = _exports.default = {\n name: \"checklist\",\n initialize() {\n (0, _pluginApi.withPluginApi)(\"0.1\", api => initializePlugin(api));\n }\n };\n});","define(\"discourse/plugins/checklist/lib/discourse-markdown/checklist\", [\"exports\"], function (_exports) {\n \"use strict\";\n\n Object.defineProperty(_exports, \"__esModule\", {\n value: true\n });\n _exports.setup = setup;\n const REGEX = /\\[( |x)?\\]/gi;\n function getClasses(str) {\n switch (str) {\n case \"x\":\n return \"checked fa fa-square-check-o fa-fw\";\n case \"X\":\n return \"checked permanent fa fa-square-check fa-fw\";\n default:\n return \"fa fa-square-o fa-fw\";\n }\n }\n function addCheckbox(result, content, match, state) {\n const classes = getClasses(match[1]);\n const checkOpenToken = new state.Token(\"check_open\", \"span\", 1);\n checkOpenToken.attrs = [[\"class\", `chcklst-box ${classes}`]];\n result.push(checkOpenToken);\n const checkCloseToken = new state.Token(\"check_close\", \"span\", -1);\n result.push(checkCloseToken);\n }\n function applyCheckboxes(content, state) {\n let match;\n let result = null;\n let pos = 0;\n while (match = REGEX.exec(content)) {\n if (match.index > pos) {\n result = result || [];\n const token = new state.Token(\"text\", \"\", 0);\n token.content = content.slice(pos, match.index);\n result.push(token);\n }\n pos = match.index + match[0].length;\n result = result || [];\n addCheckbox(result, content, match, state);\n }\n if (result && pos < content.length) {\n const token = new state.Token(\"text\", \"\", 0);\n token.content = content.slice(pos);\n result.push(token);\n }\n return result;\n }\n function processChecklist(state) {\n let i,\n j,\n l,\n tokens,\n token,\n blockTokens = state.tokens,\n nesting = 0;\n for (j = 0, l = blockTokens.length; j < l; j++) {\n if (blockTokens[j].type !== \"inline\") {\n continue;\n }\n tokens = blockTokens[j].children;\n\n // We scan from the end, to keep position when new tags are added.\n // Use reversed logic in links start/end match\n for (i = tokens.length - 1; i >= 0; i--) {\n token = tokens[i];\n nesting += token.nesting;\n if (token.type === \"text\" && nesting === 0) {\n const processed = applyCheckboxes(token.content, state);\n if (processed) {\n blockTokens[j].children = tokens = state.md.utils.arrayReplaceAt(tokens, i, processed);\n }\n }\n }\n }\n }\n function setup(helper) {\n helper.registerOptions((opts, siteSettings) => {\n opts.features[\"checklist\"] = !!siteSettings.checklist_enabled;\n });\n helper.allowList([\"span.chcklst-stroked\", \"span.chcklst-box fa fa-square-o fa-fw\", \"span.chcklst-box checked fa fa-square-check-o fa-fw\", \"span.chcklst-box checked permanent fa fa-square-check fa-fw\"]);\n helper.registerPlugin(md => md.core.ruler.push(\"checklist\", processChecklist));\n }\n});"],"mappings":"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"}