mkdocs-placeholder-plugin 0.5.2.dev3__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/PKG-INFO +5 -2
  2. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/README.md +4 -1
  3. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/pyproject.toml +1 -1
  4. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/assets/__init__.py +2 -6
  5. mkdocs_placeholder_plugin-0.6.0/src/mkdocs_placeholder_plugin/assets/placeholder.min.js +2 -0
  6. mkdocs_placeholder_plugin-0.6.0/src/mkdocs_placeholder_plugin/assets/placeholder.min.js.map +1 -0
  7. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/config/configuration.py +8 -1
  8. mkdocs_placeholder_plugin-0.6.0/src/mkdocs_placeholder_plugin/generic/config/cyclic_dependency_detector.py +86 -0
  9. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/config/placeholder.py +86 -6
  10. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/json_generator.py +7 -0
  11. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/validators/__init__.py +1 -1
  12. mkdocs_placeholder_plugin-0.6.0/src/mkdocs_placeholder_plugin/generic/validators/basic.py +34 -0
  13. mkdocs_placeholder_plugin-0.5.2.dev3/src/mkdocs_placeholder_plugin/assets/placeholder.min.js +0 -2
  14. mkdocs_placeholder_plugin-0.5.2.dev3/src/mkdocs_placeholder_plugin/assets/placeholder.min.js.map +0 -1
  15. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/LICENSE +0 -0
  16. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/__init__.py +0 -0
  17. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/assets/placeholder-data.js +0 -0
  18. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/__init__.py +0 -0
  19. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/config/__init__.py +0 -0
  20. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/config/parser_utils.py +0 -0
  21. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/config/validator.py +0 -0
  22. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/generic_style.py +0 -0
  23. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/html_tag_handler.py +0 -0
  24. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/html_tag_parser.py +0 -0
  25. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/page_processor.py +0 -0
  26. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/static/__init__.py +0 -0
  27. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/static/input_elements.py +0 -0
  28. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/static/placeholder_replacer.py +0 -0
  29. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/static/table_generator.py +0 -0
  30. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/static/table_replacer.py +0 -0
  31. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/validators/files.py +0 -0
  32. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/validators/internet.py +0 -0
  33. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/validators/ip_address.py +0 -0
  34. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/generic/validators/network.py +0 -0
  35. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/mkdocs/__init__.py +0 -0
  36. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/mkdocs/plugin.py +0 -0
  37. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/mkdocs/plugin_config.py +0 -0
  38. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/mkdocs/style.py +0 -0
  39. {mkdocs_placeholder_plugin-0.5.2.dev3 → mkdocs_placeholder_plugin-0.6.0}/src/mkdocs_placeholder_plugin/mkdocs/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mkdocs-placeholder-plugin
3
- Version: 0.5.2.dev3
3
+ Version: 0.6.0
4
4
  Summary: Add dynamic placeholders to your mkdocs page
5
5
  License: MIT
6
6
  Author: six-two
@@ -64,9 +64,12 @@ The corresponding documentation is hosted at <https://dev.mkdocs-placeholder-plu
64
64
 
65
65
  ## Notable changes
66
66
 
67
- ### HEAD / 0.5.2.dev1
67
+ ### Version 0.6.0
68
68
 
