{"version":3,"file":"main.xWw0s9.js","sources":["theme-180/virtual:theme","theme-180/discourse/components/modal/discourse-placeholder-builder.gjs","theme-180/discourse/initializers/setup.js","theme-180/virtual:entrypoint:main"],"sourcesContent":["import { getObjectForTheme } from \"discourse/lib/theme-settings-store\";\n\nexport const settings = getObjectForTheme(180);\n\nexport function themePrefix(key) {\n  return `theme_translations.180.${key}`;\n}\n","/* eslint-disable ember/no-classic-components, ember/require-tagless-components */\nimport Component, { Input } from \"@ember/component\";\nimport { fn, hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport EmberObject, { action } from \"@ember/object\";\nimport { service } from \"@ember/service\";\nimport { isBlank } from \"@ember/utils\";\nimport DButton from \"discourse/components/d-button\";\nimport DModal from \"discourse/components/d-modal\";\nimport MultiSelect from \"discourse/select-kit/components/multi-select\";\nimport { i18n } from \"discourse-i18n\";\n\nexport default class DiscoursePlaceholderBuilder extends Component {\n  @service dialog;\n\n  form = EmberObject.create({\n    key: null,\n    description: null,\n    values: [],\n  });\n\n  @action\n  updateKey(event) {\n    this.form.set(\"key\", event.target.value);\n  }\n\n  @action\n  updateDescription(event) {\n    this.form.set(\"description\", event.target.value);\n  }\n\n  @action\n  insertPlaceholder() {\n    if (isBlank(this.form.key)) {\n      this.dialog.alert(i18n(themePrefix(\"builder.errors.no_key\")));\n      return;\n    }\n\n    let output = `[wrap=placeholder key=\"${this.form.key}\"`;\n\n    if (this.form.description) {\n      output += ` description=\"${this.form.description}\"`;\n    }\n\n    if (this.form.values.length) {\n      if (this.form.values.length === 1) {\n        output += ` default=\"${this.form.values[0]}\"`;\n      } else {\n        output += ` defaults=\"${this.form.values.join(\",\")}\"`;\n      }\n    }\n\n    output += \"][/wrap]\";\n    this.model.toolbarEvent.addText(output);\n\n    this.closeModal();\n  }\n\n  <template>\n    <DModal\n      @title={{i18n (themePrefix \"builder.title\")}}\n      @closeModal={{@closeModal}}\n      @tagName=\"form\"\n      class=\"placeholder-builder\"\n    >\n      <:body>\n        <div class=\"control\">\n          <span class=\"label\">\n            {{i18n (themePrefix \"builder.key.label\")}}\n          </span>\n          <div class=\"input\">\n            <Input\n              {{on \"input\" this.updateKey}}\n              @value={{readonly this.form.key}}\n              class=\"placeholder-builder__key\"\n            />\n          </div>\n          <p class=\"description\">{{i18n\n              (themePrefix \"builder.key.description\")\n            }}</p>\n        </div>\n\n        <div class=\"control\">\n          <span class=\"label\">\n            {{i18n (themePrefix \"builder.description.label\")}}\n          </span>\n          <div class=\"input\">\n            <Input\n              {{on \"input\" this.updateDescription}}\n              @value={{readonly this.form.description}}\n              class=\"placeholder-builder__description\"\n            />\n          </div>\n          <p class=\"description\">\n            {{i18n (themePrefix \"builder.description.description\")}}\n          </p>\n        </div>\n\n        <div class=\"control\">\n          <span class=\"label\">\n            {{i18n (themePrefix \"builder.values.label\")}}\n          </span>\n          <div class=\"input\">\n            <MultiSelect\n              @valueProperty={{null}}\n              @nameProperty={{null}}\n              @value={{this.form.values}}\n              @content={{this.form.values}}\n              @options={{hash allowAny=true placementStrategy=\"absolute\"}}\n              @onChange={{fn (mut this.form.values)}}\n              class=\"placeholder-builder__default-values\"\n            />\n          </div>\n          <p class=\"description\">{{i18n\n              (themePrefix \"builder.values.description\")\n            }}</p>\n        </div>\n      </:body>\n\n      <:footer>\n        <DButton\n          @action={{this.insertPlaceholder}}\n          @label={{themePrefix \"builder.insert\"}}\n          class=\"btn-primary\"\n        />\n      </:footer>\n    </DModal>\n  </template>\n}\n","import { debounce, later } from \"@ember/runloop\";\nimport { withPluginApi } from \"discourse/lib/plugin-api\";\nimport DiscoursePlaceholderBuilder from \"../components/modal/discourse-placeholder-builder\";\n\nconst VALID_TAGS =\n  \"h1, h2, h3, h4, h5, h6, p, code, blockquote, .md-table, li, li > *\";\nconst DELIMITER = \"=\";\nconst EXPIRE_AFTER_DAYS = 7;\nconst EXPIRE_AFTER_SECONDS = EXPIRE_AFTER_DAYS * 24 * 60 * 60;\nconst STORAGE_PREFIX = \"d-placeholder-\";\n\nconst originalContentMap = new WeakMap();\n\nfunction buildInput(key, placeholder) {\n  const input = document.createElement(\"input\");\n  input.classList.add(\"discourse-placeholder-value\");\n  input.dataset.key = key;\n  input.dataset.delimiter = placeholder.delimiter;\n\n  if (placeholder.description) {\n    input.setAttribute(\"placeholder\", placeholder.description);\n  }\n\n  if (placeholder.value) {\n    input.value = placeholder.value;\n  }\n\n  return input;\n}\n\nfunction addSelectOption(select, options = {}) {\n  const option = document.createElement(\"option\");\n  option.classList.add(\"discourse-placeholder-option\");\n  option.value = options.value;\n  option.text = options.description || options.value;\n\n  if (options.selected) {\n    option.setAttribute(\"selected\", true);\n  }\n\n  select.appendChild(option);\n}\n\nfunction buildSelect(key, placeholder) {\n  const select = document.createElement(\"select\");\n  select.classList.add(\"discourse-placeholder-select\");\n  select.dataset.key = key;\n  select.dataset.delimiter = placeholder.delimiter;\n\n  if (placeholder.description) {\n    addSelectOption(select, {\n      value: \"none\",\n      description: placeholder.description,\n    });\n  }\n\n  placeholder.defaults.forEach((value) =>\n    addSelectOption(select, {\n      value,\n      selected: placeholder.value === value,\n    })\n  );\n\n  return select;\n}\n\nfunction replaceInText(text, placeholders) {\n  for (const [key, { delimiter, value }] of Object.entries(placeholders)) {\n    const placeholderWithDelimiter = `${delimiter}${key}${delimiter}`;\n\n    let substitution = value;\n    if (!substitution?.length || substitution === \"none\") {\n      substitution = placeholderWithDelimiter;\n    }\n\n    text = text.replaceAll(placeholderWithDelimiter, substitution);\n  }\n  return text;\n}\n\nfunction performReplacements(cooked, placeholders) {\n  cooked.querySelectorAll(VALID_TAGS).forEach((elem) => {\n    const textNodeWalker = document.createTreeWalker(\n      elem,\n      NodeFilter.SHOW_TEXT\n    );\n\n    // Handle text nodes\n    while (textNodeWalker.nextNode()) {\n      const node = textNodeWalker.currentNode;\n\n      if (!originalContentMap.has(node)) {\n        // Haven't seen this node before. Get the text, and store it for future transformations\n        originalContentMap.set(node, node.data);\n      }\n\n      const originalText = originalContentMap.get(node);\n      const text = replaceInText(originalText, placeholders);\n\n      if (node.data !== text) {\n        node.data = text;\n      }\n    }\n\n    // Handle a[href] attributes\n    cooked.querySelectorAll(\"a[href]\").forEach((link) => {\n      const hrefAttr = link.attributes.getNamedItem(\"href\");\n\n      if (!originalContentMap.has(hrefAttr)) {\n        // Haven't seen this attr before. Get the text, and store it for future transformations\n        originalContentMap.set(hrefAttr, hrefAttr.value);\n      }\n      const originalUrl = originalContentMap.get(hrefAttr);\n      const newUrl = replaceInText(originalUrl, placeholders);\n\n      if (hrefAttr.value !== newUrl) {\n        hrefAttr.value = newUrl;\n      }\n    });\n  });\n}\n\nexport default {\n  name: \"discourse-placeholder-theme-component\",\n\n  expireOldValues() {\n    const now = Date.now();\n    this.keyValueStore.removeKeys?.((k, v) => {\n      if (!k.includes(STORAGE_PREFIX)) {\n        return false;\n      }\n\n      return !v?.expires || v.expires < now;\n    });\n  },\n\n  getValue(key) {\n    const data = this.keyValueStore.getObject(`${STORAGE_PREFIX}${key}`);\n    if (data) {\n      data.expires = Date.now() + EXPIRE_AFTER_SECONDS;\n      this.keyValueStore.setObject(`${STORAGE_PREFIX}${key}`, data);\n      return data.value;\n    }\n  },\n\n  setValue(key, value) {\n    this.keyValueStore.setObject({\n      key: `${STORAGE_PREFIX}${key}`,\n      value: {\n        expires: Date.now() + EXPIRE_AFTER_SECONDS,\n        value,\n      },\n    });\n  },\n\n  removeValue(key) {\n    this.keyValueStore.remove(`${STORAGE_PREFIX}${key}`);\n  },\n\n  initialize(container) {\n    this.keyValueStore = container.lookup(\"service:key-value-store\");\n    this.expireOldValues();\n\n    withPluginApi((api) => {\n      api.decorateCookedElement(\n        (cooked, helper) => {\n          if (!helper) {\n            return;\n          }\n\n          const postIdentifier = `${helper.model.topic?.id}-${helper.model.id}-`;\n          const placeholders = {};\n\n          const processChange = (inputEvent) => {\n            const value = inputEvent.target.value;\n            const key = inputEvent.target.dataset.key;\n            const placeholder = placeholders[inputEvent.target.dataset.key];\n            const placeholderIdentifier = `${postIdentifier}${key}`;\n\n            if (value && value !== placeholder.default) {\n              placeholder.value = value;\n              this.setValue(placeholderIdentifier, value);\n            } else {\n              placeholder.value = placeholder.default;\n              this.removeValue(placeholderIdentifier);\n            }\n\n            performReplacements(cooked, placeholders);\n          };\n\n          const placeholderNodes = cooked.querySelectorAll(\n            \".d-wrap[data-wrap=placeholder]:not(.placeholdered)\"\n          );\n\n          placeholderNodes.forEach((elem) => {\n            const dataKey = elem.dataset.key;\n\n            if (!dataKey) {\n              return;\n            }\n\n            const placeholderIdentifier = `${postIdentifier}${dataKey}`;\n            const valueFromStore = this.getValue(placeholderIdentifier);\n            const defaultValues = (elem.dataset.defaults || \"\")\n              .split(\",\")\n              .filter(Boolean);\n\n            placeholders[dataKey] = {\n              default: elem.dataset.default,\n              defaults: defaultValues,\n              delimiter: elem.dataset.delimiter || DELIMITER,\n              description: elem.dataset.description,\n              value: valueFromStore || elem.dataset.default,\n            };\n\n            const span = document.createElement(\"span\");\n            span.classList.add(\"discourse-placeholder-name\", \"placeholdered\");\n            span.innerText = dataKey;\n\n            // content has been set inside the [wrap][/wrap] block\n            if (elem.querySelector(\"p\")) {\n              elem.querySelector(\"p\").prepend(span);\n            } else {\n              elem.prepend(span);\n            }\n\n            if (defaultValues && defaultValues.length) {\n              const select = buildSelect(dataKey, placeholders[dataKey]);\n              elem.appendChild(select);\n            } else {\n              const input = buildInput(dataKey, placeholders[dataKey]);\n              elem.appendChild(input);\n            }\n          });\n\n          cooked\n            .querySelectorAll(\".discourse-placeholder-value\")\n            .forEach((el) => {\n              el.addEventListener(\"input\", (inputEvent) =>\n                debounce(this, processChange, inputEvent, 150)\n              );\n            });\n\n          cooked\n            .querySelectorAll(\".discourse-placeholder-select\")\n            .forEach((el) => {\n              el.addEventListener(\"change\", (inputEvent) =>\n                debounce(this, processChange, inputEvent, 150)\n              );\n            });\n\n          later(performReplacements, cooked, placeholders, 500);\n        },\n        { onlyStream: true, id: \"discourse-placeholder-theme-component\" }\n      );\n\n      api.addComposerToolbarPopupMenuOption({\n        label: themePrefix(\"toolbar.builder\"),\n        icon: \"file\",\n        action: (toolbarEvent) => {\n          const modal = container.lookup(\"service:modal\");\n          modal.show(DiscoursePlaceholderBuilder, {\n            model: {\n              toolbarEvent,\n            },\n          });\n        },\n      });\n    });\n  },\n};\n","import * as Mod1 from \"./discourse/components/modal/discourse-placeholder-builder\";\nimport * as Mod2 from \"./discourse/initializers/setup\";\nconst compatModules = {\n  \"discourse/components/modal/discourse-placeholder-builder\": Mod1,\n  \"discourse/initializers/setup\": Mod2,\n};\nexport { compatModules };\nexport default compatModules;\n"],"names":["themePrefix","key","getObjectForTheme","DiscoursePlaceholderBuilder","Component","dt7948","g","this","prototype","service","dialog","i","form","EmberObject","create","description","values","updateKey","event","set","target","value","n","action","updateDescription","insertPlaceholder","isBlank","alert","i18n","output","length","join","model","toolbarEvent","addText","closeModal","setComponentTemplate","createTemplateFactory","id","block","moduleName","scope","DModal","Input","on","MultiSelect","hash","fn","DButton","isStrictMode","EXPIRE_AFTER_SECONDS","EXPIRE_AFTER_DAYS","STORAGE_PREFIX","originalContentMap","WeakMap","addSelectOption","select","options","option","document","createElement","classList","add","text","selected","setAttribute","appendChild","replaceInText","placeholders","delimiter","Object","entries","placeholderWithDelimiter","substitution","replaceAll","performReplacements","cooked","querySelectorAll","forEach","elem","textNodeWalker","createTreeWalker","NodeFilter","SHOW_TEXT","nextNode","node","currentNode","has","data","get","link","hrefAttr","attributes","getNamedItem","newUrl","setup","name","expireOldValues","now","Date","keyValueStore","removeKeys","k","v","includes","expires","getValue","getObject","setObject","setValue","removeValue","remove","initialize","container","lookup","withPluginApi","api","decorateCookedElement","helper","postIdentifier","topic","processChange","inputEvent","dataset","placeholder","placeholderIdentifier","default","dataKey","valueFromStore","defaultValues","defaults","split","filter","Boolean","span","innerText","querySelector","prepend","buildSelect","input","buildInput","el","addEventListener","debounce","later","onlyStream","addComposerToolbarPopupMenuOption","label","icon","show","compatModules","Mod1"],"mappings":"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"}