69
+ - Added computed placeholders that can calculate values using arbitrary JavaScript code. Thanks to @alexandrevilain for the PR (#13)
69
70
  - Added `html_prefix_optional` setting to enable silencing warnings when using placeholders in link URLs (see [#12](https://github.com/six-two/mkdocs-placeholder-plugin/issues/12)).
71
+ - New validators: `int`, `uint`, `float`, and `ufloat`
72
+ - Added dependency graph checking during build time to catch cyclic placeholder dependencies
70
73
 
71
74
  ### Version 0.5.1
72
75
 
@@ -46,9 +46,12 @@ The corresponding documentation is hosted at <https://dev.mkdocs-placeholder-plu
46
46
 
47
47
  ## Notable changes
48
48
 
49
- ### HEAD / 0.5.2.dev1
49
+ ### Version 0.6.0
50
50
 
51
+ - Added computed placeholders that can calculate values using arbitrary JavaScript code. Thanks to @alexandrevilain for the PR (#13)
51
52
  - Added `html_prefix_optional` setting to enable silencing warnings when using placeholders in link URLs (see [#12](https://github.com/six-two/mkdocs-placeholder-plugin/issues/12)).
53
+ - New validators: `int`, `uint`, `float`, and `ufloat`
54
+ - Added dependency graph checking during build time to catch cyclic placeholder dependencies
52
55
 
53
56
  ### Version 0.5.1
54
57
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mkdocs-placeholder-plugin"
3
- version = "0.5.2.dev3"
3
+ version = "0.6.0"
4
4
  description = "Add dynamic placeholders to your mkdocs page"
5
5
  authors = [
6
6
  {name = "six-two",email = "pip@six-two.dev"}
@@ -2,7 +2,6 @@ import os
2
2
  import shutil
3
3
  from typing import Optional
4
4
  # local
5
- from ..generic import LOGGER
6
5
  from ..generic.config import PlaceholderConfig
7
6
  from ..generic.json_generator import generate_json_for_javascript_code
8
7
 
@@ -61,11 +60,8 @@ def copy_assets_to_directory_debuggable(generic_config: PlaceholderConfig, outpu
61
60
 
62
61
  def read_resource_file(name: str) -> str:
63
62
  path = get_resource_path(name)
64
- try:
65
- with open(path, "r") as f:
66
- return f.read()
67
- except Exception as ex:
68
- LOGGER.error(f"Failed to read resource '{name}' (full path: {path}) because of error: {ex}")
63
+ with open(path, "r") as f:
64
+ return f.read()
69
65
 
70
66
 
71
67
 
@@ -0,0 +1,2 @@
1
+ (()=>{"use strict";const e=()=>`${(new Date).toISOString().slice(11,23)} (TS)`;let t=!0;function n(...t){console.log.apply(console,[`${e()} |`,...t])}function o(...t){console.info.apply(console,[`${e()} |`,...t])}function l(...t){console.debug.apply(console,[`${e()} |`,...t])}function a(...e){}const r=()=>{t?window.location.reload():o("Page reload was triggered and blocked due to PlaceholderPlugin.debug_disable_reload")},s={log:a,info:a,debug:a};let i=s;const c=()=>{o("Page reload was disabled for debugging purposes"),t=!1};var d,u;!function(e){e.Warning="WARNING",e.Error="ERROR"}(d||(d={})),function(e){e.Good="GOOD",e.Warning="WARNING",e.Error="ERROR",e.NoValidator="NO_VALIDATOR"}(u||(u={}));const p=e=>{const t=De("rules","object",e);if(0==t.length)throw new Error(`Rules should not be an empty array.\nProblematic object: ${JSON.stringify(e)}`);const n=Te("id",e);return{display_name:Te("display_name",e),id:n,rules:t.map((e=>w(e,n)))}},h=(e,t)=>{for(const n of e.rules)if(n.is_match_function(t)!=n.should_match&&n.severity==d.Error)return!1;return!0},f=(e,t)=>{if(e.validators.length>0){for(const n of e.validators)if(h(n,t))return!0;return!1}return!0},_=(e,t)=>{const n=[],o=[];for(const l of e.rules)l.is_match_function(t)!=l.should_match&&(l.severity==d.Error?o.push(`[${e.display_name}] Error: ${l.error_message}`):l.severity==d.Warning?n.push(`[${e.display_name}] Warning: ${l.error_message}`):console.warn(`Unknown rule severity ${l.severity}`));return{errors:o,warnings:n}},g=(e,t)=>{const n=[];let o=!1;if(e.validators.length>0){for(const l of e.validators){const a=_(l,t);if(n.push(a),0==a.errors.length&&(o=!0,0==a.warnings.length))return b(e)}return o?v(n):m(n)}return{rating:u.NoValidator,message:"No validators are specified for this placeholder"}},m=e=>{const t=[];for(const n of e)t.push(...n.errors);return{rating:u.Error,message:t.join("\n")}},v=e=>{const t=[];for(const n of e)0==n.errors.length&&t.push(...n.warnings);return{rating:u.Warning,message:t.join("\n")}},b=e=>{let t;if(1==e.validators.length)t=`Expecting: ${e.validators[0].display_name}`;else{t="Expecting one of the following: ";for(const n of e.validators)t+=`\n - ${n.display_name}`}return{rating:u.Good,message:t}},w=(e,t)=>{const n=Te("severity",e);let o,l;if("warning"==n||"warn"==n)o=d.Warning;else{if("error"!=n)throw new Error(`Unknown severity '${n}'`);o=d.Error}if(e.regex){const t=Te("regex",e),n=new RegExp(t);l=e=>n.test(e)}else{const n=Te("match_function",e),o=new Function("value",n);l=e=>{try{const l=o(e);if("boolean"!=typeof l)throw new Error(`Custom match_function '${n}' of validator ${t} should return a boolean, but it returned a ${typeof l}: ${l}`);return l}catch(e){throw new Error(`Failed to evaluate match_function '${n}' of validator ${t}: ${e}`)}}}return{severity:o,should_match:Ce("should_match",e),error_message:Te("error_message",e),is_match_function:l}},x=(e,t)=>{e.classList.remove("validation-error","validation-warn","validation-ok","validation-none"),t.rating==u.Good?e.classList.add("validation-ok"):t.rating==u.Warning?e.classList.add("validation-warn"):t.rating==u.Error?e.classList.add("validation-error"):t.rating==u.NoValidator?e.classList.add("validation-none"):console.warn(`Unknown placeholder validity: ${t.rating}`),e.title=t.message},y=(e,t)=>{const n=g(e,t.value);return x(t,n),i.debug("Validation: name =",e.name,", value =",t.value,", results =",n.rating),n.rating!=u.Error},$=(e,t)=>{const n=g(e,t.innerText);return x(t,n),i.debug("Validation: name =",e.name,", value =",t.innerText,", results =",n.rating),n.rating!=u.Error},k="PLACEHOLDER_",E="PLACEHOLDER-SETTING_",L=(e,t)=>{localStorage.setItem(k+e,t)},T=e=>localStorage.getItem(k+e),C=(e,t)=>{const n=localStorage.getItem(`${E}${e}`);return i.info(`Reading boolean setting '${e}' with value ${n}`),null===n?t:"1"===n||"0"!==n&&(console.warn(`Unexpected state for boolean setting. Should be null, '0' or '1', but was '${n}'`),t)},N=(e,t,n)=>{n.includes(t)||console.warn(`Default value '${t}' for multiple choice setting ${e} is not in the list of allowed values. Allowed are: ${n}`);const o=localStorage.getItem(`${E}${e}`);return i.info(`Reading multiple choice setting '${e}' with value ${o}`),null===o?t:n.includes(o)?o:(console.warn(`Unexpected state for multiple choice setting. Should be null or one of ${n}, but was '${o}'`),t)},D=(e,t)=>{e.current_is_checked=t,e.current_value=t?e.value_checked:e.value_unchecked,L(`${e.name}_IS_CHECKED`,t?"1":"0")},S=()=>{A(k)},R=()=>{A(E)},A=e=>{console.warn(`Clearing all localStorage items starting with '${e}'`);let t=0;for(;t<localStorage.length;){const n=localStorage.key(t);(null==n?void 0:n.startsWith(e))?localStorage.removeItem(n):t++}r()},P=(e,t)=>{try{const n=e.options[t];return null!=n&&null!=n}catch(e){return!1}},I=(e,t)=>{if(!P(e,t))throw new Error(`Index must a whole number N, where 0 <= N < ${e.options.length}. But it is ${t}`);L(`${e.name}_INDEX`,`${t}`),e.current_value=e.options[t].value,e.current_index=t},O=(e,t)=>{const n=f(e,t);if(i.info(`Set textbox ${e.name} to '${t}'. Validation ok? ${n}`),!n)throw new Error(`Validation error: Value '${t}' is not valid for placeholder ${e.name}`);L(`${e.name}_TEXT`,t)},H=(e,t,n)=>{t.classList.add("placeholder-value-dropdown"),t.querySelectorAll(".inline-editor-icon-span").forEach((e=>{e.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21,9L17,5V8H10V10H17V13M7,11L3,15L7,19V16H14V14H7V11Z" /></svg>'})),t.setAttribute("tabindex","0");const o={signal:e.event_listener_abort_controller.signal},l=n.description?`\nDescription: ${n.description}`:"";let a=`Placeholder name: ${n.name}${l}\nDefault option: ${n.options[n.default_index].value}\nUsage: (left-)click to cycle forward through the values, right-click to cycle through backwards. You can also use the Enter, Up, and Down keys if the placeholder is selected.\nPossible values:`;for(const e of n.options)a+=`\n- ${e.value}`;t.title=a;const r=t=>{let o=(n.current_index+t)%n.options.length;o<0&&(o+=n.options.length),I(n,o),n.current_index=o,n.current_value=n.options[o].value,oe(e,n)};t.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),r(1)}),o),t.addEventListener("contextmenu",(e=>{e.preventDefault(),e.stopPropagation(),r(-1)}),o),t.addEventListener("keydown",(e=>{"Enter"===e.key||"ArrowDown"===e.key?(r(1),e.preventDefault()):"ArrowUp"===e.key&&(r(-1),e.preventDefault())}),o)},M=(e,t,n)=>{t.tabIndex=0,t.spellcheck=!1,t.translate=!1,t.autocapitalize="off",t.classList.add("placeholder-value-editable"),t.querySelectorAll(".inline-editor-icon-span").forEach((e=>{e.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" /></svg>'}));const o={signal:e.event_listener_abort_controller.signal},l=()=>{n.current_value==t.innerText?i.debug(`Value for placeholder ${n.name} was not changed`):$(n,t)&&(O(n,t.innerText),n.current_value=t.innerText,oe(e,n),t.classList.remove("value-modified"))};$(n,t),t.title=n.default_tooltip,t.addEventListener("input",(()=>{$(n,t),t.innerText==n.current_value?t.classList.remove("value-modified"):t.classList.add("value-modified")}),o),t.addEventListener("keypress",(e=>{"Enter"===e.key&&(e.preventDefault(),i.debug("Textbox change confirmed with Enter key for",n.name,"- new value:",t.innerText),l(),U(t))}),o),t.addEventListener("keydown",(e=>{"Escape"===e.key&&(i.debug("Resetting input field for ",n.name," to current placeholder value"),xe(t,n.current_value),$(n,t),t.classList.remove("value-modified"),U(t))}),o),t.addEventListener("focusout",(()=>{var o;i.debug("Focus lost"),e.settings.apply_change_on_focus_change&&(i.debug("Textbox change confirmed by changing focus",n.name,"- new value:",t.innerText),l());const a=g(n,t.innerText);if(a.rating==u.Good||a.rating==u.NoValidator)for(const e of n.output_elements)e.classList.contains("placeholder-value-editable")&&(e.title=n.default_tooltip);t.contentEditable="false",null===(o=window.getSelection())||void 0===o||o.removeAllRanges()}),o),t.addEventListener("focusin",(()=>{i.debug("Focus gained");try{t.contentEditable="plaintext-only"}catch(e){t.contentEditable="true"}$(n,t),setTimeout((()=>U(t)),5)}),o)};let V=!1;const U=e=>{if(window.getSelection&&document.createRange){const t=window.getSelection();if(t){t.removeAllRanges();const n=document.createRange();n.selectNodeContents(e.firstChild||e),t.addRange(n)}else V||(V=!0,console.warn("getSelection returned null"))}else V||(V=!0,console.warn("Can not set selection, because window.getSelection or document.createRange are not supported"))},j=e=>{W(e.settings.inline_editor_style);const t=document.querySelectorAll("span.placeholder-value.inline-editor-requested[data-placeholder]");for(const n of t){const t=n.getAttribute("data-placeholder");if(t){const o=e.placeholders.get(t);if(o){if(!o.read_only){n.classList.add("placeholder-value-any");const t=document.createElement("span");t.classList.add("inline-editor-icon-span"),t.contentEditable="false",n.appendChild(t),o.type==Re.Textbox?M(e,n,o):o.type==Re.Checkbox?ae(e,n,o):o.type==Re.Dropdown&&H(e,n,o)}}else console.warn(`Unknown placeholder referenced in input element: '${t}'`,n)}}},W=e=>{if(Ee.includes(e)){for(const e of Ee)document.body.classList.remove(`inline-editor-${e}`);document.body.classList.add(`inline-editor-${e}`)}else console.error(`Tried to set inline editor style '${e}', but only ${Ee} are allowed`)},q=new Map;q.set("name","Name"),q.set("description","Description"),q.set("value","Value"),q.set("input","Input element"),q.set("description-or-name","Description / name");const F=(e,t)=>{e.appendChild(document.createTextNode(t))},z=(e,t)=>{const n=document.createElement(t);return e.appendChild(n),n},B=(e,t,n)=>{const o=t=>{for(const n of e.placeholders.values())for(const e of n.output_elements)t?e.classList.add("placeholder-value-highlighted"):e.classList.remove("placeholder-value-highlighted")};o(e.settings.highlight_placeholders),n&&(z(t,"b").textContent="Settings");const l=e=>{};J(t,e.settings.expand_auto_tables,"expand_auto_tables","Expand placeholder tables by default*",l),J(t,e.settings.apply_change_on_focus_change,"apply_change_on_focus_change","Apply value when focus changes away*",l),J(t,e.settings.debug,"debug","Log JavaScript debug messages to console*",l),J(t,e.settings.highlight_placeholders,"highlight_placeholders","Highlight placeholders (useful for debugging)",o),J(t,e.settings.inline_editors,"inline_editors","Allow editing placeholders directly in the page",(t=>{t?j(e):(e=>{const t=document.querySelectorAll("span.placeholder-value-editable, span.placeholder-value-checkbox, span.placeholder-value-dropdown");e.event_listener_abort_controller.abort(),e.event_listener_abort_controller=new AbortController;for(const e of t){const t=e;t.classList.remove("placeholder-value-editable","placeholder-value-checkbox","placeholder-value-dropdown","placeholder-value-any","validation-error","validation-warn","validation-ok","validation-none"),t.contentEditable="false",t.title="",t.removeAttribute("tabindex"),t.querySelectorAll(".inline-editor-icon-span").forEach((e=>e.remove()))}})(e)})),X(t,e.settings.inline_editor_style,Ee,"inline_editor_style","Style to apply to inline placeholder editors",W),z(t,"i").textContent="* You need to reload the page for these settings to take effect.";const a=z(t,"div");a.classList.add("button-bar");const r=z(a,"button");r.textContent="Reset settings",r.addEventListener("click",R);const s=z(a,"button");s.textContent="Reset all placeholders",s.addEventListener("click",S)},J=(e,t,n,o,l)=>{const a=z(e,"label");a.textContent=`${o} `;const r=z(a,"input");r.type="checkbox",r.checked=t,r.addEventListener("change",(()=>{((e,t)=>{i.info(`Storing boolean setting '${e}' with value ${t}`),localStorage.setItem(`${E}${e}`,t?"1":"0")})(n,r.checked),l(r.checked)}))},X=(e,t,n,o,l,a)=>{const r=z(e,"label");r.textContent=`${l} `;const s=z(r,"select");for(const e of n){const t=document.createElement("option");t.text=e,t.value=e,s.appendChild(t)}s.value=t,s.addEventListener("change",(()=>{((e,t,n)=>{n.includes(t)?localStorage.setItem(`${E}${e}`,t):console.error(`Tried to store value '${t}' for setting '${e}', but only ${n} are allowed`)})(o,s.value,n),a(s.value)}))},G=(e,t,n,o,l)=>{o=Y(o);const a=document.createElement("div");if(0==o.length){if(!l)return void e.remove();a.textContent="No placeholders to be shown"}else{i.info("Creating automatic input table at",e,"with columns",t),a.classList.add("table-div"),z(a,"b").innerHTML="Enter different values in the table below and press <code>Enter</code> to update this page.";const l=z(a,"table"),r=z(l,"thead"),s=z(r,"tr"),c=z(l,"tbody");for(const e of t){const t=z(s,"th"),n=q.get(e);n?F(t,n):(F(t,e),console.error(`Unknown column name: ${e}`))}const d=[];for(const e of o){if(e.read_only){i.debug(`auto_table: Skipping ${e.name} because it is read-only`);continue}const o=z(c,"tr");Z(o,e,t,n),d.push({element:o,placeholder:e})}n.input_tables.push({columns:t,table_element:l,rows:d})}((e,t,n)=>{t.innerHTML="";const o=z(t,"div"),l=z(o,"div"),a=z(o,"div"),r=z(t,"div"),s=z(r,"div");r.append(n);const i=e=>{r.style.display=e?"flex":"none",l.textContent="Placeholders: Click here to "+(e?"collapse":"expand")};o.classList.add("auto-table-title"),r.classList.add("expandable_contents"),s.classList.add("settings_contents");let c=e.settings.expand_auto_tables;i(c),l.addEventListener("click",(()=>{c=!c,i(c)})),l.classList.add("text"),((e,t,n)=>{let o=!1;e.onclick=e=>{e.preventDefault(),e.stopPropagation(),o=!o,t.style.display=o?"flex":"none",o&&n()},t.style.display=o?"flex":"none",e.classList.add("settings_button"),e.innerHTML='<svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">\n <path id="svg_6" d="m7.79338,20.02127l0,0c0,-6.84327 5.74307,-12.39083 12.82751,-12.39083l0,0c3.40207,0 6.6648,1.30546 9.07042,3.62919c2.40563,2.32373 3.75709,5.47539 3.75709,8.76164l0,0c0,6.84327 -5.74307,12.39083 -12.82751,12.39083l0,0c-7.08444,0 -12.82751,-5.54757 -12.82751,-12.39083zm6.41376,0l0,0c0,3.42163 2.87154,6.19542 6.41376,6.19542c3.54222,0 6.41376,-2.77378 6.41376,-6.19542c0,-3.42163 -2.87154,-6.19542 -6.41376,-6.19542l0,0c-3.54222,0 -6.41376,2.77378 -6.41376,6.19542z" stroke="#fff" fill="#ffffff"/>\n <path id="svg_7" d="m17.46095,7.63098l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(180, 20.9544, 35.1419)" id="svg_11" d="m17.57012,37.76199l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(43, 31.5439, 9.59605)" id="svg_12" d="m28.15964,12.21614l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(90, 35.9107, 19.8581)" id="svg_13" d="m32.52645,22.47815l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(135, 31.7623, 30.2292)" id="svg_14" d="m28.37798,32.84933l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(-45, 9.49152, 9.48688)" id="svg_15" d="m6.10724,12.10697l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(-90, 5.01553, 19.9672)" id="svg_16" d="m1.63126,22.58732l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n <path transform="rotate(-135, 9.60069, 30.7751)" id="svg_17" d="m6.21641,33.39518l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z" stroke="#fff" fill="#ffffff"/>\n</svg>',e.title="Hide / show settings"})(a,s,(()=>{c||(c=!0,i(c))})),B(e,s,!0)})(n,e,a)},Y=e=>[...new Set(e)].sort(((e,t)=>e.order_index-t.order_index)),Z=(e,t,n,o)=>{for(const l of n){const n=z(e,"td");if("name"==l)F(n,t.name);else if("description"==l)F(n,t.description);else if("value"==l){const e=ce(t);n.appendChild(e),t.output_elements.push(e)}else if("input"==l){const e=z(n,"input");Q(o,t,e)}else if("description-or-name"==l){const e=t.description||t.name;F(n,e)}else console.error(`Unknown column name: ${l}`)}},K=(e,t,n)=>{n=Y(n);const o=[];for(const e of t.rows)n.includes(e.placeholder)?o.push(e):(i.debug(`Removed table row for ${e.placeholder.name}:`,e.element),e.element.remove());const l=[],a=[...o].reverse(),r=[...n].reverse();let s;for(;s=r.pop();){const n=a.slice(-1)[0];if(n&&n.placeholder===s)a.pop(),l.push(n);else{const n=document.createElement("tr");0==l.length?t.table_element.insertBefore(n,t.table_element.firstChild):l[l.length-1].element.insertAdjacentElement("afterend",n),Z(n,s,t.columns,e),l.push({element:n,placeholder:s}),i.debug(`Added table row for ${s.name}:`,n)}}t.rows=l},Q=(e,t,n)=>{n.classList.add("input-for-variable"),t.type==Re.Checkbox?ee(e,t,n):t.type==Re.Dropdown?te(e,t,n):t.type==Re.Textbox?ne(e,t,n):console.error(`Placeholder ${t.name} has unknown type '${t.type}'`)},ee=(e,t,n)=>{"INPUT"==n.tagName?(n.type="checkbox",n.checked=t.current_is_checked,t.read_only?n.disabled=!0:(n.disabled=!1,n.addEventListener("change",(()=>{i.debug("Checkbox change",t.name,"- new value:",n.checked),D(t,n.checked),t.current_value=n.checked?t.value_checked:t.value_unchecked,oe(e,t)}))),t.input_elements.push(n)):console.warn(`Input element/tag for placeholder '${t.name}' is expected to be INPUT, but is ${n.tagName}. Skipping`,n)},te=(e,t,n)=>{const o=document.createElement("select");o.classList.add("placeholder-dropdown");for(const e of t.options){const t=document.createElement("option");t.text=e.display_name,o.appendChild(t)}n.parentNode?n.parentNode.replaceChild(o,n):console.error("Input element",n,`for placeholder ${t.name} has no parent!`),o.selectedIndex=t.current_index,t.read_only?o.disabled=!0:(o.disabled=!1,o.addEventListener("change",(()=>{i.debug("Dropdown change",t.name,"- new index:",o.selectedIndex),I(t,o.selectedIndex),t.current_index=o.selectedIndex,t.current_value=t.options[o.selectedIndex].value,oe(e,t)}))),t.input_elements.push(o)},ne=(e,t,n)=>{if("INPUT"==n.tagName){if(n.value=t.current_value,t.read_only)n.disabled=!0,n.style.cursor="not-allowed";else{n.disabled=!1,null!=t.default_value?n.placeholder=`Default: ${t.default_value}`:n.placeholder="Dynamic default value";const o=()=>{t.current_value==n.value?i.debug(`Value for placeholder ${t.name} was not changed`):y(t,n)&&(O(t,n.value),t.current_value=n.value,oe(e,t),n.classList.remove("value-modified"))};y(t,n),n.addEventListener("input",(()=>{y(t,n),n.value==t.current_value?n.classList.remove("value-modified"):n.classList.add("value-modified")})),n.addEventListener("keypress",(e=>{"Enter"===e.key&&(i.debug("Textbox change confirmed with Enter key for",t.name,"- new value:",n.value),o())})),n.addEventListener("keydown",(e=>{"Escape"===e.key&&(i.debug("Resetting input field for ",t.name," to current placeholder value"),n.value=t.current_value,y(t,n),n.classList.remove("value-modified"))})),n.addEventListener("focusout",(()=>{e.settings.apply_change_on_focus_change&&(i.debug("Textbox change confirmed by changing focus",t.name,"- new value:",n.value),o())}))}t.input_elements.push(n)}else console.warn(`Input element/tag for placeholder '${t.name}' is expected to be INPUT, but is ${n.tagName}. Skipping`,n)},oe=(e,t)=>{const n=e.dependency_graph.get_all_upstream(t);let o=!1;for(const e of n)o=o||e.reload_page_on_change;if(i.debug(`Change of ${t.name} requires updates for placeholders:\n${n.map((e=>` - ${e.name}\n`)).join("")}\nRequires reload: ${o}`),o)r();else{if(e.dependency_graph.on_placeholder_value_change(t),(e=>{if(i.debug(`Updating ${e.input_tables.length} automatic input tables`),e.input_tables.length>0){const t=e.dependency_graph.get_all_used_placeholders();for(const n of e.input_tables)K(e,n,t)}})(e),t.type==Re.Checkbox){const e=t;for(const t of e.input_elements)t.checked=e.current_is_checked}else if(t.type==Re.Dropdown){const e=t;for(const t of e.input_elements)t.selectedIndex=e.current_index}else if(t.type==Re.Textbox){const e=t;for(const t of e.input_elements)t.value=e.current_value,y(e,t)}else t.type==Re.Computed||console.warn(`Placeholder ${t.name} has unexpected type '${t.type}'`);we(n)}},le=(e,t)=>{t.current_is_checked?(e.classList.add("checked"),e.classList.remove("unchecked")):(e.classList.add("unchecked"),e.classList.remove("checked"))},ae=(e,t,n)=>{t.classList.add("placeholder-value-checkbox"),t.querySelectorAll(".inline-editor-icon-span").forEach((e=>{e.innerHTML='<svg class="checkbox-checked" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M19,5V19H5V5H19M10,17L6,13L7.41,11.58L10,14.17L16.59,7.58L18,9" /></svg><svg class="checkbox-unchecked" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z" /></svg>'})),t.setAttribute("tabindex","0");const o={signal:e.event_listener_abort_controller.signal},l=n.description?`\nDescription: ${n.description}`:"";t.title=`Placeholder name: ${n.name}${l}\nUsage: Click to toggle the value. You can also press Enter if the placeholder is focused.`;const a=()=>{const t=!n.current_is_checked;n.current_value=t?n.value_checked:n.value_unchecked,i.debug("Checkbox change",n.name,"- new value:",t),D(n,t),oe(e,n)};t.addEventListener("click",a,o),t.addEventListener("keydown",(e=>{"Enter"===e.key&&(a(),e.preventDefault())}),o),le(t,n)},re=(e,t,n)=>{const o=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);let l,a=0;for(t.global||console.warn(`You should set the global flag for the regex. Context: replacing '${t.source}' with '${n}'`);l=o.nextNode();)if(l.nodeValue){const e=l.nodeValue.replace(t,n);l.nodeValue!=e&&(l.nodeValue=e,a++)}return a},se=e=>{const t=document.createElement("div");return t.appendChild(document.createTextNode(e)),t.innerHTML},ie=(e,t,n)=>{t.global||console.warn(`You should set the global flag for the regex. Context: replacing '${t.source}' with '${n}'`);const o=e.innerHTML.replace(t,n);if(o!=e.innerHTML){for(const o of e.childNodes)o.nodeType==Node.ELEMENT_NODE?ie(o,t,n):o.nodeValue&&(o.nodeValue=o.nodeValue.replace(t,n));return e.innerHTML.replace(t,n)!=e.innerHTML&&(e.innerHTML=o),1}return 0},ce=e=>{const t=document.createElement("span");return t.classList.add("placeholder-value"),t.dataset.placeholder=e.name,t.textContent=e.expanded_value,t},de=(e,t,n,o)=>pe(e,t,n,o,"placeholder-value-static"),ue=(e,t,n,o)=>pe(e,t,n,o,"inline-editor-requested"),pe=(e,t,n,o,l)=>{var a;const r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);let s;t.global||console.warn(`You should set the global flag for the regex. Context: replacing '${t.source}' with '${n.current_value}'`);let c=0;if(o){const e=l?`.${l}`:"",t=document.querySelectorAll(`${e}.placeholder-value[data-placeholder]`);for(const e of t)e.getAttribute("data-placeholder")===n.name&&c++;if(c>0){const e=l?"editable":"dynamic";i.debug(`${c} ${e} placeholder elements already exist for placeholder ${n.name}`)}}const d=[];for(;s=r.nextNode();)s.nodeValue&&s.nodeValue.match(t)&&d.push(s);if(d){const e=`<span class="placeholder-value${l?` ${l}`:""}" data-placeholder="${se(n.name)}">TEMPORARY PLACEHOLDER</span>`;for(const n of d)if(n.nodeValue){const o=se(n.nodeValue).replace(t,e),l=document.createElement("span");l.innerHTML=o,null===(a=n.parentElement)||void 0===a||a.replaceChild(l,n)}}return d.length+c},he=(e,t)=>{const n=de(e,t.regex_dynamic,t,!0);n>0&&(i.debug(`Replaced ${t.name} via dynamic method at least ${n} time(s)`),t.count_on_page+=n)},fe=(e,t)=>{const n=ue(e,t.regex_editable,t,!0);n>0&&(i.debug(`Replaced ${t.name} via editable method at least ${n} time(s)`),t.count_on_page+=n)},_e=(e,t,n)=>{const o=ge(e,t,n);o>0&&(i.debug(`Replaced ${t.name} via normal (${n.settings.normal_is_alias_for}) method at least ${o} time(s)`),t.count_on_page+=o)},ge=(e,t,n)=>{switch(n.settings.normal_is_alias_for){case"dynamic":return de(e,t.regex_normal,t,!1);case"editable":return ue(e,t.regex_normal,t,!1);case"html":const o=se(t.expanded_value);return ie(e,t.regex_html,o);case"static":return re(e,t.regex_static,t.expanded_value);default:return console.warn(`Unknown replace type mapped in 'settings.normal_is_alias_for': ${n.settings.normal_is_alias_for}. Skipping replacing normal placeholders`),0}},me=(e,t)=>{const n=re(e,t.regex_static,t.expanded_value);n>0&&(i.debug(`Replaced ${t.name} via static method at least ${n} time(s)`),t.count_on_page+=n,t.reload_page_on_change=!0)},ve=(e,t)=>{const n=ie(e,t.regex_html,t.expanded_value);n>0&&(i.debug(`Replaced ${t.name} via innerHTML method at least ${n} time(s)`),t.count_on_page+=n,t.reload_page_on_change=!0)},be=(e,t,n)=>e.replace(t.regex_dynamic,n).replace(t.regex_editable,n).replace(t.regex_html,n).replace(t.regex_normal,n).replace(t.regex_static,n),we=e=>{for(const t of e)if(t.output_elements.length>0){for(const e of t.output_elements)xe(e,t.expanded_value);if(t.type==Re.Textbox){const e=g(t,t.expanded_value);for(const n of t.output_elements)n.classList.contains("placeholder-value-editable")&&x(n,e)}else if(t.type==Re.Checkbox)for(const e of t.output_elements)e.classList.contains("placeholder-value-checkbox")&&le(e,t)}},xe=(e,t)=>{t?e.classList.remove("value-empty"):e.classList.add("value-empty");for(const n of e.childNodes)if(n.nodeType===Node.TEXT_NODE)return void(n.textContent=t);e.insertAdjacentText("afterbegin",t)};class ye{constructor(e){this.placeholders=e,this.nodes=new Map,this.reset()}reset(){this.nodes.clear();for(const e of this.placeholders.values())this.nodes.set(e.name,new ke(e));for(const e of this.placeholders.values())try{this.on_placeholder_value_change(e)}catch(e){console.error("Error while building dependency graph",e),console.warn("Placeholder values may be inconsistent. Clearing your localStorage should fix this problem."),confirm("We detected a problem with your placeholder values. Resetting them to the defaults should fix this. Should we reset your placeholders?")&&S()}for(const e of this.nodes.values())0==e.downlinks.length&&e.recalculate_expanded_value(!0)}debug_print_representation(){let e="Dependency graph nodes (DEBUG view):";for(const t of this.nodes.values()){const n=t.downlinks.map((e=>e.placeholder.name)).join(", ");0==n.length?e+=`\n${t.placeholder.name} (${t.placeholder.expanded_value}) has no dependencies`:e+=`\n${t.placeholder.name} (${t.placeholder.expanded_value}) depends on ${n}`}i.debug(e)}unmark_everything(){for(const e of this.nodes.values())e.marked=!1}get_node(e){const t=this.nodes.get(e.name);if(null==t)throw new Error(`Placeholder ${e.name} is not part of the dependency graph`);return t}on_placeholder_value_change(e){const t=this.get_node(e);if(this.update_placeholder_downlinks(e),this.has_loop())throw e.expanded_value=e.current_value,t.downlinks=[],new Error(`Placeholder ${e.name} was part of a loop and has temporarily been made non-recursive`);t.recalculate_expanded_value(!0)}get_all_marked(){const e=[];for(const t of this.nodes.values())t.marked&&e.push(t.placeholder);return e}get_all_upstream(e){return this.unmark_everything(),this.get_node(e).recursive_mark_upstream(),this.get_all_marked()}update_placeholder_downlinks(e){const t=this.get_node(e);for(const e of t.downlinks)e.remove_uplink(t);if(t.downlinks=[],e.type===Re.Computed){const n=e;for(const e of n.computed_depends_on){const o=this.nodes.get(e);o?(t.downlinks.push(o),o.uplinks.push(t)):console.error(`Computed placeholder '${n.name}': dependency '${e}' not found in graph`)}}else if(e.allow_nested)for(const n of this.nodes.values())n!=t&&$e(e.current_value,n.placeholder)&&(t.downlinks.push(n),n.uplinks.push(t));else i.debug(`${e.name} has no dependencies (not nested, not computed)`)}get_all_used_placeholders(){this.unmark_everything();for(const e of this.nodes.values())e.placeholder.count_on_page>0&&e.recursive_mark_downstream();return this.get_all_marked()}has_loop(){this.unmark_everything();for(const e of this.nodes.values())if(!e.marked&&this._has_loop([],e))return!0;return!1}_has_loop(e,t){const n=[...e,t],o=e.indexOf(t);if(-1!=o){let e="Dependency cycle in placeholders detected:";for(let t=o;t<n.length;t++){const o=n[t].placeholder;e+=`\n$ -> ${o.name}: ${o.current_value}`}return console.warn(e),!0}if(t.marked)return!1;t.marked=!0;for(const e of t.downlinks)if(this._has_loop(n,e))return!0;return!1}}const $e=(e,t)=>t.regex_dynamic.test(e)||t.regex_editable.test(e)||t.regex_html.test(e)||t.regex_normal.test(e)||t.regex_static.test(e);class ke{constructor(e){this.uplinks=[],this.downlinks=[],this.marked=!1,this.placeholder=e}remove_uplink(e){this.uplinks=this.uplinks.filter((t=>t!=e))}recalculate_expanded_value(e){if(this.placeholder.type===Re.Computed){const e=this.placeholder,t={};for(const e of this.downlinks)t[e.placeholder.name]=e.placeholder.current_value;try{const n=e.computed_function(t);e.current_value=n,e.expanded_value=n,i.debug(`Computed placeholder '${e.name}' evaluated to: '${n}'`)}catch(t){console.error(`Error evaluating computed placeholder '${e.name}':`,t),e.current_value="COMPUTED_ERROR",e.expanded_value="COMPUTED_ERROR"}}else{let e=this.placeholder.current_value;this.placeholder.allow_nested&&(e=((e,t)=>{if(0==t.length)return e;if(1==t.length){const n=t[0];return be(e,n,n.expanded_value)}{const n=`${Date.now()}_${Math.random()}`;for(const o of t)e=be(e,o,`x${o.name}#${n}x`);for(const o of t){const t=new RegExp(`x${o.name}#${n}x`,"g");e=e.replace(t,o.expanded_value)}return e}})(e,this.downlinks.map((e=>e.placeholder)))),this.placeholder.expanded_value=e}if(e)for(const t of this.uplinks)t.recalculate_expanded_value(e)}recursive_mark_upstream(){this.marked=!0;for(const e of this.uplinks)e.recursive_mark_upstream()}recursive_mark_downstream(){this.marked=!0;for(const e of this.downlinks)e.recursive_mark_downstream()}}const Ee=["simple","icons","custom"],Le=(e,t,n)=>{const o=n[e],l=typeof o;if(l!=t)throw new Error(`Type mismatch: ${e} should be ${t}, but is ${l}.\nProblematic object: ${JSON.stringify(n)}`);return o},Te=(e,t)=>Le(e,"string",t),Ce=(e,t)=>Le(e,"boolean",t),Ne=(e,t)=>Le(e,"number",t),De=(e,t,n)=>{const o=n[e];if(Array.isArray(o)){for(const[l,a]of o.entries()){const o=typeof a;if(o!=t){const a=`Type mismatch: ${e}'s ${l+1}th element should be ${t}, but is ${o}.\nProblematic object: ${JSON.stringify(n)}`;throw new Error(a)}}return o}throw new Error(`Type mismatch: ${e} should be an array, but is not.\nProblematic object: ${JSON.stringify(n)}`)};var Se,Re;!function(e){e.Editable="editable"}(Se||(Se={})),function(e){e.Textbox="TEXTBOX",e.Checkbox="CHECKBOX",e.Dropdown="DROPDOWN",e.Computed="COMPUTED"}(Re||(Re={}));const Ae=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Pe=(e,t,n,o)=>{const l=Te("type",e),a=Te("name",e),r={name:a,order_index:o,regex_dynamic:RegExp(Ae(n.dynamic_prefix)+a+Ae(n.dynamic_suffix),"g"),regex_editable:RegExp(Ae(n.editable_prefix)+a+Ae(n.editable_suffix),"g"),regex_html:RegExp("(:?"+Ae(n.html_prefix_optional)+")?"+Ae(n.html_prefix)+a+Ae(n.html_suffix),"g"),regex_normal:RegExp(Ae(n.normal_prefix)+a+Ae(n.normal_suffix),"g"),regex_static:RegExp(Ae(n.static_prefix)+a+Ae(n.static_suffix),"g"),default_tooltip:"",description:Te("description",e),read_only:Ce("read_only",e),allow_inner_html:Ce("allow_inner_html",e),allow_nested:Ce("allow_nested",e),current_value:"UNINITIALIZED",expanded_value:"UNINITIALIZED",count_on_page:0,reload_page_on_change:!1,output_elements:[]};if("textbox"===l){const n=Ie(r,e,t);return(e=>{const t=T(`${e.name}_TEXT`);if(null!=t){if(f(e,t))return void(e.current_value=t);console.warn(`Stored value for placeholder ${e.name} is invalid: '${t}'. Will revert to default.`)}if(null!=e.default_value)e.current_value=e.default_value,f(e,e.default_value)||console.warn(`Default value for placeholder '${e.name}' is invalid: '${e.default_value}'`);else{if(!e.default_function)throw new Error(`Either 'default_value' or 'default_function' needs to be set for placeholder ${e.name}`);try{const t=e.default_function();e.current_value=t;try{O(e,t)}catch(n){console.warn(`Default function for placeholder '${e.name}' returned invalid value: '${t}'`)}}catch(t){console.error(`Error while loading default textbox state for placeholder ${e.name}:`,t),e.current_value="DEFAULT_FUNCTION_ERROR"}}})(n),n}if("checkbox"==l){const t=Oe(r,e);return(e=>{const t=T(`${e.name}_IS_CHECKED`);null==t?e.current_is_checked=e.checked_by_default:"0"==t||"1"==t?e.current_is_checked="1"==t:(console.warn(`Unexpected state for checkbox. Should be '0' or '1', but was '${t}'`),e.current_is_checked=e.checked_by_default),e.current_value=e.current_is_checked?e.value_checked:e.value_unchecked})(t),t}if("dropdown"==l){const t=He(r,e);return(e=>{const t=T(`${e.name}_INDEX`);if(null==t)e.current_index=e.default_index;else{const n=Number(t);P(e,n)?e.current_index=n:(console.warn(`Unexpected state for dropdown. Should be a whole number N, where 0 <= N < ${e.options.length}. But it is ${t}`),e.current_index=e.default_index)}e.current_value=e.options[e.current_index].value})(t),t}if("computed"==l)return Me(r,e);throw new Error(`Unsupported placeholder type '${l}'`)},Ie=(e,t,n)=>{let o,l;if(null!=t.default_value)l=Te("default_value",t);else{const n=Te("default_function",t);o=()=>{try{const e=new Function(n)();if("string"!=typeof e)throw new Error(`Custom function '${n}' should return a string, but it returned a ${typeof e}: ${e}`);return e}catch(t){throw new Error(`Failed to evaluate default_function '${n}' of placeholder ${e.name}: ${t}`)}}}const a=De("validators","string",t),r=[];for(const e of a){const t=n.get(e);if(!t){const t=Array.from(n.keys()).join(", ");throw new Error(`No validator with id '${e}' was found. Known validators are ${t}`)}r.push(t)}const s=e.description?`\nDescription: ${e.description}`:"",i=l?`\nDefault value: ${l}`:"\nDefault value generated by function",c=`Placeholder name: ${e.name}${s}${i}\nUsage: Click to edit the value. Leaving the text field or pressing enter will store the new value, pressing Escape will revert current changes. While editing the field, the tooltip will show warnings/errors if your value is not what is expected`;return Object.assign(Object.assign({},e),{default_tooltip:c,default_function:o,default_value:l,input_elements:[],type:Re.Textbox,validators:r})},Oe=(e,t)=>Object.assign(Object.assign({},e),{checked_by_default:Ce("checked_by_default",t),current_is_checked:!1,input_elements:[],value_checked:Te("value_checked",t),value_unchecked:Te("value_unchecked",t),type:Re.Checkbox}),He=(e,t)=>{const n=De("options","object",t),o=[];for(const e of n)o.push({display_name:Te("display_name",e),value:Te("value",e)});const l=Ne("default_index",t);if(l<0)throw new Error(`Invalid value: "default_index" should not be negative, but is ${l}.\nProblematic object: ${JSON.stringify(t)}`);if(l>=o.length)throw new Error(`Invalid value: "default_index" should be smaller than the number of options (${o.length}), but is ${l}.\nProblematic object: ${JSON.stringify(t)}`);const a=e.description?`\nDescription: ${e.description}`:"";let r=`Placeholder name: ${e.name}${a}\nDefault option: ${o[l].value}\nUsage: (left-)click to cycle forward through the values, right-click to cycle through backwards. You can also use the Enter, Up, and Down keys if the placeholder is selected.\nPossible values:`;for(const e of o)r+=`\n- ${e.value}`;return Object.assign(Object.assign({},e),{default_tooltip:r,current_index:0,default_index:l,input_elements:[],options:o,type:Re.Dropdown})},Me=(e,t)=>{const n=De("computed_depends_on","string",t),o=Te("computed_function",t),l=e.description?`\nDescription: ${e.description}`:"",a=`Placeholder name: ${e.name}${l}\nThis is a computed (read-only) placeholder. Its value is automatically derived from: ${n.join(", ")}`;return Object.assign(Object.assign({},e),{default_tooltip:a,computed_depends_on:n,computed_function:t=>{try{const l=n,a=n.map((e=>{var n;return null!==(n=t[e])&&void 0!==n?n:""})),r=new Function(...l,o)(...a);if("string"!=typeof r)throw new Error(`Computed function for '${e.name}' must return a string, but returned ${typeof r}: ${r}`);return r}catch(t){throw new Error(`Failed to evaluate computed_function for placeholder '${e.name}': ${t}`)}},input_elements:[],type:Re.Computed,current_value:"",expanded_value:""})},Ve=()=>{const e=(e=>{const t=new Map,n=new Map,o=new Map,l=new Map,a=new Map,r=De("validators","object",e);for(const e of r){const t=p(e);if(a.has(t.id))throw new Error(`Multiple validators with id '${t.id}'`);a.set(t.id,t)}const s=(e=>{const t=Ce("apply_change_on_focus_change",e),n=Ce("debug",e),o=Ce("expand_auto_tables",e),l=Ce("inline_editors",e),a=Te("inline_editor_style",e);return{apply_change_on_focus_change:C("apply_change_on_focus_change",t),debug:C("debug",n),delay_millis:Ne("delay_millis",e),expand_auto_tables:C("expand_auto_tables",o),highlight_placeholders:C("highlight_placeholders",!1),inline_editors:C("inline_editors",l),inline_editor_style:N("inline_editor_style",a,Ee),normal_is_alias_for:Te("normal_is_alias_for",e),normal_prefix:Te("normal_prefix",e),normal_suffix:Te("normal_suffix",e),editable_prefix:Te("editable_prefix",e),editable_suffix:Te("editable_suffix",e),html_prefix_optional:Te("html_prefix_optional",e),html_prefix:Te("html_prefix",e),html_suffix:Te("html_suffix",e),static_prefix:Te("static_prefix",e),static_suffix:Te("static_suffix",e),dynamic_prefix:Te("dynamic_prefix",e),dynamic_suffix:Te("dynamic_suffix",e)}})(Le("settings","object",e)),i=De("placeholder_list","object",e);for(let e=0;e<i.length;e++){const r=Pe(i[e],a,s,e);t.set(r.name,r),r.type==Re.Textbox?n.set(r.name,r):r.type==Re.Checkbox?o.set(r.name,r):r.type==Re.Dropdown?l.set(r.name,r):r.type==Re.Computed||console.warn("Unknown placeholder type:",r.type)}return{placeholders:t,textboxes:n,checkboxes:o,dropdowns:l,settings:s,dependency_graph:new ye(t),input_tables:[],event_listener_abort_controller:new AbortController}})(window.PlaceholderPluginConfigJson);var t;t=e.settings.debug,i=t?{log:n,info:o,debug:l}:s,i.info("PluginConfig",e),(e=>{window.PlaceholderPlugin={version:"0.5.2-dev1",settings:e.settings,placeholders:e.placeholders,debug_disable_reload:c,debug_print_dependency_graph:()=>e.dependency_graph.debug_print_representation()}})(e);const a=e.settings.delay_millis,r=window.document$;r?r.subscribe((()=>{a>0?setTimeout((()=>Ue(e)),a):Ue(e)})):a<0?Ue(e):0==a?window.addEventListener("load",(()=>Ue(e))):window.addEventListener("load",(()=>{setTimeout((()=>Ue(e)),a)}))},Ue=e=>{i.info("Called do_plugin_stuff (function for parsing and modifying the page)"),e.placeholders.forEach(((e,t,n)=>{e.count_on_page=0,e.input_elements=[]})),((e,t)=>{for(const n of t.placeholders.values())he(e,n),fe(e,n),_e(e,n,t),me(e,n),n.allow_inner_html&&ve(e,n);(e=>{const t=document.querySelectorAll(".placeholder-value[data-placeholder]");for(const n of t){const t=n.getAttribute("data-placeholder");if(t){const o=e.placeholders.get(t);o?o.output_elements.push(n):console.warn(`No placeholder named '${t}', that is referenced by element:`,n)}else console.warn("Element has empty/no attribute 'data-placeholder':",n)}})(t),we([...t.placeholders.values()])})(document.body,e),e.dependency_graph.debug_print_representation(),(e=>{const t=document.querySelectorAll("input[data-input-for], select[data-input-for]");for(const n of t){const t=n.getAttribute("data-input-for");if(null==t)throw new Error("How can this be, the selector forces the 'data-input-for' attribute to exist");const o=e.placeholders.get(t);o?Q(e,o,n):(console.warn(`Unknown placeholder referenced in input element: '${t}'`),n.classList.add("input-for-variable"),n.value=`ERROR_UNDEFINED_PLACEHOLDER: ${t}`)}})(e),(e=>{const t=document.querySelectorAll("div.auto-input-table");if(t.length>0){const n=e.dependency_graph.get_all_used_placeholders().filter((e=>!e.read_only));for(const o of t)if(o instanceof HTMLElement){const t=o.getAttribute("data-columns")||"name,input",l=t.includes(",")?t.split(","):[t],a=null===o.getAttribute("data-hide-empty");G(o,l,e,n,a)}else console.warn("Element",o,"is expected to be an HTMLElement, but is not")}})(e),(e=>{const t=document.querySelectorAll("div.placeholder-settings-panel");for(const n of t)B(e,n,!1)})(e),e.settings.inline_editors&&j(e),document.body.classList.add("placeholder-plugin-init-done")};window.PlaceholderPluginConfigJson?Ve():document.addEventListener("PlaceholderPluginConfigJson",Ve)})();
2
+ //# sourceMappingURL=placeholder.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placeholder.min.js","mappings":"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","sources":["webpack:///./src/debug.ts","webpack:///./src/validator.ts","webpack:///./src/state_manager.ts","webpack:///./src/inline-editors/dropdown.ts","webpack:///./src/inline-editors/textbox.ts","webpack:///./src/inline-editors/register.ts","webpack:///./src/auto_tables.ts","webpack:///./src/inputs.ts","webpack:///./src/inline-editors/checkbox.ts","webpack:///./src/replacer.ts","webpack:///./src/dependency_graph.ts","webpack:///./src/parse_settings.ts","webpack:///./src/main.ts","webpack:///./src/api.ts","webpack:///./src/index.ts"],"sourcesContent":["const timestamp = () => `${new Date().toISOString().slice(11, 23)} (TS)`;\nlet is_reload_enabled = true;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction internal_log(...args) {\n console.log.apply(console, [`${timestamp()} |`, ...args]);\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction internal_info(...args) {\n console.info.apply(console, [`${timestamp()} |`, ...args]);\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction internal_debug(...args) {\n console.debug.apply(console, [`${timestamp()} |`, ...args]);\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction noop(..._args) {\n}\nexport const reload_page = () => {\n if (is_reload_enabled) {\n window.location.reload();\n }\n else {\n internal_info(\"Page reload was triggered and blocked due to PlaceholderPlugin.debug_disable_reload\");\n }\n};\nconst noop_logger = {\n \"log\": noop,\n \"info\": noop,\n \"debug\": noop,\n};\nexport const init_logging = (enable_debug) => {\n if (enable_debug) {\n // Write debugging messages to console\n logger = {\n \"log\": internal_log,\n \"info\": internal_info,\n \"debug\": internal_debug,\n };\n }\n else {\n // If debugging is disabled, make the functions do nothing\n logger = noop_logger;\n return;\n }\n};\nexport let logger = noop_logger;\n// You can call this manually from the browser's console to temporarily disable reloads and debug the application\nexport const debug_disable_reload = () => {\n internal_info(\"Page reload was disabled for debugging purposes\");\n is_reload_enabled = false;\n};\n","import { logger } from \"./debug\";\nimport { get_array_field, get_boolean_field, get_string_field } from \"./parse_settings\";\nexport var ValidatorSeverity;\n(function (ValidatorSeverity) {\n ValidatorSeverity[\"Warning\"] = \"WARNING\";\n ValidatorSeverity[\"Error\"] = \"ERROR\";\n})(ValidatorSeverity || (ValidatorSeverity = {}));\nexport var PlaceholderValidatity;\n(function (PlaceholderValidatity) {\n PlaceholderValidatity[\"Good\"] = \"GOOD\";\n PlaceholderValidatity[\"Warning\"] = \"WARNING\";\n PlaceholderValidatity[\"Error\"] = \"ERROR\";\n PlaceholderValidatity[\"NoValidator\"] = \"NO_VALIDATOR\";\n})(PlaceholderValidatity || (PlaceholderValidatity = {}));\n// We accept unknown data to parse, so I think the any type is ok.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const parse_validator = (data) => {\n const rules = get_array_field(\"rules\", \"object\", data);\n if (rules.length == 0) {\n throw new Error(`Rules should not be an empty array.\\nProblematic object: ${JSON.stringify(data)}`);\n }\n const id = get_string_field(\"id\", data);\n return {\n \"display_name\": get_string_field(\"display_name\", data),\n \"id\": id,\n \"rules\": rules.map(x => parse_rule(x, id)),\n };\n};\nconst is_valid_value = (validator, value) => {\n for (const rule of validator.rules) {\n if (rule.is_match_function(value) != rule.should_match) {\n // this rule rejects the value\n if (rule.severity == ValidatorSeverity.Error) {\n // immediately return once we found a hard failure\n return false;\n }\n }\n }\n // no real errors -> is valid\n return true;\n};\nexport const is_valid_value_for_placeholder = (placeholder, value) => {\n // @TODO decide: validate normal value or expanded value? Needs to be checked for every function call\n if (placeholder.validators.length > 0) {\n for (const validator of placeholder.validators) {\n if (is_valid_value(validator, value)) {\n // a single validator accepting it is enough\n return true;\n }\n }\n // no validator accepted it -> bad\n return false;\n }\n else {\n return true;\n }\n};\nconst validate_value = (validator, value) => {\n const warnings = [];\n const errors = [];\n for (const rule of validator.rules) {\n if (rule.is_match_function(value) != rule.should_match) {\n // this rule rejects the value\n if (rule.severity == ValidatorSeverity.Error) {\n errors.push(`[${validator.display_name}] Error: ${rule.error_message}`);\n }\n else if (rule.severity == ValidatorSeverity.Warning) {\n warnings.push(`[${validator.display_name}] Warning: ${rule.error_message}`);\n }\n else {\n console.warn(`Unknown rule severity ${rule.severity}`);\n }\n }\n }\n return {\n \"errors\": errors,\n \"warnings\": warnings,\n };\n};\nexport const validate_placeholder_value = (placeholder, value) => {\n const result_list = [];\n let has_no_error = false; // whether at least one placeholder has no errors\n if (placeholder.validators.length > 0) {\n for (const validator of placeholder.validators) {\n const result = validate_value(validator, value);\n result_list.push(result);\n if (result.errors.length == 0) {\n has_no_error = true;\n if (result.warnings.length == 0) {\n return placeholder_is_good(placeholder);\n }\n }\n }\n if (has_no_error) {\n return placeholder_is_warning(result_list);\n }\n else {\n return placeholder_is_error(result_list);\n }\n }\n else {\n return {\n \"rating\": PlaceholderValidatity.NoValidator,\n \"message\": \"No validators are specified for this placeholder\",\n };\n }\n};\nconst placeholder_is_error = (result_list) => {\n // If all of them have errors, we will ignore the warnings to keep it shorter\n const errors = [];\n for (const result of result_list) {\n errors.push(...result.errors);\n }\n return {\n \"rating\": PlaceholderValidatity.Error,\n \"message\": errors.join(\"\\n\"),\n };\n};\nconst placeholder_is_warning = (result_list) => {\n // If some return warnings and some return errors, we will only show the ones with warnings.\n const lines = [];\n for (const result of result_list) {\n if (result.errors.length == 0) {\n lines.push(...result.warnings);\n }\n }\n return {\n \"rating\": PlaceholderValidatity.Warning,\n \"message\": lines.join(\"\\n\"),\n };\n};\nconst placeholder_is_good = (placeholder) => {\n // If one of them has neither warnings or errors, we return Good status immediately\n let message;\n if (placeholder.validators.length == 1) {\n message = `Expecting: ${placeholder.validators[0].display_name}`;\n }\n else {\n message = \"Expecting one of the following: \";\n for (const v of placeholder.validators) {\n message += `\\n - ${v.display_name}`;\n }\n }\n return {\n \"rating\": PlaceholderValidatity.Good,\n \"message\": message,\n };\n};\n// We accept unknown data to parse, so I think the any type is ok.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst parse_rule = (data, validator_id) => {\n const severity_str = get_string_field(\"severity\", data);\n let severity;\n if (severity_str == \"warning\" || severity_str == \"warn\") {\n severity = ValidatorSeverity.Warning;\n }\n else if (severity_str == \"error\") {\n severity = ValidatorSeverity.Error;\n }\n else {\n throw new Error(`Unknown severity '${severity_str}'`);\n }\n let is_match_function;\n if (data.regex) {\n const regex = get_string_field(\"regex\", data);\n const compiled_regex = new RegExp(regex);\n is_match_function = (value) => compiled_regex.test(value);\n }\n else {\n const match_function_body = get_string_field(\"match_function\", data);\n // we need to use Function instead of eval(), since minification will rename the argument\n // this may also be more performant, since the code is only compiled once\n const match_function = new Function(\"value\", match_function_body);\n is_match_function = (value) => {\n try {\n const result = match_function(value);\n if (typeof (result) != \"boolean\") {\n throw new Error(`Custom match_function '${match_function_body}' of validator ${validator_id} should return a boolean, but it returned a ${typeof (result)}: ${result}`);\n }\n else {\n return result;\n }\n }\n catch (error) {\n throw new Error(`Failed to evaluate match_function '${match_function_body}' of validator ${validator_id}: ${error}`);\n }\n };\n }\n return {\n \"severity\": severity,\n \"should_match\": get_boolean_field(\"should_match\", data),\n \"error_message\": get_string_field(\"error_message\", data),\n \"is_match_function\": is_match_function,\n };\n};\nexport const update_tooltip = (input_field, validation_result) => {\n // Set highlighting\n input_field.classList.remove(\"validation-error\", \"validation-warn\", \"validation-ok\", \"validation-none\");\n if (validation_result.rating == PlaceholderValidatity.Good) {\n input_field.classList.add(`validation-ok`);\n }\n else if (validation_result.rating == PlaceholderValidatity.Warning) {\n input_field.classList.add(`validation-warn`);\n }\n else if (validation_result.rating == PlaceholderValidatity.Error) {\n input_field.classList.add(`validation-error`);\n }\n else if (validation_result.rating == PlaceholderValidatity.NoValidator) {\n input_field.classList.add(`validation-none`);\n }\n else {\n console.warn(`Unknown placeholder validity: ${validation_result.rating}`);\n }\n // Set tooltip\n input_field.title = validation_result.message;\n};\n// Returns \"false\" if the value has an error, so for example page reloading should be cancelled.\nexport const validate_textbox_input_field = (placeholder, input_field) => {\n const result = validate_placeholder_value(placeholder, input_field.value);\n update_tooltip(input_field, result);\n logger.debug(\"Validation: name =\", placeholder.name, \", value =\", input_field.value, \", results =\", result.rating);\n const can_accept_value = result.rating != PlaceholderValidatity.Error;\n return can_accept_value;\n};\n// Returns \"false\" if the value has an error, so for example page reloading should be cancelled.\nexport const validate_textbox_editable_span = (placeholder, input_field) => {\n const result = validate_placeholder_value(placeholder, input_field.innerText);\n update_tooltip(input_field, result);\n logger.debug(\"Validation: name =\", placeholder.name, \", value =\", input_field.innerText, \", results =\", result.rating);\n const can_accept_value = result.rating != PlaceholderValidatity.Error;\n return can_accept_value;\n};\n","import { logger, reload_page } from \"./debug\";\nimport { is_valid_value_for_placeholder } from \"./validator\";\n// These functions are here to make it easier to change the storage backend (for example locasstorage -> cookies)\n// and to make it possible to potentially have better debugging\nconst STORAGE_PREFIX = \"PLACEHOLDER_\"; // @TODO make it configurable by settings?\nconst SETTINGS_PREFIX = \"PLACEHOLDER-SETTING_\";\nconst store_value = (name, value) => {\n localStorage.setItem(STORAGE_PREFIX + name, value);\n};\nconst load_value = (name) => {\n return localStorage.getItem(STORAGE_PREFIX + name);\n};\nexport const store_boolean_setting = (name, value) => {\n logger.info(`Storing boolean setting '${name}' with value ${value}`);\n localStorage.setItem(`${SETTINGS_PREFIX}${name}`, value ? \"1\" : \"0\");\n};\nexport const load_boolean_setting = (name, default_value) => {\n const stored = localStorage.getItem(`${SETTINGS_PREFIX}${name}`);\n logger.info(`Reading boolean setting '${name}' with value ${stored}`);\n if (stored === null) {\n return default_value;\n }\n else if (stored === \"1\") {\n return true;\n }\n else if (stored === \"0\") {\n return false;\n }\n else {\n // Unexpected state, warn user and fall back to default\n console.warn(`Unexpected state for boolean setting. Should be null, '0' or '1', but was '${stored}'`);\n return default_value;\n }\n};\nexport const store_multiple_choice_setting = (name, value, choices) => {\n if (choices.includes(value)) {\n localStorage.setItem(`${SETTINGS_PREFIX}${name}`, value);\n }\n else {\n console.error(`Tried to store value '${value}' for setting '${name}', but only ${choices} are allowed`);\n }\n};\nexport const load_multiple_choice_setting = (name, default_value, allowed_values) => {\n if (!allowed_values.includes(default_value)) {\n console.warn(`Default value '${default_value}' for multiple choice setting ${name} is not in the list of allowed values. Allowed are: ${allowed_values}`);\n }\n const stored = localStorage.getItem(`${SETTINGS_PREFIX}${name}`);\n logger.info(`Reading multiple choice setting '${name}' with value ${stored}`);\n if (stored === null) {\n return default_value;\n }\n else if (allowed_values.includes(stored)) {\n return stored;\n }\n else {\n // Unexpected state, warn user and fall back to default\n console.warn(`Unexpected state for multiple choice setting. Should be null or one of ${allowed_values}, but was '${stored}'`);\n return default_value;\n }\n};\n// I changed the storage model: the real value is stored in the placeholder object instead of in localstorage -> easier and safer to access\n// We pass the whole placeholder instead of just a name, so that you can not accidentally call the wrong function or use an invalid placeholder name\n// We use different values for different types (checkbox -> NAME_IS_CHECKED, textbox -> NAME_TEXT, ...) so that if a user changes the type of a placeholder it should not cause problems\nexport const store_checkbox_state = (placeholder, new_is_checked) => {\n // Update the placeholder's value\n placeholder.current_is_checked = new_is_checked;\n placeholder.current_value = new_is_checked ? placeholder.value_checked : placeholder.value_unchecked;\n // Permanently store the new state\n store_value(`${placeholder.name}_IS_CHECKED`, new_is_checked ? \"1\" : \"0\");\n};\nexport const load_checkbox_state = (placeholder) => {\n const stored_state = load_value(`${placeholder.name}_IS_CHECKED`);\n if (stored_state == null) {\n // No stored state -> use default value\n placeholder.current_is_checked = placeholder.checked_by_default;\n }\n else {\n if (stored_state == \"0\" || stored_state == \"1\") {\n // Load the stored state\n placeholder.current_is_checked = stored_state == \"1\";\n }\n else {\n // Unexpected state, warn user and fall back to default\n console.warn(`Unexpected state for checkbox. Should be '0' or '1', but was '${stored_state}'`);\n placeholder.current_is_checked = placeholder.checked_by_default;\n }\n }\n // Now we update the actual value based on the state\n placeholder.current_value = placeholder.current_is_checked ? placeholder.value_checked : placeholder.value_unchecked;\n};\nexport const clear_state = () => {\n clear_by_prefix(STORAGE_PREFIX);\n};\nexport const clear_settings = () => {\n clear_by_prefix(SETTINGS_PREFIX);\n};\nconst clear_by_prefix = (prefix) => {\n // The easiest way would be to clear the whole storage, but that might break other plugins / scripts.\n // So we only delete all items that start with our prefix\n console.warn(`Clearing all localStorage items starting with '${prefix}'`);\n let i = 0;\n while (i < localStorage.length) {\n const key = localStorage.key(i);\n if (key === null || key === void 0 ? void 0 : key.startsWith(prefix)) {\n // Delete the item\n localStorage.removeItem(key);\n }\n else {\n // Not ours, so we skip it\n i++;\n }\n }\n reload_page();\n};\nconst is_valid_index = (placeholder, index) => {\n try {\n const item = placeholder.options[index];\n return item != undefined && item != null;\n }\n catch (error) {\n return false;\n }\n};\nexport const store_dropdown_state = (placeholder, new_index) => {\n // Perform sanity checks on the index\n if (is_valid_index(placeholder, new_index)) {\n store_value(`${placeholder.name}_INDEX`, `${new_index}`);\n placeholder.current_value = placeholder.options[new_index].value;\n placeholder.current_index = new_index;\n }\n else {\n throw new Error(`Index must a whole number N, where 0 <= N < ${placeholder.options.length}. But it is ${new_index}`);\n }\n};\nexport const load_dropdown_state = (placeholder) => {\n const stored_state = load_value(`${placeholder.name}_INDEX`);\n if (stored_state == null) {\n // No stored state -> use default value\n placeholder.current_index = placeholder.default_index;\n }\n else {\n const stored_index = Number(stored_state);\n if (is_valid_index(placeholder, stored_index)) {\n // Load the stored state\n placeholder.current_index = stored_index;\n }\n else {\n // Unexpected state, warn user and fall back to default\n console.warn(`Unexpected state for dropdown. Should be a whole number N, where 0 <= N < ${placeholder.options.length}. But it is ${stored_state}`);\n placeholder.current_index = placeholder.default_index;\n }\n }\n // Now we update the actual value based on the state\n placeholder.current_value = placeholder.options[placeholder.current_index].value;\n};\nexport const store_textbox_state = (placeholder, new_value) => {\n const is_validation_ok = is_valid_value_for_placeholder(placeholder, new_value);\n logger.info(`Set textbox ${placeholder.name} to '${new_value}'. Validation ok? ${is_validation_ok}`);\n if (is_validation_ok) {\n store_value(`${placeholder.name}_TEXT`, new_value);\n }\n else {\n throw new Error(`Validation error: Value '${new_value}' is not valid for placeholder ${placeholder.name}`);\n }\n};\nexport const load_textbox_state = (placeholder) => {\n const stored_state = load_value(`${placeholder.name}_TEXT`);\n if (stored_state != null) {\n if (is_valid_value_for_placeholder(placeholder, stored_state)) {\n placeholder.current_value = stored_state;\n return; // Do not use the default value / function\n }\n else {\n console.warn(`Stored value for placeholder ${placeholder.name} is invalid: '${stored_state}'. Will revert to default.`);\n // Should we remove the value? Idk\n }\n }\n // Use a default value\n if (placeholder.default_value != undefined) {\n placeholder.current_value = placeholder.default_value;\n if (!is_valid_value_for_placeholder(placeholder, placeholder.default_value)) {\n console.warn(`Default value for placeholder '${placeholder.name}' is invalid: '${placeholder.default_value}'`);\n }\n }\n else if (placeholder.default_function) {\n try {\n const result = placeholder.default_function();\n placeholder.current_value = result;\n try {\n // store the function result, since it may be different with each invocation (such as a randomly generated password)\n store_textbox_state(placeholder, result);\n }\n catch (error) {\n console.warn(`Default function for placeholder '${placeholder.name}' returned invalid value: '${result}'`);\n }\n }\n catch (error) {\n // This will be called if the placeholder's custom function fails\n console.error(`Error while loading default textbox state for placeholder ${placeholder.name}:`, error);\n placeholder.current_value = \"DEFAULT_FUNCTION_ERROR\";\n }\n }\n else {\n throw new Error(`Either 'default_value' or 'default_function' needs to be set for placeholder ${placeholder.name}`);\n }\n};\n","import { on_placeholder_change } from \"../inputs\";\nimport { store_dropdown_state } from \"../state_manager\";\n// Source: https://pictogrammers.com/library/mdi/icon/swap-horizontal/\nconst SWAP_SVG_URL = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M21,9L17,5V8H10V10H17V13M7,11L3,15L7,19V16H14V14H7V11Z\" /></svg>';\nexport const prepare_span_for_dropdown_editor = (config, input_element, placeholder) => {\n input_element.classList.add(\"placeholder-value-dropdown\");\n // There should be only one, but this prevents crashes if there are more or even none\n input_element.querySelectorAll(\".inline-editor-icon-span\").forEach(icon => { icon.innerHTML = SWAP_SVG_URL; });\n input_element.setAttribute(\"tabindex\", \"0\");\n const abort_signal_object = { signal: config.event_listener_abort_controller.signal };\n const description = placeholder.description ? `\\nDescription: ${placeholder.description}` : \"\";\n let tooltip = `Placeholder name: ${placeholder.name}${description}\\nDefault option: ${placeholder.options[placeholder.default_index].value}\\nUsage: (left-)click to cycle forward through the values, right-click to cycle through backwards. You can also use the Enter, Up, and Down keys if the placeholder is selected.\\nPossible values:`;\n for (const option of placeholder.options) {\n tooltip += `\\n- ${option.value}`;\n }\n input_element.title = tooltip;\n const modify_index_by = (count) => {\n let index = (placeholder.current_index + count) % placeholder.options.length;\n if (index < 0) {\n index += placeholder.options.length;\n }\n store_dropdown_state(placeholder, index);\n placeholder.current_index = index;\n placeholder.current_value = placeholder.options[index].value;\n on_placeholder_change(config, placeholder);\n };\n // Showing an inline dropdown modifies the layout too much and binding it to events like click, mouseenter, etc is problematic. Thus this seems to be the simplest and least buggy solution.\n input_element.addEventListener(\"click\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n modify_index_by(1);\n }, abort_signal_object);\n input_element.addEventListener(\"contextmenu\", (event) => {\n // prevent right click menu\n event.preventDefault();\n event.stopPropagation();\n modify_index_by(-1);\n }, abort_signal_object);\n input_element.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\" || event.key === \"ArrowDown\") {\n modify_index_by(1);\n event.preventDefault();\n }\n else if (event.key === 'ArrowUp') {\n modify_index_by(-1);\n event.preventDefault();\n }\n }, abort_signal_object);\n};\n","import { logger } from \"../debug\";\nimport { validate_textbox_editable_span, validate_placeholder_value, PlaceholderValidatity } from \"../validator\";\nimport { on_placeholder_change } from \"../inputs\";\nimport { store_textbox_state } from \"../state_manager\";\nimport { change_text_keep_other_children } from \"../replacer\";\n// Source: https://pictogrammers.com/library/mdi/icon/pencil/\nconst PEN_SVG = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z\" /></svg>';\nexport const prepare_span_for_textbox_editor = (config, input_element, placeholder) => {\n // We need to set this so that the element can obtain focus.\n input_element.tabIndex = 0;\n // Stop browsers from trying to be smart\n input_element.spellcheck = false;\n input_element.translate = false;\n input_element.autocapitalize = \"off\";\n // Add a special class for styling\n input_element.classList.add(\"placeholder-value-editable\");\n // There should be only one, but this prevents crashes if there are more or even none\n input_element.querySelectorAll(\".inline-editor-icon-span\").forEach(icon => { icon.innerHTML = PEN_SVG; });\n const abort_signal_object = { signal: config.event_listener_abort_controller.signal };\n // copy paste from inputs.ts @TODO clean up/deduplicate\n const confirm_change = () => {\n if (placeholder.current_value == input_element.innerText) {\n logger.debug(`Value for placeholder ${placeholder.name} was not changed`);\n }\n else {\n // Expensive actions, only perform them if the value was actually changed\n if (validate_textbox_editable_span(placeholder, input_element)) {\n store_textbox_state(placeholder, input_element.innerText);\n placeholder.current_value = input_element.innerText;\n on_placeholder_change(config, placeholder);\n // The new value is applied, so it now is the same as the stored one\n input_element.classList.remove(\"value-modified\");\n }\n }\n };\n // Check if initial value is valid and initialize the tooltip\n validate_textbox_editable_span(placeholder, input_element);\n input_element.title = placeholder.default_tooltip;\n // Listen for state changes\n input_element.addEventListener(\"input\", () => {\n // The text was probably modified, so we need to update the validator\n validate_textbox_editable_span(placeholder, input_element);\n // Update the changed status of the placeholder\n if (input_element.innerText == placeholder.current_value) {\n input_element.classList.remove(\"value-modified\");\n }\n else {\n input_element.classList.add(\"value-modified\");\n }\n }, abort_signal_object);\n input_element.addEventListener(\"keypress\", (event) => {\n if (event.key === \"Enter\") {\n // prevent inserting a line break\n event.preventDefault();\n logger.debug(\"Textbox change confirmed with Enter key for\", placeholder.name, \"- new value:\", input_element.innerText);\n confirm_change();\n select_all_text_in_element(input_element);\n }\n }, abort_signal_object);\n input_element.addEventListener(\"keydown\", (event) => {\n // I have no idea, why Escape does not work with the keypress event (Safari on MacOS). As a work around, we listen to the keydown event\n if (event.key === \"Escape\") {\n logger.debug(\"Resetting input field for \", placeholder.name, \" to current placeholder value\");\n change_text_keep_other_children(input_element, placeholder.current_value);\n // reset the validation state\n validate_textbox_editable_span(placeholder, input_element);\n input_element.classList.remove(\"value-modified\");\n select_all_text_in_element(input_element);\n }\n }, abort_signal_object);\n input_element.addEventListener(\"focusout\", () => {\n var _a;\n logger.debug(\"Focus lost\");\n // The value may change on the fly (use changes settings), so we can not just conditionally add the event listener, but need to check each time\n if (config.settings.apply_change_on_focus_change) {\n logger.debug(\"Textbox change confirmed by changing focus\", placeholder.name, \"- new value:\", input_element.innerText);\n confirm_change();\n }\n // if there are no validation warnings or errors, restore the original tooltip for all inline editors (since they are updated to reflect the validation status)\n const validation_result = validate_placeholder_value(placeholder, input_element.innerText);\n if (validation_result.rating == PlaceholderValidatity.Good || validation_result.rating == PlaceholderValidatity.NoValidator) {\n for (const element of placeholder.output_elements) {\n if (element.classList.contains(\"placeholder-value-editable\")) {\n element.title = placeholder.default_tooltip;\n }\n }\n }\n // disable editing to make selecting (part of the) text work\n input_element.contentEditable = \"false\";\n // Remove the selection range (by default entire element)\n (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();\n }, abort_signal_object);\n input_element.addEventListener(\"focusin\", () => {\n logger.debug(\"Focus gained\");\n // This lets users actually modify the span like an input element\n // Because firefox does not support this attribute, we need to do exception handling and fall back to the one it supports\n try {\n input_element.contentEditable = \"plaintext-only\";\n }\n catch (_a) {\n input_element.contentEditable = \"true\";\n }\n // show the validation popup instead\n validate_textbox_editable_span(placeholder, input_element);\n // Select the whole contents of the element when it gains focus. This is required for tabbing into the element to create a cursor.\n // It also makes it quicker to replace the whole value of an element.\n setTimeout(() => select_all_text_in_element(input_element), 5);\n }, abort_signal_object);\n};\nlet shown_no_selection_warning = false;\nconst select_all_text_in_element = (element) => {\n // Check if the browser supports the Selection and Range APIs\n if (window.getSelection && document.createRange) {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n const range = document.createRange();\n range.selectNodeContents(element.firstChild || element); // fix safari bug? Select only the text node, not the icon too\n selection.addRange(range);\n }\n else if (!shown_no_selection_warning) {\n shown_no_selection_warning = true;\n console.warn(\"getSelection returned null\");\n }\n }\n else {\n if (!shown_no_selection_warning) {\n shown_no_selection_warning = true;\n console.warn(\"Can not set selection, because window.getSelection or document.createRange are not supported\");\n }\n }\n};\n","import { InputType, VALID_INLINE_EDITOR_STYLES } from \"../parse_settings\";\nimport { prepare_span_for_checkbox_editor } from \"./checkbox\";\nimport { prepare_span_for_dropdown_editor } from \"./dropdown\";\nimport { prepare_span_for_textbox_editor } from \"./textbox\";\nexport const register_inline_value_editors = (config) => {\n // Ensure that the correct class is set before the editors are created\n set_inline_editor_style(config.settings.inline_editor_style);\n const placeholder_value_elements = document.querySelectorAll(\"span.placeholder-value.inline-editor-requested[data-placeholder]\");\n for (const element of placeholder_value_elements) {\n const placeholder_name = element.getAttribute(\"data-placeholder\");\n if (placeholder_name) {\n // ^-- Should always be true, since we check for it in our query\n const placeholder = config.placeholders.get(placeholder_name);\n if (placeholder) {\n if (!placeholder.read_only) {\n element.classList.add(\"placeholder-value-any\");\n const icon = document.createElement(\"span\");\n icon.classList.add(\"inline-editor-icon-span\");\n icon.contentEditable = \"false\";\n element.appendChild(icon);\n if (placeholder.type == InputType.Textbox) {\n prepare_span_for_textbox_editor(config, element, placeholder);\n }\n else if (placeholder.type == InputType.Checkbox) {\n prepare_span_for_checkbox_editor(config, element, placeholder);\n }\n else if (placeholder.type == InputType.Dropdown) {\n prepare_span_for_dropdown_editor(config, element, placeholder);\n }\n }\n }\n else {\n console.warn(`Unknown placeholder referenced in input element: '${placeholder_name}'`, element);\n }\n }\n }\n};\nexport const unregister_inline_value_editors = (config) => {\n const placeholder_value_elements = document.querySelectorAll(\"span.placeholder-value-editable, span.placeholder-value-checkbox, span.placeholder-value-dropdown\");\n // Remove all previously added event listeners\n config.event_listener_abort_controller.abort();\n // Replace the now triggered abort controller with a new one\n config.event_listener_abort_controller = new AbortController();\n // Remove the specific classes and editable attribute that the register method added\n for (const element of placeholder_value_elements) {\n const span_element = element;\n span_element.classList.remove(\"placeholder-value-editable\", \"placeholder-value-checkbox\", \"placeholder-value-dropdown\", \"placeholder-value-any\", \"validation-error\", \"validation-warn\", \"validation-ok\", \"validation-none\");\n // make it non-editable (only affects textbox placeholders)\n span_element.contentEditable = \"false\";\n // remove the tooltip\n span_element.title = \"\";\n // remove the ability to focus them via tab\n span_element.removeAttribute(\"tabindex\");\n // remove the icon\n span_element.querySelectorAll(\".inline-editor-icon-span\").forEach(icon => icon.remove());\n }\n};\nexport const set_inline_editor_style = (style) => {\n if (VALID_INLINE_EDITOR_STYLES.includes(style)) {\n // We add the class to the body, so that it will apply to all placeholders (at once)\n for (const style_to_remove of VALID_INLINE_EDITOR_STYLES) {\n document.body.classList.remove(`inline-editor-${style_to_remove}`);\n }\n document.body.classList.add(`inline-editor-${style}`);\n }\n else {\n console.error(`Tried to set inline editor style '${style}', but only ${VALID_INLINE_EDITOR_STYLES} are allowed`);\n }\n};\n","import { logger } from \"./debug\";\nimport { register_inline_value_editors, set_inline_editor_style, unregister_inline_value_editors } from \"./inline-editors/register\";\nimport { prepare_input_field } from \"./inputs\";\nimport { VALID_INLINE_EDITOR_STYLES } from \"./parse_settings\";\nimport { create_dynamic_placeholder_element } from \"./replacer\";\nimport { clear_settings, clear_state, store_boolean_setting, store_multiple_choice_setting } from \"./state_manager\";\nconst TABLE_CELL_HEADINGS = new Map();\nTABLE_CELL_HEADINGS.set(\"name\", \"Name\");\nTABLE_CELL_HEADINGS.set(\"description\", \"Description\");\nTABLE_CELL_HEADINGS.set(\"value\", \"Value\");\nTABLE_CELL_HEADINGS.set(\"input\", \"Input element\");\nTABLE_CELL_HEADINGS.set(\"description-or-name\", \"Description / name\");\n// Created myself, so no licensing issues should occur. Still, a decent unicode / font awesome icon may be better if it works across themes/operating systems/browsers\nconst GEAR_SVG = `<svg viewBox=\"0 0 40 40\" xmlns=\"http://www.w3.org/2000/svg\">\n <path id=\"svg_6\" d=\"m7.79338,20.02127l0,0c0,-6.84327 5.74307,-12.39083 12.82751,-12.39083l0,0c3.40207,0 6.6648,1.30546 9.07042,3.62919c2.40563,2.32373 3.75709,5.47539 3.75709,8.76164l0,0c0,6.84327 -5.74307,12.39083 -12.82751,12.39083l0,0c-7.08444,0 -12.82751,-5.54757 -12.82751,-12.39083zm6.41376,0l0,0c0,3.42163 2.87154,6.19542 6.41376,6.19542c3.54222,0 6.41376,-2.77378 6.41376,-6.19542c0,-3.42163 -2.87154,-6.19542 -6.41376,-6.19542l0,0c-3.54222,0 -6.41376,2.77378 -6.41376,6.19542z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path id=\"svg_7\" d=\"m17.46095,7.63098l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(180, 20.9544, 35.1419)\" id=\"svg_11\" d=\"m17.57012,37.76199l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(43, 31.5439, 9.59605)\" id=\"svg_12\" d=\"m28.15964,12.21614l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(90, 35.9107, 19.8581)\" id=\"svg_13\" d=\"m32.52645,22.47815l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(135, 31.7623, 30.2292)\" id=\"svg_14\" d=\"m28.37798,32.84933l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(-45, 9.49152, 9.48688)\" id=\"svg_15\" d=\"m6.10724,12.10697l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(-90, 5.01553, 19.9672)\" id=\"svg_16\" d=\"m1.63126,22.58732l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n <path transform=\"rotate(-135, 9.60069, 30.7751)\" id=\"svg_17\" d=\"m6.21641,33.39518l1.2691,-5.24017l4.23035,0l1.2691,5.24017l-6.76856,0z\" stroke=\"#fff\" fill=\"#ffffff\"/>\n</svg>`;\n// Helper functions to simplify the following code\nconst appendTextNode = (element, text) => {\n element.appendChild(document.createTextNode(text));\n};\nconst createChildElement = (parent, tag_name) => {\n const child = document.createElement(tag_name);\n parent.appendChild(child);\n return child;\n};\nconst convert_to_dynamic_placeholder_table = (config, element, content_element) => {\n // Remove the current contents. This enables the plugin to generate fallback contents in case the JavaScript code does not work\n element.innerHTML = \"\";\n const title = createChildElement(element, \"div\");\n const title_text = createChildElement(title, \"div\");\n const settings_button = createChildElement(title, \"div\");\n const expandable_contents = createChildElement(element, \"div\");\n const settings_contents = createChildElement(expandable_contents, \"div\");\n expandable_contents.append(content_element);\n const update_expanded_state = (is_expanded) => {\n expandable_contents.style.display = is_expanded ? \"flex\" : \"none\";\n title_text.textContent = \"Placeholders: Click here to \" + (is_expanded ? \"collapse\" : \"expand\");\n };\n title.classList.add(\"auto-table-title\");\n expandable_contents.classList.add(\"expandable_contents\");\n settings_contents.classList.add(\"settings_contents\");\n let expanded = config.settings.expand_auto_tables;\n update_expanded_state(expanded);\n title_text.addEventListener(\"click\", () => {\n expanded = !expanded;\n update_expanded_state(expanded);\n });\n title_text.classList.add(\"text\");\n prepare_settings_button(settings_button, settings_contents, () => {\n if (!expanded) {\n expanded = true;\n update_expanded_state(expanded);\n }\n });\n fill_settings_content_container(config, settings_contents, true);\n};\nconst prepare_settings_button = (settings_button, settings_contents, expand_if_needed) => {\n let show_settings = false;\n settings_button.onclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n show_settings = !show_settings;\n settings_contents.style.display = show_settings ? \"flex\" : \"none\";\n if (show_settings) {\n expand_if_needed();\n }\n };\n settings_contents.style.display = show_settings ? \"flex\" : \"none\";\n settings_button.classList.add(\"settings_button\");\n settings_button.innerHTML = GEAR_SVG;\n settings_button.title = \"Hide / show settings\";\n};\nconst fill_settings_content_container = (config, settings_contents, in_placeholder_table) => {\n const set_highlight_placeholders = (enabled) => {\n for (const placeholder of config.placeholders.values()) {\n for (const output of placeholder.output_elements) {\n if (enabled) {\n output.classList.add(\"placeholder-value-highlighted\");\n }\n else {\n output.classList.remove(\"placeholder-value-highlighted\");\n }\n }\n }\n };\n set_highlight_placeholders(config.settings.highlight_placeholders);\n const set_inline_editors_enabled = (enabled) => {\n if (enabled) {\n register_inline_value_editors(config);\n }\n else {\n unregister_inline_value_editors(config);\n }\n };\n if (in_placeholder_table) {\n createChildElement(settings_contents, \"b\").textContent = \"Settings\";\n }\n const do_nothing = (_enabled) => { };\n // @TODO: later: when there are multiple settings dialogs, keep their values in sync\n append_boolean_setting_checkbox(settings_contents, config.settings.expand_auto_tables, \"expand_auto_tables\", \"Expand placeholder tables by default*\", do_nothing);\n append_boolean_setting_checkbox(settings_contents, config.settings.apply_change_on_focus_change, \"apply_change_on_focus_change\", \"Apply value when focus changes away*\", do_nothing);\n append_boolean_setting_checkbox(settings_contents, config.settings.debug, \"debug\", \"Log JavaScript debug messages to console*\", do_nothing);\n append_boolean_setting_checkbox(settings_contents, config.settings.highlight_placeholders, \"highlight_placeholders\", \"Highlight placeholders (useful for debugging)\", set_highlight_placeholders);\n append_boolean_setting_checkbox(settings_contents, config.settings.inline_editors, \"inline_editors\", \"Allow editing placeholders directly in the page\", set_inline_editors_enabled);\n append_setting_dropdown(settings_contents, config.settings.inline_editor_style, VALID_INLINE_EDITOR_STYLES, \"inline_editor_style\", \"Style to apply to inline placeholder editors\", set_inline_editor_style);\n createChildElement(settings_contents, \"i\").textContent = \"* You need to reload the page for these settings to take effect.\";\n const settings_button_bar = createChildElement(settings_contents, \"div\");\n settings_button_bar.classList.add(\"button-bar\");\n const settings_reset_button = createChildElement(settings_button_bar, \"button\");\n settings_reset_button.textContent = \"Reset settings\";\n settings_reset_button.addEventListener(\"click\", clear_settings);\n const placeholder_reset_button = createChildElement(settings_button_bar, \"button\");\n placeholder_reset_button.textContent = \"Reset all placeholders\";\n placeholder_reset_button.addEventListener(\"click\", clear_state);\n};\nconst append_boolean_setting_checkbox = (parent_element, value, name, label_text, custom_on_change) => {\n const label = createChildElement(parent_element, \"label\");\n label.textContent = `${label_text} `;\n const checkbox = createChildElement(label, \"input\");\n checkbox.type = \"checkbox\";\n checkbox.checked = value;\n checkbox.addEventListener(\"change\", () => {\n store_boolean_setting(name, checkbox.checked);\n custom_on_change(checkbox.checked);\n });\n};\nconst append_setting_dropdown = (parent_element, value, allowed_values, name, label_text, custom_on_change) => {\n const label = createChildElement(parent_element, \"label\");\n label.textContent = `${label_text} `;\n const dropdown = createChildElement(label, \"select\");\n for (const style_name of allowed_values) {\n const option_element = document.createElement(\"option\");\n option_element.text = style_name;\n option_element.value = style_name;\n dropdown.appendChild(option_element);\n }\n dropdown.value = value;\n dropdown.addEventListener(\"change\", () => {\n store_multiple_choice_setting(name, dropdown.value, allowed_values);\n custom_on_change(dropdown.value);\n });\n};\nconst generate_automatic_placeholder_table = (element, columns, config, placeholders_to_show, show_empty) => {\n placeholders_to_show = sort_and_remove_duplicate_placeholders(placeholders_to_show);\n const root_element = document.createElement(\"div\");\n if (placeholders_to_show.length == 0) {\n if (show_empty) {\n root_element.textContent = \"No placeholders to be shown\";\n }\n else {\n // Remove the table placeholder\n element.remove();\n // No need constructing something that is never added to the DOM -> return immediately\n return;\n }\n }\n else {\n logger.info(\"Creating automatic input table at\", element, \"with columns\", columns);\n root_element.classList.add(\"table-div\");\n createChildElement(root_element, \"b\").innerHTML = \"Enter different values in the table below and press <code>Enter</code> to update this page.\";\n const table = createChildElement(root_element, \"table\");\n const table_head = createChildElement(table, \"thead\");\n const table_head_row = createChildElement(table_head, \"tr\");\n const table_body = createChildElement(table, \"tbody\");\n for (const column of columns) {\n const table_cell = createChildElement(table_head_row, \"th\");\n const heading = TABLE_CELL_HEADINGS.get(column);\n if (heading) {\n appendTextNode(table_cell, heading);\n }\n else {\n appendTextNode(table_cell, column);\n console.error(`Unknown column name: ${column}`);\n }\n }\n const rows = [];\n for (const placeholder of placeholders_to_show) {\n if (placeholder.read_only) {\n logger.debug(`auto_table: Skipping ${placeholder.name} because it is read-only`);\n continue;\n }\n const row = createChildElement(table_body, \"tr\");\n populate_auto_table_row(row, placeholder, columns, config);\n rows.push({\n \"element\": row,\n \"placeholder\": placeholder,\n });\n }\n config.input_tables.push({\n \"columns\": columns,\n \"table_element\": table,\n \"rows\": rows,\n });\n }\n // Wrap the result in a collapsible wrapper\n convert_to_dynamic_placeholder_table(config, element, root_element);\n};\nconst sort_and_remove_duplicate_placeholders = (placeholder_list) => {\n return [...new Set(placeholder_list)].sort((a, b) => a.order_index - b.order_index);\n};\nconst populate_auto_table_row = (row, placeholder, columns, config) => {\n for (const column of columns) {\n const cell = createChildElement(row, \"td\");\n if (column == \"name\") {\n appendTextNode(cell, placeholder.name);\n }\n else if (column == \"description\") {\n appendTextNode(cell, placeholder.description);\n }\n else if (column == \"value\") {\n const dynamic_placeholer = create_dynamic_placeholder_element(placeholder);\n cell.appendChild(dynamic_placeholer);\n placeholder.output_elements.push(dynamic_placeholer);\n }\n else if (column == \"input\") {\n const input = createChildElement(cell, \"input\");\n prepare_input_field(config, placeholder, input);\n }\n else if (column == \"description-or-name\") {\n const text = placeholder.description || placeholder.name;\n appendTextNode(cell, text);\n }\n else {\n console.error(`Unknown column name: ${column}`);\n }\n }\n};\nconst update_auto_table = (config, table, new_placeholder_list) => {\n // Sort them the same way they are sorted in the table -> lists are easy to compare\n new_placeholder_list = sort_and_remove_duplicate_placeholders(new_placeholder_list);\n // Step 1: remove rows that are no longer to be shown\n const rows_to_keep = [];\n for (const row of table.rows) {\n if (new_placeholder_list.includes(row.placeholder)) {\n rows_to_keep.push(row);\n }\n else {\n logger.debug(`Removed table row for ${row.placeholder.name}:`, row.element);\n row.element.remove();\n }\n }\n // Step 2: add rows that do not yet exist\n const final_rows = [];\n const reversed_current = [...rows_to_keep].reverse();\n const reversed_new = [...new_placeholder_list].reverse();\n let next_new;\n while ((next_new = reversed_new.pop())) {\n // const next_new = reversed_new.pop();\n const next_current = reversed_current.slice(-1)[0];\n if (next_current && next_current.placeholder === next_new) {\n // The row is already in the table\n reversed_current.pop(); // remove from queue to keep in sync with other queue\n final_rows.push(next_current);\n }\n else {\n const element = document.createElement(\"tr\");\n // insert at the correct position in the dom\n if (final_rows.length == 0) {\n // adds it before the first child or if it does not exist at the end (which would also be the first element :D)\n table.table_element.insertBefore(element, table.table_element.firstChild);\n }\n else {\n // insert it after the last row that was processed\n const last_node = final_rows[final_rows.length - 1].element;\n last_node.insertAdjacentElement(\"afterend\", element);\n }\n populate_auto_table_row(element, next_new, table.columns, config);\n final_rows.push({\n \"element\": element,\n \"placeholder\": next_new,\n });\n logger.debug(`Added table row for ${next_new.name}:`, element);\n }\n }\n // Store the updated row information in the original table object\n table.rows = final_rows;\n};\nexport const update_all_auto_tables = (config) => {\n logger.debug(`Updating ${config.input_tables.length} automatic input tables`);\n if (config.input_tables.length > 0) {\n const new_placeholder_list = config.dependency_graph.get_all_used_placeholders();\n for (const table of config.input_tables) {\n update_auto_table(config, table, new_placeholder_list);\n }\n }\n};\nexport const initialize_auto_tables = (config) => {\n const element_list = document.querySelectorAll(\"div.auto-input-table\");\n if (element_list.length > 0) {\n const used_placeholders = config.dependency_graph.get_all_used_placeholders().filter(x => !x.read_only);\n for (const element of element_list) {\n if (element instanceof HTMLElement) {\n const columns_str = element.getAttribute(\"data-columns\") || \"name,input\";\n const columns = columns_str.includes(\",\") ? columns_str.split(\",\") : [columns_str];\n const show_empty = element.getAttribute(\"data-hide-empty\") === null;\n generate_automatic_placeholder_table(element, columns, config, used_placeholders, show_empty);\n }\n else {\n console.warn(\"Element\", element, \"is expected to be an HTMLElement, but is not\");\n }\n }\n }\n};\nexport const initialize_placeholder_settings_divs = (config) => {\n const element_list = document.querySelectorAll(\"div.placeholder-settings-panel\");\n for (const element of element_list) {\n fill_settings_content_container(config, element, false);\n }\n};\n","import { update_all_auto_tables } from \"./auto_tables\";\nimport { logger, reload_page } from \"./debug\";\nimport { InputType } from \"./parse_settings\";\nimport { replace_dynamic_placeholder_values } from \"./replacer\";\nimport { store_checkbox_state, store_dropdown_state, store_textbox_state } from \"./state_manager\";\nimport { validate_textbox_input_field } from \"./validator\";\nexport const initialize_all_input_fields = (config) => {\n const input_list = document.querySelectorAll(\"input[data-input-for], select[data-input-for]\");\n for (const input_element of input_list) {\n const placeholder_name = input_element.getAttribute(\"data-input-for\");\n if (placeholder_name == null) {\n throw new Error(\"How can this be, the selector forces the 'data-input-for' attribute to exist\");\n }\n const placeholder = config.placeholders.get(placeholder_name);\n if (placeholder) {\n prepare_input_field(config, placeholder, input_element);\n }\n else {\n console.warn(`Unknown placeholder referenced in input element: '${placeholder_name}'`);\n input_element.classList.add(\"input-for-variable\");\n input_element.value = `ERROR_UNDEFINED_PLACEHOLDER: ${placeholder_name}`;\n }\n }\n};\nexport const prepare_input_field = (config, placeholder, input_element) => {\n input_element.classList.add(\"input-for-variable\");\n if (placeholder.type == InputType.Checkbox) {\n initialize_input_checkbox(config, placeholder, input_element);\n }\n else if (placeholder.type == InputType.Dropdown) {\n initialize_input_dropdown(config, placeholder, input_element);\n }\n else if (placeholder.type == InputType.Textbox) {\n initialize_input_textbox(config, placeholder, input_element);\n }\n else {\n console.error(`Placeholder ${placeholder.name} has unknown type '${placeholder.type}'`);\n }\n};\nconst initialize_input_checkbox = (config, placeholder, input_element) => {\n if (input_element.tagName != \"INPUT\") {\n console.warn(`Input element/tag for placeholder '${placeholder.name}' is expected to be INPUT, but is ${input_element.tagName}. Skipping`, input_element);\n return;\n }\n input_element.type = \"checkbox\";\n input_element.checked = placeholder.current_is_checked;\n if (placeholder.read_only) {\n // disable the checkbox\n input_element.disabled = true;\n }\n else {\n input_element.disabled = false;\n // Listen for state changes\n input_element.addEventListener(\"change\", () => {\n logger.debug(\"Checkbox change\", placeholder.name, \"- new value:\", input_element.checked);\n store_checkbox_state(placeholder, input_element.checked);\n placeholder.current_value = input_element.checked ? placeholder.value_checked : placeholder.value_unchecked;\n on_placeholder_change(config, placeholder);\n });\n }\n // Store this input element\n placeholder.input_elements.push(input_element);\n};\nconst initialize_input_dropdown = (config, placeholder, input_element) => {\n const new_node = document.createElement(\"select\");\n new_node.classList.add(\"placeholder-dropdown\");\n for (const option of placeholder.options) {\n const option_element = document.createElement(\"option\");\n option_element.text = option.display_name; // @TODO: allow placeholders in here\n new_node.appendChild(option_element);\n }\n // Replace input element entirely with the dropdown menu\n if (input_element.parentNode) {\n input_element.parentNode.replaceChild(new_node, input_element);\n }\n else {\n // How would we find it in the DOM if it has no parent?\n console.error(`Input element`, input_element, `for placeholder ${placeholder.name} has no parent!`);\n }\n // Select the stored option\n new_node.selectedIndex = placeholder.current_index;\n if (placeholder.read_only) {\n // disable the dropdown\n new_node.disabled = true;\n }\n else {\n new_node.disabled = false;\n // Add an event listener\n new_node.addEventListener(\"change\", () => {\n logger.debug(\"Dropdown change\", placeholder.name, \"- new index:\", new_node.selectedIndex);\n store_dropdown_state(placeholder, new_node.selectedIndex);\n placeholder.current_index = new_node.selectedIndex;\n placeholder.current_value = placeholder.options[new_node.selectedIndex].value;\n on_placeholder_change(config, placeholder);\n });\n }\n // Store this input element\n placeholder.input_elements.push(new_node);\n};\nconst initialize_input_textbox = (config, placeholder, input_element) => {\n if (input_element.tagName != \"INPUT\") {\n console.warn(`Input element/tag for placeholder '${placeholder.name}' is expected to be INPUT, but is ${input_element.tagName}. Skipping`, input_element);\n return;\n }\n // Restore the stored state\n input_element.value = placeholder.current_value;\n if (placeholder.read_only) {\n // disable the checkbox\n input_element.disabled = true;\n input_element.style.cursor = \"not-allowed\";\n }\n else {\n input_element.disabled = false;\n if (placeholder.default_value != undefined) {\n input_element.placeholder = `Default: ${placeholder.default_value}`;\n }\n else {\n input_element.placeholder = \"Dynamic default value\";\n }\n const confirm_change = () => {\n if (placeholder.current_value == input_element.value) {\n logger.debug(`Value for placeholder ${placeholder.name} was not changed`);\n }\n else {\n // Expensive actions, only perform them if the value was actually changed\n if (validate_textbox_input_field(placeholder, input_element)) {\n store_textbox_state(placeholder, input_element.value);\n placeholder.current_value = input_element.value;\n on_placeholder_change(config, placeholder);\n // The new value is applied, so it now is the same as the stored one\n input_element.classList.remove(\"value-modified\");\n }\n }\n };\n // Check if initial value is valid and initialize the tooltip\n validate_textbox_input_field(placeholder, input_element);\n // Listen for state changes\n input_element.addEventListener(\"input\", () => {\n // The text was probably modified, so we need to update the validator\n validate_textbox_input_field(placeholder, input_element);\n // Update the changed status of the placeholder\n if (input_element.value == placeholder.current_value) {\n input_element.classList.remove(\"value-modified\");\n }\n else {\n input_element.classList.add(\"value-modified\");\n }\n });\n input_element.addEventListener(\"keypress\", (event) => {\n if (event.key === \"Enter\") {\n logger.debug(\"Textbox change confirmed with Enter key for\", placeholder.name, \"- new value:\", input_element.value);\n confirm_change();\n }\n });\n input_element.addEventListener(\"keydown\", (event) => {\n // I have no idea, why Escape does not work with the keypress event (Safari on MacOS). As a work aroud, we listen to the keydown event\n if (event.key === \"Escape\") {\n logger.debug(\"Resetting input field for \", placeholder.name, \" to current placeholder value\");\n input_element.value = placeholder.current_value;\n // reset the validation state\n validate_textbox_input_field(placeholder, input_element);\n input_element.classList.remove(\"value-modified\");\n }\n });\n input_element.addEventListener(\"focusout\", () => {\n // The value may change on the fly (use changes settings), so we can not just conditionally add the event listener, but need to check each time\n if (config.settings.apply_change_on_focus_change) {\n logger.debug(\"Textbox change confirmed by changing focus\", placeholder.name, \"- new value:\", input_element.value);\n confirm_change();\n }\n });\n }\n // Store this input element\n placeholder.input_elements.push(input_element);\n};\nexport const on_placeholder_change = (config, placeholder) => {\n const affected_placeholders = config.dependency_graph.get_all_upstream(placeholder);\n let require_reload = false;\n for (const ph of affected_placeholders) {\n require_reload = require_reload || ph.reload_page_on_change;\n }\n logger.debug(`Change of ${placeholder.name} requires updates for placeholders:\\n${affected_placeholders.map(p => ` - ${p.name}\\n`).join(\"\")}\\nRequires reload: ${require_reload}`);\n if (require_reload) {\n reload_page(); // for now we just use the full reload\n }\n else {\n config.dependency_graph.on_placeholder_value_change(placeholder);\n // update auto-tables, since downstream may be changed\n update_all_auto_tables(config);\n // Update all input elements for the modified placeholder\n if (placeholder.type == InputType.Checkbox) {\n const ph = placeholder;\n for (const input_element of ph.input_elements) {\n input_element.checked = ph.current_is_checked;\n }\n }\n else if (placeholder.type == InputType.Dropdown) {\n const ph = placeholder;\n for (const input_element of ph.input_elements) {\n input_element.selectedIndex = ph.current_index;\n }\n }\n else if (placeholder.type == InputType.Textbox) {\n const ph = placeholder;\n for (const input_element of ph.input_elements) {\n input_element.value = ph.current_value;\n validate_textbox_input_field(ph, input_element);\n }\n }\n else if (placeholder.type == InputType.Computed) {\n // Computed placeholders have no editable input_elements, nothing to update here\n }\n else {\n console.warn(`Placeholder ${placeholder.name} has unexpected type '${placeholder.type}'`);\n }\n // @TODO Not needed as long as the dropdown display name is static\n // // Update input elements\n // for (const ph of affected_placeholders) {\n // // Only dropdown's input elements can depend on other placeholders (the label)\n // if (ph.type == InputType.Dropdown) {\n // for (const input of (ph as DropdownPlaceholder).input_elements) {\n // // code here\n // }\n // }\n // }\n // Update output elements\n replace_dynamic_placeholder_values(affected_placeholders);\n }\n};\n","import { logger } from \"../debug\";\nimport { on_placeholder_change } from \"../inputs\";\nimport { store_checkbox_state } from \"../state_manager\";\n// Source: https://pictogrammers.com/library/mdi/icon/checkbox-outline/\nconst CHECKED_SVG_URL = '<svg class=\"checkbox-checked\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M19,5V19H5V5H19M10,17L6,13L7.41,11.58L10,14.17L16.59,7.58L18,9\" /></svg>';\n// Source: https://pictogrammers.com/library/mdi/icon/checkbox-blank-outline/\nconst UNCHECKED_SVG_URL = '<svg class=\"checkbox-unchecked\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z\" /></svg>';\nexport const update_inline_checkbox_editor_classes = (element, placeholder) => {\n // these classes can be used to show the current state with inline placeholders\n if (placeholder.current_is_checked) {\n element.classList.add(\"checked\");\n element.classList.remove(\"unchecked\");\n }\n else {\n element.classList.add(\"unchecked\");\n element.classList.remove(\"checked\");\n }\n};\nexport const prepare_span_for_checkbox_editor = (config, input_element, placeholder) => {\n input_element.classList.add(\"placeholder-value-checkbox\");\n // There should be only one, but this prevents crashes if there are more or even none\n input_element.querySelectorAll(\".inline-editor-icon-span\").forEach(icon => { icon.innerHTML = CHECKED_SVG_URL + UNCHECKED_SVG_URL; });\n input_element.setAttribute(\"tabindex\", \"0\");\n const abort_signal_object = { signal: config.event_listener_abort_controller.signal };\n const description = placeholder.description ? `\\nDescription: ${placeholder.description}` : \"\";\n input_element.title = `Placeholder name: ${placeholder.name}${description}\\nUsage: Click to toggle the value. You can also press Enter if the placeholder is focused.`;\n const fn_change_value = () => {\n // toggle checkbox state\n const new_value = !placeholder.current_is_checked;\n placeholder.current_value = new_value ? placeholder.value_checked : placeholder.value_unchecked;\n logger.debug(\"Checkbox change\", placeholder.name, \"- new value:\", new_value);\n store_checkbox_state(placeholder, new_value);\n on_placeholder_change(config, placeholder);\n };\n input_element.addEventListener(\"click\", fn_change_value, abort_signal_object);\n input_element.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n fn_change_value();\n event.preventDefault();\n }\n }, abort_signal_object);\n update_inline_checkbox_editor_classes(input_element, placeholder);\n};\n","import { logger } from \"./debug\";\nimport { update_tooltip, validate_placeholder_value } from \"./validator\";\nimport { InputType } from \"./parse_settings\";\nimport { update_inline_checkbox_editor_classes } from \"./inline-editors/checkbox\";\n// Replace a specific placeholder and return the estimated number of occurences (underestimated, may actually be higher)\nconst static_replace = (root_element, search_regex, replacement_value) => {\n const walker = document.createTreeWalker(root_element, NodeFilter.SHOW_TEXT);\n let node;\n let count = 0;\n if (!search_regex.global) {\n console.warn(`You should set the global flag for the regex. Context: replacing '${search_regex.source}' with '${replacement_value}'`);\n }\n while ((node = walker.nextNode())) {\n if (node.nodeValue) {\n const replaced_str = node.nodeValue.replace(search_regex, replacement_value);\n if (node.nodeValue != replaced_str) {\n node.nodeValue = replaced_str;\n count++; // Of course, it might have been replaced multiple times by replaceAll. But this is just for debugging\n // and performing an accurate count would impact the performace.\n }\n }\n }\n return count;\n};\nconst escapeHTML = (text) => {\n const element = document.createElement(\"div\");\n element.appendChild(document.createTextNode(text));\n return element.innerHTML;\n};\nconst inner_html_replace = (root_element, search_regex, replacement_value) => {\n if (!search_regex.global) {\n console.warn(`You should set the global flag for the regex. Context: replacing '${search_regex.source}' with '${replacement_value}'`);\n }\n const new_value = root_element.innerHTML.replace(search_regex, replacement_value);\n // Only process this node if it or its children contain the placeholder\n if (new_value != root_element.innerHTML) {\n // First update/check all children (recursively)\n for (const child of root_element.childNodes) {\n if (child.nodeType == Node.ELEMENT_NODE) {\n let element = child;\n inner_html_replace(element, search_regex, replacement_value);\n }\n else {\n if (child.nodeValue) {\n child.nodeValue = child.nodeValue.replace(search_regex, replacement_value);\n }\n }\n }\n // If the element still contains the placeholder, then we need to replace it entirely\n const new_value_after_updating_children = root_element.innerHTML.replace(search_regex, replacement_value);\n if (new_value_after_updating_children != root_element.innerHTML) {\n root_element.innerHTML = new_value;\n }\n return 1;\n }\n else {\n return 0;\n }\n};\nexport const create_dynamic_placeholder_element = (placeholder) => {\n const span = document.createElement(\"span\");\n span.classList.add(\"placeholder-value\");\n span.dataset.placeholder = placeholder.name;\n span.textContent = placeholder.expanded_value;\n return span;\n};\nconst dynamic_replace = (root_element, search_regex, placeholder, search_for_pre_replaced) => {\n return inner_dynamic_or_editable_replace(root_element, search_regex, placeholder, search_for_pre_replaced, \"placeholder-value-static\");\n};\nconst editable_replace = (root_element, search_regex, placeholder, search_for_pre_replaced) => {\n return inner_dynamic_or_editable_replace(root_element, search_regex, placeholder, search_for_pre_replaced, \"inline-editor-requested\");\n};\nconst inner_dynamic_or_editable_replace = (root_element, search_regex, placeholder, search_for_pre_replaced, extra_class) => {\n var _a;\n const walker = document.createTreeWalker(root_element, NodeFilter.SHOW_TEXT);\n let node;\n if (!search_regex.global) {\n console.warn(`You should set the global flag for the regex. Context: replacing '${search_regex.source}' with '${placeholder.current_value}'`);\n }\n let existing_count = 0;\n if (search_for_pre_replaced) {\n const extra_class_query = extra_class ? `.${extra_class}` : \"\";\n const already_existing_wrappers = document.querySelectorAll(`${extra_class_query}.placeholder-value[data-placeholder]`);\n for (const wrapper of already_existing_wrappers) {\n if (wrapper.getAttribute(\"data-placeholder\") === placeholder.name) {\n existing_count++;\n }\n }\n if (existing_count > 0) {\n const query_type = extra_class ? \"editable\" : \"dynamic\";\n logger.debug(`${existing_count} ${query_type} placeholder elements already exist for placeholder ${placeholder.name}`);\n }\n }\n const nodes_to_modify = [];\n while ((node = walker.nextNode())) {\n if (node.nodeValue) {\n if (node.nodeValue.match(search_regex)) {\n // Do not modify in-place while iterating over the DOM\n nodes_to_modify.push(node);\n }\n }\n }\n if (nodes_to_modify) {\n // Do not put in the value yet, otherwise it may be replaced by other placeholders\n const extra_class_insert = extra_class ? ` ${extra_class}` : \"\";\n const replacement_value = `<span class=\"placeholder-value${extra_class_insert}\" data-placeholder=\"${escapeHTML(placeholder.name)}\">TEMPORARY PLACEHOLDER</span>`;\n for (const node of nodes_to_modify) {\n if (node.nodeValue) {\n const replaced_str = escapeHTML(node.nodeValue).replace(search_regex, replacement_value);\n const new_node = document.createElement(\"span\");\n new_node.innerHTML = replaced_str;\n (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.replaceChild(new_node, node);\n }\n }\n }\n return nodes_to_modify.length + existing_count;\n};\nconst do_dynamic_replace = (root_element, placeholder) => {\n const count = dynamic_replace(root_element, placeholder.regex_dynamic, placeholder, true);\n if (count > 0) {\n logger.debug(`Replaced ${placeholder.name} via dynamic method at least ${count} time(s)`);\n placeholder.count_on_page += count;\n }\n};\nconst do_editable_replace = (root_element, placeholder) => {\n const count = editable_replace(root_element, placeholder.regex_editable, placeholder, true);\n if (count > 0) {\n logger.debug(`Replaced ${placeholder.name} via editable method at least ${count} time(s)`);\n placeholder.count_on_page += count;\n }\n};\nconst do_normal_replace = (root_element, placeholder, config) => {\n const count = inner_do_normal_replace(root_element, placeholder, config);\n if (count > 0) {\n logger.debug(`Replaced ${placeholder.name} via normal (${config.settings.normal_is_alias_for}) method at least ${count} time(s)`);\n placeholder.count_on_page += count;\n }\n};\nconst inner_do_normal_replace = (root_element, placeholder, config) => {\n // Replace with the actual method that normal maps to and return the count\n switch (config.settings.normal_is_alias_for) {\n case \"dynamic\":\n return dynamic_replace(root_element, placeholder.regex_normal, placeholder, false);\n case \"editable\":\n return editable_replace(root_element, placeholder.regex_normal, placeholder, false);\n case \"html\":\n // User supplied input, HTML escape it before we inject it in the page\n const replacement_value = escapeHTML(placeholder.expanded_value);\n return inner_html_replace(root_element, placeholder.regex_html, replacement_value);\n case \"static\":\n return static_replace(root_element, placeholder.regex_static, placeholder.expanded_value);\n default:\n console.warn(`Unknown replace type mapped in 'settings.normal_is_alias_for': ${config.settings.normal_is_alias_for}. Skipping replacing normal placeholders`);\n return 0;\n }\n};\nconst do_static_replace = (root_element, placeholder) => {\n const count = static_replace(root_element, placeholder.regex_static, placeholder.expanded_value);\n if (count > 0) {\n logger.debug(`Replaced ${placeholder.name} via static method at least ${count} time(s)`);\n placeholder.count_on_page += count;\n placeholder.reload_page_on_change = true;\n }\n};\nconst do_html_replace = (root_element, placeholder) => {\n const count = inner_html_replace(root_element, placeholder.regex_html, placeholder.expanded_value);\n if (count > 0) {\n logger.debug(`Replaced ${placeholder.name} via innerHTML method at least ${count} time(s)`);\n placeholder.count_on_page += count;\n placeholder.reload_page_on_change = true;\n }\n};\n// Replace all placeholders in the given order and return which placeholders actually were actually found in the page\nexport const replace_placeholders_in_subtree = (root_element, config) => {\n for (const placeholder of config.placeholders.values()) {\n do_dynamic_replace(root_element, placeholder);\n do_editable_replace(root_element, placeholder);\n do_normal_replace(root_element, placeholder, config);\n do_static_replace(root_element, placeholder);\n if (placeholder.allow_inner_html) {\n do_html_replace(root_element, placeholder);\n }\n }\n find_dynamic_placeholder_wrappers(config);\n replace_dynamic_placeholder_values([...config.placeholders.values()]);\n};\nexport const safe_replace_multiple_placeholders_in_string = (text, placeholder_list) => {\n // Optimize for trivial cases\n if (placeholder_list.length == 0) {\n return text;\n }\n else if (placeholder_list.length == 1) {\n // We can directly replace it without any problems\n const placeholder = placeholder_list[0];\n return replace_placeholder_in_string_with(text, placeholder, placeholder.expanded_value);\n }\n else {\n // If we just replace the values directly in a for loop, we get bugs, when the value of one placeholder contains another placeholder that is also replaced, but later\n // To circumvent this, we replace placeholders with randomized other placeholders and then replace these with the actual values\n const unique = `${Date.now()}_${Math.random()}`;\n for (const placeholder of placeholder_list) {\n text = replace_placeholder_in_string_with(text, placeholder, `x${placeholder.name}#${unique}x`);\n }\n for (const placeholder of placeholder_list) {\n const regex = new RegExp(`x${placeholder.name}#${unique}x`, \"g\");\n text = text.replace(regex, placeholder.expanded_value);\n }\n return text;\n }\n};\nconst replace_placeholder_in_string_with = (text, placeholder, value) => {\n // This funtion will perform replacements, but will ignore the replacement type (all will be simple/direct replace)\n return text.replace(placeholder.regex_dynamic, value)\n .replace(placeholder.regex_editable, value)\n .replace(placeholder.regex_html, value)\n .replace(placeholder.regex_normal, value)\n .replace(placeholder.regex_static, value);\n};\nexport const replace_dynamic_placeholder_values = (placeholder_list) => {\n for (const placeholder of placeholder_list) {\n if (placeholder.output_elements.length > 0) {\n for (const element of placeholder.output_elements) {\n change_text_keep_other_children(element, placeholder.expanded_value);\n }\n if (placeholder.type == InputType.Textbox) {\n // could have inline editor, and we need to correctly set their validation states.\n // Perform validation only once and reuse it for all elements\n //@TODO: Check current_value or expanded_value?\n const result = validate_placeholder_value(placeholder, placeholder.expanded_value);\n for (const element of placeholder.output_elements) {\n if (element.classList.contains(\"placeholder-value-editable\")) {\n // This element is an inline editor\n update_tooltip(element, result);\n }\n }\n }\n else if (placeholder.type == InputType.Checkbox) {\n for (const element of placeholder.output_elements) {\n if (element.classList.contains(\"placeholder-value-checkbox\")) {\n // This element is an inline editor\n update_inline_checkbox_editor_classes(element, placeholder);\n }\n }\n }\n }\n }\n};\nexport const change_text_keep_other_children = (element, new_text) => {\n if (new_text) {\n element.classList.remove(\"value-empty\");\n }\n else {\n element.classList.add(\"value-empty\");\n }\n // If it exists, replace the first text node\n for (const child of element.childNodes) {\n if (child.nodeType === Node.TEXT_NODE) {\n child.textContent = new_text;\n return;\n }\n }\n // If no text node exists, add a text node to the beginning\n element.insertAdjacentText(\"afterbegin\", new_text);\n};\nconst find_dynamic_placeholder_wrappers = (config) => {\n const output_list = document.querySelectorAll(\".placeholder-value[data-placeholder]\");\n for (const element of output_list) {\n const placeholder_name = element.getAttribute(\"data-placeholder\");\n if (placeholder_name) {\n const placeholder = config.placeholders.get(placeholder_name);\n if (placeholder) {\n placeholder.output_elements.push(element);\n }\n else {\n console.warn(`No placeholder named '${placeholder_name}', that is referenced by element:`, element);\n }\n }\n else {\n console.warn(`Element has empty/no attribute 'data-placeholder':`, element);\n }\n }\n};\n","import { logger } from \"./debug\";\nimport { InputType } from \"./parse_settings\";\nimport { safe_replace_multiple_placeholders_in_string } from \"./replacer\";\nimport { clear_state } from \"./state_manager\";\n// Should be a directed acyclical graph\nexport class DependencyGraph {\n constructor(placeholders) {\n this.placeholders = placeholders;\n this.nodes = new Map();\n this.reset();\n }\n reset() {\n this.nodes.clear();\n for (const placeholder of this.placeholders.values()) {\n this.nodes.set(placeholder.name, new GraphNode(placeholder));\n }\n // Needs to be in different loops to ensure that all nodes have been created first\n for (const placeholder of this.placeholders.values()) {\n try {\n this.on_placeholder_value_change(placeholder);\n }\n catch (e) {\n console.error(\"Error while building dependency graph\", e);\n console.warn(\"Placeholder values may be inconsistent. Clearing your localStorage should fix this problem.\");\n if (confirm(\"We detected a problem with your placeholder values. Resetting them to the defaults should fix this. Should we reset your placeholders?\")) {\n clear_state();\n }\n }\n }\n // Make sure that all expanded values are calculated\n // We take every node with no downlinks (bottom of the graph) and do a recursive recalculation (upwards).\n // Not super efficient, but simple to implement\n for (const node of this.nodes.values()) {\n if (node.downlinks.length == 0) {\n node.recalculate_expanded_value(true);\n }\n }\n }\n debug_print_representation() {\n let text = \"Dependency graph nodes (DEBUG view):\";\n for (const node of this.nodes.values()) {\n const dependencies = node.downlinks.map(n => n.placeholder.name).join(\", \");\n if (dependencies.length == 0) {\n text += `\\n${node.placeholder.name} (${node.placeholder.expanded_value}) has no dependencies`;\n }\n else {\n text += `\\n${node.placeholder.name} (${node.placeholder.expanded_value}) depends on ${dependencies}`;\n }\n }\n logger.debug(text);\n }\n unmark_everything() {\n for (const node of this.nodes.values()) {\n node.marked = false;\n }\n }\n get_node(placeholder) {\n const node = this.nodes.get(placeholder.name);\n if (node == undefined) {\n throw new Error(`Placeholder ${placeholder.name} is not part of the dependency graph`);\n }\n else {\n return node;\n }\n }\n on_placeholder_value_change(placeholder) {\n const node = this.get_node(placeholder);\n this.update_placeholder_downlinks(placeholder);\n if (this.has_loop()) {\n // Emergency measure: ignore any placeholders in this value. This should fix the loop\n placeholder.expanded_value = placeholder.current_value;\n node.downlinks = [];\n // Also raise an exception to inform the user\n throw new Error(`Placeholder ${placeholder.name} was part of a loop and has temporarily been made non-recursive`);\n }\n else {\n node.recalculate_expanded_value(true);\n }\n }\n get_all_marked() {\n const marked = [];\n for (const node of this.nodes.values()) {\n if (node.marked) {\n marked.push(node.placeholder);\n }\n }\n return marked;\n }\n get_all_upstream(placeholder) {\n this.unmark_everything();\n const node = this.get_node(placeholder);\n node.recursive_mark_upstream();\n return this.get_all_marked();\n }\n update_placeholder_downlinks(placeholder) {\n // Step 1: remove all old downlinks\n const node = this.get_node(placeholder);\n for (const old_downlink of node.downlinks) {\n old_downlink.remove_uplink(node);\n }\n node.downlinks = [];\n // Step 2: set new downlinks based on placeholder type\n if (placeholder.type === InputType.Computed) {\n // Computed placeholders have explicit dependencies declared in computed_depends_on\n const comp = placeholder;\n for (const dep_name of comp.computed_depends_on) {\n const dep_node = this.nodes.get(dep_name);\n if (dep_node) {\n node.downlinks.push(dep_node);\n dep_node.uplinks.push(node);\n }\n else {\n console.error(`Computed placeholder '${comp.name}': dependency '${dep_name}' not found in graph`);\n }\n }\n }\n else if (placeholder.allow_nested) {\n // Nested placeholders: scan the value string for references to other placeholders\n for (const other_node of this.nodes.values()) {\n // No placeholder should directly be able to contain itself -> ignoring this case.\n // This should lead to the placeholder's name appearing in it's text, which was probably intended\n if (other_node != node) {\n if (string_contains_placeholder(placeholder.current_value, other_node.placeholder)) {\n // This placeholder's value contains a reference to the other node's placeholder\n // -> This node depends on the other node\n node.downlinks.push(other_node);\n other_node.uplinks.push(node);\n }\n }\n }\n }\n else {\n logger.debug(`${placeholder.name} has no dependencies (not nested, not computed)`);\n }\n }\n get_all_used_placeholders() {\n // Also includes all placeholders used by the placeholders that were included\n this.unmark_everything();\n // Mark all used placeholders and their downstream nodes\n for (const node of this.nodes.values()) {\n if (node.placeholder.count_on_page > 0) {\n node.recursive_mark_downstream();\n }\n }\n return this.get_all_marked();\n }\n has_loop() {\n // General algorithm: https://www.geeksforgeeks.org/detect-cycle-in-a-graph/\n this.unmark_everything();\n for (const node of this.nodes.values()) {\n // Make sure that we check every single node (we likely have multiple graphs that are not connected)\n if (!node.marked) {\n if (this._has_loop([], node)) {\n return true;\n }\n }\n }\n return false;\n }\n _has_loop(back_stack, current_node) {\n const new_back_stack = [...back_stack, current_node];\n const index = back_stack.indexOf(current_node);\n if (index != -1) {\n let message = \"Dependency cycle in placeholders detected:\";\n for (let i = index; i < new_back_stack.length; i++) {\n const placeholder = new_back_stack[i].placeholder;\n message += `\\n$ -> ${placeholder.name}: ${placeholder.current_value}`;\n }\n console.warn(message);\n return true;\n }\n else if (!current_node.marked) {\n // No cycle found yet, scan all children that are not yet marked\n current_node.marked = true;\n for (const child of current_node.downlinks) {\n if (this._has_loop(new_back_stack, child)) {\n return true;\n }\n }\n return false;\n }\n else {\n // Already checked, so no need to start recursive scans\n return false;\n }\n }\n}\nconst string_contains_placeholder = (string_to_test, placeholder_to_find) => {\n return placeholder_to_find.regex_dynamic.test(string_to_test) ||\n placeholder_to_find.regex_editable.test(string_to_test) ||\n placeholder_to_find.regex_html.test(string_to_test) ||\n placeholder_to_find.regex_normal.test(string_to_test) ||\n placeholder_to_find.regex_static.test(string_to_test);\n};\nclass GraphNode {\n constructor(placeholder) {\n // These other nodes depend on this node\n this.uplinks = [];\n // This are the nodes this node depends on\n this.downlinks = [];\n // State used during operations to see if this node was already visited/processed\n this.marked = false;\n this.placeholder = placeholder;\n }\n remove_uplink(node) {\n this.uplinks = this.uplinks.filter(x => x != node);\n }\n recalculate_expanded_value(recursive) {\n if (this.placeholder.type === InputType.Computed) {\n // Computed placeholders: re-evaluate the function using dependency values from downlinks\n const comp = this.placeholder;\n const args = {};\n for (const downlink of this.downlinks) {\n args[downlink.placeholder.name] = downlink.placeholder.current_value;\n }\n try {\n const result = comp.computed_function(args);\n comp.current_value = result;\n comp.expanded_value = result;\n logger.debug(`Computed placeholder '${comp.name}' evaluated to: '${result}'`);\n }\n catch (error) {\n console.error(`Error evaluating computed placeholder '${comp.name}':`, error);\n comp.current_value = \"COMPUTED_ERROR\";\n comp.expanded_value = \"COMPUTED_ERROR\";\n }\n }\n else {\n // Regular placeholders: expand nested placeholder references via string substitution\n let expanded_value = this.placeholder.current_value;\n if (this.placeholder.allow_nested) {\n expanded_value = safe_replace_multiple_placeholders_in_string(expanded_value, this.downlinks.map(n => n.placeholder));\n }\n this.placeholder.expanded_value = expanded_value;\n }\n if (recursive) {\n // Recalculate all uplink nodes in recursive too\n for (const uplink_node of this.uplinks) {\n uplink_node.recalculate_expanded_value(recursive);\n }\n }\n }\n recursive_mark_upstream() {\n this.marked = true;\n for (const node of this.uplinks) {\n node.recursive_mark_upstream();\n }\n }\n recursive_mark_downstream() {\n this.marked = true;\n for (const node of this.downlinks) {\n node.recursive_mark_downstream();\n }\n }\n}\n","import { load_checkbox_state, load_dropdown_state, load_textbox_state, load_boolean_setting, load_multiple_choice_setting } from \"./state_manager\";\nimport { parse_validator } from \"./validator\";\nimport { DependencyGraph } from \"./dependency_graph\";\nexport const VALID_INLINE_EDITOR_STYLES = [\"simple\", \"icons\", \"custom\"];\n// It parses random unspecified data, so any should be fine\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const assert_field_type = (name, expected_type_str, parent_object) => {\n const value = parent_object[name];\n const actual_type_str = typeof (value);\n if (actual_type_str != expected_type_str) {\n throw new Error(`Type mismatch: ${name} should be ${expected_type_str}, but is ${actual_type_str}.\\nProblematic object: ${JSON.stringify(parent_object)}`);\n }\n else {\n return value;\n }\n};\n// These functions are here to make sure, that I the type checker can properly work (since they have a specific return type)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const get_string_field = (name, parent_object) => {\n return assert_field_type(name, \"string\", parent_object);\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const get_boolean_field = (name, parent_object) => {\n return assert_field_type(name, \"boolean\", parent_object);\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst get_number_field = (name, parent_object) => {\n return assert_field_type(name, \"number\", parent_object);\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const get_array_field = (name, element_type, parent_object) => {\n const array = parent_object[name];\n if (Array.isArray(array)) {\n for (const [index, entry] of array.entries()) {\n const actual_type_str = typeof (entry);\n if (actual_type_str != element_type) {\n const msg = `Type mismatch: ${name}'s ${index + 1}th element should be ${element_type}, but is ${actual_type_str}.\\nProblematic object: ${JSON.stringify(parent_object)}`;\n throw new Error(msg);\n }\n }\n return array;\n }\n else {\n throw new Error(`Type mismatch: ${name} should be an array, but is not.\\nProblematic object: ${JSON.stringify(parent_object)}`);\n }\n};\nexport var ReplaceType;\n(function (ReplaceType) {\n // Excluding normal, since it is just an alias for one of the other types\n ReplaceType[\"Editable\"] = \"editable\";\n})(ReplaceType || (ReplaceType = {}));\nexport var InputType;\n(function (InputType) {\n InputType[\"Textbox\"] = \"TEXTBOX\";\n InputType[\"Checkbox\"] = \"CHECKBOX\";\n InputType[\"Dropdown\"] = \"DROPDOWN\";\n InputType[\"Computed\"] = \"COMPUTED\";\n})(InputType || (InputType = {}));\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const parse_config = (data) => {\n const placeholder_map = new Map();\n const textboxes = new Map();\n const checkboxes = new Map();\n const dropdowns = new Map();\n const validator_map = new Map();\n const validator_data_list = get_array_field(\"validators\", \"object\", data);\n for (const validator_data of validator_data_list) {\n const validator = parse_validator(validator_data);\n if (validator_map.has(validator.id)) {\n throw new Error(`Multiple validators with id '${validator.id}'`);\n }\n else {\n validator_map.set(validator.id, validator);\n }\n }\n const settings_data = assert_field_type(\"settings\", \"object\", data);\n const settings = parse_settings(settings_data);\n const placeholder_data = get_array_field(\"placeholder_list\", \"object\", data);\n for (let i = 0; i < placeholder_data.length; i++) {\n const placeholder = parse_any_placeholder(placeholder_data[i], validator_map, settings, i);\n // Add the placeholder to the correct lists\n placeholder_map.set(placeholder.name, placeholder);\n if (placeholder.type == InputType.Textbox) {\n textboxes.set(placeholder.name, placeholder);\n }\n else if (placeholder.type == InputType.Checkbox) {\n checkboxes.set(placeholder.name, placeholder);\n }\n else if (placeholder.type == InputType.Dropdown) {\n dropdowns.set(placeholder.name, placeholder);\n }\n else if (placeholder.type == InputType.Computed) {\n // Computed placeholders are handled by the DependencyGraph:\n // their dependencies are registered as downlinks, and their values\n // are evaluated during the graph's leaf-to-root recalculation.\n }\n else {\n console.warn(\"Unknown placeholder type:\", placeholder.type);\n }\n }\n // The DependencyGraph handles all dependency tracking and value computation,\n // including computed placeholders (their functions are evaluated during\n // the graph's recursive recalculation from leaves upward).\n const graph = new DependencyGraph(placeholder_map);\n return {\n \"placeholders\": placeholder_map,\n \"textboxes\": textboxes,\n \"checkboxes\": checkboxes,\n \"dropdowns\": dropdowns,\n \"settings\": settings,\n \"dependency_graph\": graph,\n \"input_tables\": [],\n \"event_listener_abort_controller\": new AbortController(),\n };\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst parse_settings = (data) => {\n const apply_change_on_focus_change_default = get_boolean_field(\"apply_change_on_focus_change\", data);\n const debug_default = get_boolean_field(\"debug\", data);\n const expand_auto_tables_default = get_boolean_field(\"expand_auto_tables\", data);\n const inline_editors = get_boolean_field(\"inline_editors\", data);\n const default_inline_editor_style = get_string_field(\"inline_editor_style\", data);\n return {\n \"apply_change_on_focus_change\": load_boolean_setting(\"apply_change_on_focus_change\", apply_change_on_focus_change_default),\n \"debug\": load_boolean_setting(\"debug\", debug_default),\n \"delay_millis\": get_number_field(\"delay_millis\", data),\n \"expand_auto_tables\": load_boolean_setting(\"expand_auto_tables\", expand_auto_tables_default),\n \"highlight_placeholders\": load_boolean_setting(\"highlight_placeholders\", false),\n \"inline_editors\": load_boolean_setting(\"inline_editors\", inline_editors),\n \"inline_editor_style\": load_multiple_choice_setting(\"inline_editor_style\", default_inline_editor_style, VALID_INLINE_EDITOR_STYLES),\n \"normal_is_alias_for\": get_string_field(\"normal_is_alias_for\", data),\n // How normal placeholders are marked\n \"normal_prefix\": get_string_field(\"normal_prefix\", data),\n \"normal_suffix\": get_string_field(\"normal_suffix\", data),\n // How editable placeholders are marked\n \"editable_prefix\": get_string_field(\"editable_prefix\", data),\n \"editable_suffix\": get_string_field(\"editable_suffix\", data),\n // How placeholders using the innerHTML method are marked\n \"html_prefix_optional\": get_string_field(\"html_prefix_optional\", data),\n \"html_prefix\": get_string_field(\"html_prefix\", data),\n \"html_suffix\": get_string_field(\"html_suffix\", data),\n // How placeholders using the direct/static replacement methodare marked\n \"static_prefix\": get_string_field(\"static_prefix\", data),\n \"static_suffix\": get_string_field(\"static_suffix\", data),\n // How placeholders using the dynamic replacement methodare marked\n \"dynamic_prefix\": get_string_field(\"dynamic_prefix\", data),\n \"dynamic_suffix\": get_string_field(\"dynamic_suffix\", data),\n };\n};\nconst escapeRegExp = (regex_pattern) => {\n // @SOURCE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping\n return regex_pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst parse_any_placeholder = (data, validator_map, settings, index) => {\n const type = get_string_field(\"type\", data);\n // Parse fields that are shared between all placeholders\n const name = get_string_field(\"name\", data);\n const parsed = {\n \"name\": name,\n \"order_index\": index,\n // The regexes for the different replace methods. Stored here so that I only need to compile them once\n // @TODO: editable\n \"regex_dynamic\": RegExp(escapeRegExp(settings.dynamic_prefix) + name + escapeRegExp(settings.dynamic_suffix), \"g\"),\n \"regex_editable\": RegExp(escapeRegExp(settings.editable_prefix) + name + escapeRegExp(settings.editable_suffix), \"g\"),\n \"regex_html\": RegExp(\"(:?\" + escapeRegExp(settings.html_prefix_optional) + \")?\" + escapeRegExp(settings.html_prefix) + name + escapeRegExp(settings.html_suffix), \"g\"),\n \"regex_normal\": RegExp(escapeRegExp(settings.normal_prefix) + name + escapeRegExp(settings.normal_suffix), \"g\"),\n \"regex_static\": RegExp(escapeRegExp(settings.static_prefix) + name + escapeRegExp(settings.static_suffix), \"g\"),\n //\n \"default_tooltip\": \"\", // have it empty by default, the different finish_parse_<type> functions will overwrite it if needed\n \"description\": get_string_field(\"description\", data),\n \"read_only\": get_boolean_field(\"read_only\", data),\n \"allow_inner_html\": get_boolean_field(\"allow_inner_html\", data),\n \"allow_nested\": get_boolean_field(\"allow_nested\", data),\n \"current_value\": \"UNINITIALIZED\", // should be replaced by the 'load_*_state' funcion, that is called later on in this function\n \"expanded_value\": \"UNINITIALIZED\", // should be replaced by the 'load_*_state' funcion, that is called later on in this function\n \"count_on_page\": 0, // Will be incremented by the replace functions\n \"reload_page_on_change\": false, // May be changed by the replace function\n \"output_elements\": [], // Will be set, when the page is searched\n };\n // Parse the type specific attributes\n if (type === \"textbox\") {\n const placeholder = finish_parse_textbox(parsed, data, validator_map);\n load_textbox_state(placeholder);\n return placeholder;\n }\n else if (type == \"checkbox\") {\n const placeholder = finish_parse_checkbox(parsed, data);\n load_checkbox_state(placeholder);\n return placeholder;\n }\n else if (type == \"dropdown\") {\n const placeholder = finish_parse_dropdown(parsed, data);\n load_dropdown_state(placeholder);\n return placeholder;\n }\n else if (type == \"computed\") {\n // Computed state is initialized by the DependencyGraph (leaf-to-root recalculation)\n return finish_parse_computed(parsed, data);\n }\n else {\n throw new Error(`Unsupported placeholder type '${type}'`);\n }\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst finish_parse_textbox = (parsed, data, validator_map) => {\n let default_function, default_value;\n if (data[\"default_value\"] != undefined) {\n default_value = get_string_field(\"default_value\", data);\n }\n else {\n const default_js_code = get_string_field(\"default_function\", data);\n default_function = () => {\n // Wrap the function, so that we can ensure that errors are properly handled\n try {\n const compiled_function = new Function(default_js_code);\n const result = compiled_function();\n if (typeof (result) != \"string\") {\n throw new Error(`Custom function '${default_js_code}' should return a string, but it returned a ${typeof (result)}: ${result}`);\n }\n else {\n return result;\n }\n }\n catch (error) {\n throw new Error(`Failed to evaluate default_function '${default_js_code}' of placeholder ${parsed.name}: ${error}`);\n }\n };\n }\n const validator_names = get_array_field(\"validators\", \"string\", data);\n const validator_list = [];\n for (const name of validator_names) {\n const validator = validator_map.get(name);\n if (validator) {\n validator_list.push(validator);\n }\n else {\n const known_validators = Array.from(validator_map.keys()).join(\", \");\n throw new Error(`No validator with id '${name}' was found. Known validators are ${known_validators}`);\n }\n }\n const description = parsed.description ? `\\nDescription: ${parsed.description}` : \"\";\n const default_value_line = default_value ? `\\nDefault value: ${default_value}` : `\\nDefault value generated by function`;\n const validation_ok_tooltip = `Placeholder name: ${parsed.name}${description}${default_value_line}\\nUsage: Click to edit the value. Leaving the text field or pressing enter will store the new value, pressing Escape will revert current changes. While editing the field, the tooltip will show warnings/errors if your value is not what is expected`;\n return Object.assign(Object.assign({}, parsed), { \"default_tooltip\": validation_ok_tooltip, \"default_function\": default_function, \"default_value\": default_value, \"input_elements\": [], \"type\": InputType.Textbox, \"validators\": validator_list });\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst finish_parse_checkbox = (parsed, data) => {\n return Object.assign(Object.assign({}, parsed), { \"checked_by_default\": get_boolean_field(\"checked_by_default\", data), \"current_is_checked\": false, \"input_elements\": [], \"value_checked\": get_string_field(\"value_checked\", data), \"value_unchecked\": get_string_field(\"value_unchecked\", data), \"type\": InputType.Checkbox });\n};\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst finish_parse_dropdown = (parsed, data) => {\n const raw_options = get_array_field(\"options\", \"object\", data);\n const options = [];\n for (const option of raw_options) {\n options.push({\n display_name: get_string_field(\"display_name\", option),\n value: get_string_field(\"value\", option),\n });\n }\n const default_index = get_number_field(\"default_index\", data);\n if (default_index < 0) {\n throw new Error(`Invalid value: \"default_index\" should not be negative, but is ${default_index}.\\nProblematic object: ${JSON.stringify(data)}`);\n }\n else if (default_index >= options.length) {\n throw new Error(`Invalid value: \"default_index\" should be smaller than the number of options (${options.length}), but is ${default_index}.\\nProblematic object: ${JSON.stringify(data)}`);\n }\n const description = parsed.description ? `\\nDescription: ${parsed.description}` : \"\";\n let default_tooltip = `Placeholder name: ${parsed.name}${description}\\nDefault option: ${options[default_index].value}\\nUsage: (left-)click to cycle forward through the values, right-click to cycle through backwards. You can also use the Enter, Up, and Down keys if the placeholder is selected.\\nPossible values:`;\n for (const option of options) {\n default_tooltip += `\\n- ${option.value}`;\n }\n return Object.assign(Object.assign({}, parsed), { \"default_tooltip\": default_tooltip, \"current_index\": 0, \"default_index\": default_index, \"input_elements\": [], \"options\": options, \"type\": InputType.Dropdown });\n};\nconst finish_parse_computed = (parsed, data) => {\n const computed_depends_on = get_array_field(\"computed_depends_on\", \"string\", data);\n const function_body = get_string_field(\"computed_function\", data);\n // Build the compiled function: it receives an object with dependency values and returns a string\n const compiled_function = (args) => {\n try {\n // Build parameter list and values in the same order as computed_depends_on\n const param_names = computed_depends_on;\n const param_values = computed_depends_on.map(dep => { var _a; return (_a = args[dep]) !== null && _a !== void 0 ? _a : \"\"; });\n const fn = new Function(...param_names, function_body);\n const result = fn(...param_values);\n if (typeof result !== \"string\") {\n throw new Error(`Computed function for '${parsed.name}' must return a string, but returned ${typeof result}: ${result}`);\n }\n return result;\n }\n catch (error) {\n throw new Error(`Failed to evaluate computed_function for placeholder '${parsed.name}': ${error}`);\n }\n };\n const description = parsed.description ? `\\nDescription: ${parsed.description}` : \"\";\n const default_tooltip = `Placeholder name: ${parsed.name}${description}\\nThis is a computed (read-only) placeholder. Its value is automatically derived from: ${computed_depends_on.join(\", \")}`;\n return Object.assign(Object.assign({}, parsed), { \"default_tooltip\": default_tooltip, \"computed_depends_on\": computed_depends_on, \"computed_function\": compiled_function, \"input_elements\": [], \"type\": InputType.Computed, \n // current_value and expanded_value will be set by DependencyGraph during initialization\n \"current_value\": \"\", \"expanded_value\": \"\" });\n};\n","import { parse_config } from \"./parse_settings\";\nimport { init_logging, logger } from \"./debug\";\nimport { replace_placeholders_in_subtree } from \"./replacer\";\nimport { initialize_all_input_fields } from \"./inputs\";\nimport { export_api_functions } from \"./api\";\nimport { initialize_auto_tables, initialize_placeholder_settings_divs } from \"./auto_tables\";\nimport { register_inline_value_editors } from \"./inline-editors/register\";\nexport const main = () => {\n // This is the easiest way to read the attribute from the window. It should be set by \"placeholder-data.js\"\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const config = parse_config(window.PlaceholderPluginConfigJson);\n init_logging(config.settings.debug);\n logger.info(\"PluginConfig\", config);\n export_api_functions(config);\n const delay_millis = config.settings.delay_millis;\n // Then do the placeholder replacing at the user-specified time.\n // This is the simplest way to read an non-standard attribute from the window object without TypeScript complaining, so I keep it\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const document_listener = window.document$;\n if (document_listener) {\n // This means we are using MkDocs, so we hook into it's init system\n // SEE https://github.com/squidfunk/mkdocs-material/discussions/5925\n document_listener.subscribe(() => {\n if (delay_millis > 0) {\n setTimeout(() => do_plugin_stuff(config), delay_millis);\n }\n else {\n do_plugin_stuff(config);\n }\n });\n }\n else {\n // Use the normal HTML5 way of waiting for the execution (window.onload)\n if (delay_millis < 0) {\n // For values smaller than 0, immediately do the replacements\n do_plugin_stuff(config);\n }\n else if (delay_millis == 0) {\n // Replace placeholders as soon as the page finished loading\n window.addEventListener(\"load\", () => do_plugin_stuff(config));\n }\n else {\n // Wait the amount of millis specified by the user\n window.addEventListener(\"load\", () => {\n setTimeout(() => do_plugin_stuff(config), delay_millis);\n });\n }\n }\n};\nconst do_plugin_stuff = (config) => {\n logger.info(\"Called do_plugin_stuff (function for parsing and modifying the page)\");\n // Clear current state in case we are called multiple times (instant loading)\n // config.dependency_graph.reset();\n config.placeholders.forEach((placeholder, _key, _map) => {\n placeholder.count_on_page = 0;\n placeholder.input_elements = [];\n });\n replace_placeholders_in_subtree(document.body, config);\n config.dependency_graph.debug_print_representation();\n initialize_all_input_fields(config);\n initialize_auto_tables(config);\n initialize_placeholder_settings_divs(config);\n if (config.settings.inline_editors) {\n register_inline_value_editors(config);\n }\n document.body.classList.add(\"placeholder-plugin-init-done\");\n};\n","import { debug_disable_reload } from \"./debug\";\nexport const export_api_functions = (config) => {\n // This is the simplest way to assign something to the window object without TypeScript complaining, so I keep it\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n window.PlaceholderPlugin = {\n \"version\": \"0.5.2-dev1\",\n \"settings\": config.settings,\n \"placeholders\": config.placeholders,\n \"debug_disable_reload\": debug_disable_reload,\n \"debug_print_dependency_graph\": () => config.dependency_graph.debug_print_representation(),\n };\n};\n","import { main } from \"./main\";\n// If the data is loaded via another script, make it work in any order\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nif (window.PlaceholderPluginConfigJson) {\n main();\n}\nelse {\n document.addEventListener(\"PlaceholderPluginConfigJson\", main);\n}\n"],"names":["timestamp","Date","toISOString","slice","is_reload_enabled","internal_log","args","console","log","apply","internal_info","info","internal_debug","debug","noop","_args","reload_page","window","location","reload","noop_logger","logger","debug_disable_reload","ValidatorSeverity","PlaceholderValidatity","parse_validator","data","rules","get_array_field","length","Error","JSON","stringify","id","get_string_field","map","x","parse_rule","is_valid_value","validator","value","rule","is_match_function","should_match","severity","is_valid_value_for_placeholder","placeholder","validators","validate_value","warnings","errors","push","display_name","error_message","Warning","warn","validate_placeholder_value","result_list","has_no_error","result","placeholder_is_good","placeholder_is_warning","placeholder_is_error","NoValidator","join","lines","message","v","Good","validator_id","severity_str","regex","compiled_regex","RegExp","test","match_function_body","match_function","Function","error","get_boolean_field","update_tooltip","input_field","validation_result","classList","remove","rating","add","title","validate_textbox_input_field","name","validate_textbox_editable_span","innerText","STORAGE_PREFIX","SETTINGS_PREFIX","store_value","localStorage","setItem","load_value","getItem","load_boolean_setting","default_value","stored","load_multiple_choice_setting","allowed_values","includes","store_checkbox_state","new_is_checked","current_is_checked","current_value","value_checked","value_unchecked","clear_state","clear_by_prefix","clear_settings","prefix","i","key","startsWith","removeItem","is_valid_index","index","item","options","undefined","store_dropdown_state","new_index","current_index","store_textbox_state","new_value","is_validation_ok","prepare_span_for_dropdown_editor","config","input_element","querySelectorAll","forEach","icon","innerHTML","setAttribute","abort_signal_object","signal","event_listener_abort_controller","description","tooltip","default_index","option","modify_index_by","count","on_placeholder_change","addEventListener","event","preventDefault","stopPropagation","prepare_span_for_textbox_editor","tabIndex","spellcheck","translate","autocapitalize","confirm_change","default_tooltip","select_all_text_in_element","change_text_keep_other_children","_a","settings","apply_change_on_focus_change","element","output_elements","contains","contentEditable","getSelection","removeAllRanges","setTimeout","shown_no_selection_warning","document","createRange","selection","range","selectNodeContents","firstChild","addRange","register_inline_value_editors","set_inline_editor_style","inline_editor_style","placeholder_value_elements","placeholder_name","getAttribute","placeholders","get","read_only","createElement","appendChild","type","InputType","Textbox","Checkbox","prepare_span_for_checkbox_editor","Dropdown","style","VALID_INLINE_EDITOR_STYLES","style_to_remove","body","TABLE_CELL_HEADINGS","Map","set","appendTextNode","text","createTextNode","createChildElement","parent","tag_name","child","fill_settings_content_container","settings_contents","in_placeholder_table","set_highlight_placeholders","enabled","values","output","highlight_placeholders","textContent","do_nothing","_enabled","append_boolean_setting_checkbox","expand_auto_tables","inline_editors","abort","AbortController","span_element","removeAttribute","unregister_inline_value_editors","append_setting_dropdown","settings_button_bar","settings_reset_button","placeholder_reset_button","parent_element","label_text","custom_on_change","label","checkbox","checked","store_boolean_setting","dropdown","style_name","option_element","choices","store_multiple_choice_setting","generate_automatic_placeholder_table","columns","placeholders_to_show","show_empty","sort_and_remove_duplicate_placeholders","root_element","table","table_head","table_head_row","table_body","column","table_cell","heading","rows","row","populate_auto_table_row","input_tables","content_element","title_text","settings_button","expandable_contents","append","update_expanded_state","is_expanded","display","expanded","expand_if_needed","show_settings","onclick","e","prepare_settings_button","convert_to_dynamic_placeholder_table","placeholder_list","Set","sort","a","b","order_index","cell","dynamic_placeholer","create_dynamic_placeholder_element","input","prepare_input_field","update_auto_table","new_placeholder_list","rows_to_keep","final_rows","reversed_current","reverse","reversed_new","next_new","pop","next_current","table_element","insertBefore","insertAdjacentElement","initialize_input_checkbox","initialize_input_dropdown","initialize_input_textbox","tagName","disabled","input_elements","new_node","parentNode","replaceChild","selectedIndex","cursor","affected_placeholders","dependency_graph","get_all_upstream","require_reload","ph","reload_page_on_change","p","on_placeholder_value_change","get_all_used_placeholders","update_all_auto_tables","Computed","replace_dynamic_placeholder_values","update_inline_checkbox_editor_classes","CHECKED_SVG_URL","fn_change_value","static_replace","search_regex","replacement_value","walker","createTreeWalker","NodeFilter","SHOW_TEXT","node","global","source","nextNode","nodeValue","replaced_str","replace","escapeHTML","inner_html_replace","childNodes","nodeType","Node","ELEMENT_NODE","span","dataset","expanded_value","dynamic_replace","search_for_pre_replaced","inner_dynamic_or_editable_replace","editable_replace","extra_class","existing_count","extra_class_query","already_existing_wrappers","wrapper","query_type","nodes_to_modify","match","parentElement","do_dynamic_replace","regex_dynamic","count_on_page","do_editable_replace","regex_editable","do_normal_replace","inner_do_normal_replace","normal_is_alias_for","regex_normal","regex_html","regex_static","do_static_replace","do_html_replace","replace_placeholder_in_string_with","new_text","TEXT_NODE","insertAdjacentText","DependencyGraph","constructor","this","nodes","reset","clear","GraphNode","confirm","downlinks","recalculate_expanded_value","debug_print_representation","dependencies","n","unmark_everything","marked","get_node","update_placeholder_downlinks","has_loop","get_all_marked","recursive_mark_upstream","old_downlink","remove_uplink","comp","dep_name","computed_depends_on","dep_node","uplinks","allow_nested","other_node","string_contains_placeholder","recursive_mark_downstream","_has_loop","back_stack","current_node","new_back_stack","indexOf","string_to_test","placeholder_to_find","filter","recursive","downlink","computed_function","unique","now","Math","random","safe_replace_multiple_placeholders_in_string","uplink_node","assert_field_type","expected_type_str","parent_object","actual_type_str","get_number_field","element_type","array","Array","isArray","entry","entries","msg","ReplaceType","escapeRegExp","regex_pattern","parse_any_placeholder","validator_map","parsed","dynamic_prefix","dynamic_suffix","editable_prefix","editable_suffix","html_prefix_optional","html_prefix","html_suffix","normal_prefix","normal_suffix","static_prefix","static_suffix","finish_parse_textbox","stored_state","default_function","load_textbox_state","finish_parse_checkbox","checked_by_default","load_checkbox_state","finish_parse_dropdown","stored_index","Number","load_dropdown_state","finish_parse_computed","default_js_code","compiled_function","validator_names","validator_list","known_validators","from","keys","default_value_line","validation_ok_tooltip","Object","assign","raw_options","function_body","param_names","param_values","dep","fn","main","placeholder_map","textboxes","checkboxes","dropdowns","validator_data_list","validator_data","has","apply_change_on_focus_change_default","debug_default","expand_auto_tables_default","default_inline_editor_style","parse_settings","placeholder_data","parse_config","PlaceholderPluginConfigJson","enable_debug","PlaceholderPlugin","export_api_functions","delay_millis","document_listener","document$","subscribe","do_plugin_stuff","_key","_map","allow_inner_html","output_list","find_dynamic_placeholder_wrappers","replace_placeholders_in_subtree","input_list","initialize_all_input_fields","element_list","used_placeholders","HTMLElement","columns_str","split","initialize_auto_tables","initialize_placeholder_settings_divs"],"sourceRoot":""}