@real1ty-obsidian-plugins/utils 2.30.0 → 2.31.0

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 (238) hide show
  1. package/dist/async/async.d.ts +69 -0
  2. package/dist/async/async.d.ts.map +1 -0
  3. package/dist/async/async.js +108 -0
  4. package/dist/async/async.js.map +1 -0
  5. package/dist/async/batch-operations.d.ts +21 -0
  6. package/dist/async/batch-operations.d.ts.map +1 -0
  7. package/dist/async/batch-operations.js +60 -0
  8. package/dist/async/batch-operations.js.map +1 -0
  9. package/dist/async/change-notifier.d.ts +13 -0
  10. package/dist/async/change-notifier.d.ts.map +1 -0
  11. package/dist/async/change-notifier.js +26 -0
  12. package/dist/async/change-notifier.js.map +1 -0
  13. package/dist/async/debounced-notifier.d.ts +26 -0
  14. package/dist/async/debounced-notifier.d.ts.map +1 -0
  15. package/dist/async/debounced-notifier.js +50 -0
  16. package/dist/async/debounced-notifier.js.map +1 -0
  17. package/dist/async/index.d.ts +5 -0
  18. package/dist/async/index.d.ts.map +1 -0
  19. package/dist/async/index.js +5 -0
  20. package/dist/async/index.js.map +1 -0
  21. package/dist/components/frontmatter-propagation-modal.d.ts +17 -0
  22. package/dist/components/frontmatter-propagation-modal.d.ts.map +1 -0
  23. package/dist/components/frontmatter-propagation-modal.js +85 -0
  24. package/dist/components/frontmatter-propagation-modal.js.map +1 -0
  25. package/dist/components/index.d.ts +5 -0
  26. package/dist/components/index.d.ts.map +1 -0
  27. package/dist/components/index.js +5 -0
  28. package/dist/components/index.js.map +1 -0
  29. package/dist/components/input-managers/base.d.ts +30 -0
  30. package/dist/components/input-managers/base.d.ts.map +1 -0
  31. package/dist/components/input-managers/base.js +115 -0
  32. package/dist/components/input-managers/base.js.map +1 -0
  33. package/dist/components/input-managers/expression.d.ts +12 -0
  34. package/dist/components/input-managers/expression.d.ts.map +1 -0
  35. package/dist/components/input-managers/expression.js +56 -0
  36. package/dist/components/input-managers/expression.js.map +1 -0
  37. package/dist/components/input-managers/index.d.ts +4 -0
  38. package/dist/components/input-managers/index.d.ts.map +1 -0
  39. package/dist/components/input-managers/index.js +4 -0
  40. package/dist/components/input-managers/index.js.map +1 -0
  41. package/dist/components/input-managers/search.d.ts +6 -0
  42. package/dist/components/input-managers/search.d.ts.map +1 -0
  43. package/dist/components/input-managers/search.js +16 -0
  44. package/dist/components/input-managers/search.js.map +1 -0
  45. package/dist/components/registered-events-component.d.ts +30 -0
  46. package/dist/components/registered-events-component.d.ts.map +1 -0
  47. package/dist/components/registered-events-component.js +43 -0
  48. package/dist/components/registered-events-component.js.map +1 -0
  49. package/dist/components/whats-new-modal.d.ts +89 -0
  50. package/dist/components/whats-new-modal.d.ts.map +1 -0
  51. package/dist/components/whats-new-modal.js +196 -0
  52. package/dist/components/whats-new-modal.js.map +1 -0
  53. package/dist/core/color-utils.d.ts +17 -0
  54. package/dist/core/color-utils.d.ts.map +1 -0
  55. package/dist/core/color-utils.js +29 -0
  56. package/dist/core/color-utils.js.map +1 -0
  57. package/dist/core/css-utils.d.ts +39 -0
  58. package/dist/core/css-utils.d.ts.map +1 -0
  59. package/dist/core/css-utils.js +60 -0
  60. package/dist/core/css-utils.js.map +1 -0
  61. package/dist/core/evaluator/base.d.ts +22 -0
  62. package/dist/core/evaluator/base.d.ts.map +1 -0
  63. package/dist/core/evaluator/base.js +67 -0
  64. package/dist/core/evaluator/base.js.map +1 -0
  65. package/dist/core/evaluator/color.d.ts +19 -0
  66. package/dist/core/evaluator/color.d.ts.map +1 -0
  67. package/dist/core/evaluator/color.js +25 -0
  68. package/dist/core/evaluator/color.js.map +1 -0
  69. package/dist/core/evaluator/excluded.d.ts +32 -0
  70. package/dist/core/evaluator/excluded.d.ts.map +1 -0
  71. package/dist/core/evaluator/excluded.js +41 -0
  72. package/dist/core/evaluator/excluded.js.map +1 -0
  73. package/dist/core/evaluator/filter.d.ts +15 -0
  74. package/dist/core/evaluator/filter.d.ts.map +1 -0
  75. package/dist/core/evaluator/filter.js +27 -0
  76. package/dist/core/evaluator/filter.js.map +1 -0
  77. package/dist/core/evaluator/included.d.ts +36 -0
  78. package/dist/core/evaluator/included.d.ts.map +1 -0
  79. package/dist/core/evaluator/included.js +51 -0
  80. package/dist/core/evaluator/included.js.map +1 -0
  81. package/dist/core/evaluator/index.d.ts +6 -0
  82. package/dist/core/evaluator/index.d.ts.map +1 -0
  83. package/dist/core/evaluator/index.js +6 -0
  84. package/dist/core/evaluator/index.js.map +1 -0
  85. package/dist/core/expression-utils.d.ts +17 -0
  86. package/dist/core/expression-utils.d.ts.map +1 -0
  87. package/dist/core/expression-utils.js +40 -0
  88. package/dist/core/expression-utils.js.map +1 -0
  89. package/dist/core/frontmatter-value.d.ts +157 -0
  90. package/dist/core/frontmatter-value.d.ts.map +1 -0
  91. package/dist/core/frontmatter-value.js +417 -0
  92. package/dist/core/frontmatter-value.js.map +1 -0
  93. package/dist/core/generate.d.ts +7 -0
  94. package/dist/core/generate.d.ts.map +1 -0
  95. package/dist/core/generate.js +13 -0
  96. package/dist/core/generate.js.map +1 -0
  97. package/dist/core/history.d.ts +12 -0
  98. package/dist/core/history.d.ts.map +1 -0
  99. package/dist/core/history.js +39 -0
  100. package/dist/core/history.js.map +1 -0
  101. package/dist/core/index.d.ts +11 -0
  102. package/dist/core/index.d.ts.map +1 -0
  103. package/dist/core/index.js +11 -0
  104. package/dist/core/index.js.map +1 -0
  105. package/dist/core/indexer.d.ts +109 -0
  106. package/dist/core/indexer.d.ts.map +1 -0
  107. package/dist/core/indexer.js +185 -0
  108. package/dist/core/indexer.js.map +1 -0
  109. package/dist/core/property-renderer.d.ts +9 -0
  110. package/dist/core/property-renderer.d.ts.map +1 -0
  111. package/dist/core/property-renderer.js +42 -0
  112. package/dist/core/property-renderer.js.map +1 -0
  113. package/dist/core/validation.d.ts +13 -0
  114. package/dist/core/validation.d.ts.map +1 -0
  115. package/dist/core/validation.js +27 -0
  116. package/dist/core/validation.js.map +1 -0
  117. package/dist/date/date-recurrence.d.ts +30 -0
  118. package/dist/date/date-recurrence.d.ts.map +1 -0
  119. package/dist/date/date-recurrence.js +188 -0
  120. package/dist/date/date-recurrence.js.map +1 -0
  121. package/dist/date/date.d.ts +21 -0
  122. package/dist/date/date.d.ts.map +1 -0
  123. package/dist/date/date.js +105 -0
  124. package/dist/date/date.js.map +1 -0
  125. package/dist/date/index.d.ts +3 -0
  126. package/dist/date/index.d.ts.map +1 -0
  127. package/dist/date/index.js +3 -0
  128. package/dist/date/index.js.map +1 -0
  129. package/dist/file/child-reference.d.ts +9 -0
  130. package/dist/file/child-reference.d.ts.map +1 -0
  131. package/dist/file/child-reference.js +57 -0
  132. package/dist/file/child-reference.js.map +1 -0
  133. package/dist/file/file-operations.d.ts +31 -0
  134. package/dist/file/file-operations.d.ts.map +1 -0
  135. package/dist/file/file-operations.js +160 -0
  136. package/dist/file/file-operations.js.map +1 -0
  137. package/dist/file/file-utils.d.ts +33 -0
  138. package/dist/file/file-utils.d.ts.map +1 -0
  139. package/dist/file/file-utils.js +76 -0
  140. package/dist/file/file-utils.js.map +1 -0
  141. package/dist/file/file.d.ts +332 -0
  142. package/dist/file/file.d.ts.map +1 -0
  143. package/dist/file/file.js +559 -0
  144. package/dist/file/file.js.map +1 -0
  145. package/dist/file/frontmatter-diff.d.ts +38 -0
  146. package/dist/file/frontmatter-diff.d.ts.map +1 -0
  147. package/dist/file/frontmatter-diff.js +162 -0
  148. package/dist/file/frontmatter-diff.js.map +1 -0
  149. package/dist/file/frontmatter-propagation.d.ts +4 -0
  150. package/dist/file/frontmatter-propagation.d.ts.map +1 -0
  151. package/dist/file/frontmatter-propagation.js +28 -0
  152. package/dist/file/frontmatter-propagation.js.map +1 -0
  153. package/dist/file/frontmatter-serialization.d.ts +21 -0
  154. package/dist/file/frontmatter-serialization.d.ts.map +1 -0
  155. package/dist/file/frontmatter-serialization.js +57 -0
  156. package/dist/file/frontmatter-serialization.js.map +1 -0
  157. package/dist/file/frontmatter.d.ts +15 -0
  158. package/dist/file/frontmatter.d.ts.map +1 -0
  159. package/dist/file/frontmatter.js +68 -0
  160. package/dist/file/frontmatter.js.map +1 -0
  161. package/dist/file/index.d.ts +13 -0
  162. package/dist/file/index.d.ts.map +1 -0
  163. package/dist/file/index.js +13 -0
  164. package/dist/file/index.js.map +1 -0
  165. package/dist/file/link-parser.d.ts +63 -0
  166. package/dist/file/link-parser.d.ts.map +1 -0
  167. package/dist/file/link-parser.js +137 -0
  168. package/dist/file/link-parser.js.map +1 -0
  169. package/dist/file/property-utils.d.ts +55 -0
  170. package/dist/file/property-utils.d.ts.map +1 -0
  171. package/dist/file/property-utils.js +90 -0
  172. package/dist/file/property-utils.js.map +1 -0
  173. package/dist/file/templater-service.d.ts +16 -0
  174. package/dist/file/templater-service.d.ts.map +1 -0
  175. package/dist/file/templater-service.js +37 -0
  176. package/dist/file/templater-service.js.map +1 -0
  177. package/dist/file/templater.d.ts +28 -0
  178. package/dist/file/templater.d.ts.map +1 -0
  179. package/dist/file/templater.js +126 -0
  180. package/dist/file/templater.js.map +1 -0
  181. package/dist/index.d.ts +9 -0
  182. package/dist/index.d.ts.map +1 -0
  183. package/dist/index.js +17 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/inputs/index.d.ts +2 -0
  186. package/dist/inputs/index.d.ts.map +1 -0
  187. package/dist/inputs/index.js +2 -0
  188. package/dist/inputs/index.js.map +1 -0
  189. package/dist/inputs/input-filter-manager.d.ts +72 -0
  190. package/dist/inputs/input-filter-manager.d.ts.map +1 -0
  191. package/dist/inputs/input-filter-manager.js +140 -0
  192. package/dist/inputs/input-filter-manager.js.map +1 -0
  193. package/dist/settings/index.d.ts +3 -0
  194. package/dist/settings/index.d.ts.map +1 -0
  195. package/dist/settings/index.js +3 -0
  196. package/dist/settings/index.js.map +1 -0
  197. package/dist/settings/settings-store.d.ts +20 -0
  198. package/dist/settings/settings-store.d.ts.map +1 -0
  199. package/dist/settings/settings-store.js +82 -0
  200. package/dist/settings/settings-store.js.map +1 -0
  201. package/dist/settings/settings-ui-builder.d.ts +74 -0
  202. package/dist/settings/settings-ui-builder.d.ts.map +1 -0
  203. package/dist/settings/settings-ui-builder.js +436 -0
  204. package/dist/settings/settings-ui-builder.js.map +1 -0
  205. package/dist/string/changelog-parser.d.ts +17 -0
  206. package/dist/string/changelog-parser.d.ts.map +1 -0
  207. package/dist/string/changelog-parser.js +77 -0
  208. package/dist/string/changelog-parser.js.map +1 -0
  209. package/dist/string/filename-utils.d.ts +46 -0
  210. package/dist/string/filename-utils.d.ts.map +1 -0
  211. package/dist/string/filename-utils.js +65 -0
  212. package/dist/string/filename-utils.js.map +1 -0
  213. package/dist/string/index.d.ts +4 -0
  214. package/dist/string/index.d.ts.map +1 -0
  215. package/dist/string/index.js +4 -0
  216. package/dist/string/index.js.map +1 -0
  217. package/dist/string/string.d.ts +5 -0
  218. package/dist/string/string.d.ts.map +1 -0
  219. package/dist/string/string.js +25 -0
  220. package/dist/string/string.js.map +1 -0
  221. package/dist/testing/index.d.ts +5 -0
  222. package/dist/testing/index.d.ts.map +1 -0
  223. package/dist/testing/index.js +6 -0
  224. package/dist/testing/index.js.map +1 -0
  225. package/dist/testing/mocks/obsidian.d.ts +150 -0
  226. package/dist/testing/mocks/obsidian.d.ts.map +1 -0
  227. package/dist/testing/mocks/obsidian.js +226 -0
  228. package/dist/testing/mocks/obsidian.js.map +1 -0
  229. package/dist/testing/mocks/utils.d.ts +14 -0
  230. package/dist/testing/mocks/utils.d.ts.map +1 -0
  231. package/dist/testing/mocks/utils.js +85 -0
  232. package/dist/testing/mocks/utils.js.map +1 -0
  233. package/dist/testing/setup.d.ts +2 -0
  234. package/dist/testing/setup.d.ts.map +1 -0
  235. package/dist/testing/setup.js +18 -0
  236. package/dist/testing/setup.js.map +1 -0
  237. package/package.json +1 -1
  238. package/src/components/whats-new-modal.ts +74 -0
@@ -0,0 +1,115 @@
1
+ const DEFAULT_DEBOUNCE_MS = 150;
2
+ export class InputManager {
3
+ constructor(parentEl, placeholder, cssPrefix, onFilterChange, initiallyVisible, onHide, debounceMs = DEFAULT_DEBOUNCE_MS) {
4
+ this.parentEl = parentEl;
5
+ this.placeholder = placeholder;
6
+ this.cssPrefix = cssPrefix;
7
+ this.onFilterChange = onFilterChange;
8
+ this.inputEl = null;
9
+ this.debounceTimer = null;
10
+ this.currentValue = "";
11
+ this.persistentlyVisible = false;
12
+ this.hiddenClass = `${cssPrefix}-hidden`;
13
+ this.debounceMs = debounceMs;
14
+ this.cssClass = `${cssPrefix}-input`;
15
+ const classes = initiallyVisible
16
+ ? `${cssPrefix}-container`
17
+ : `${cssPrefix}-container ${this.hiddenClass}`;
18
+ this.containerEl = this.parentEl.createEl("div", {
19
+ cls: classes,
20
+ });
21
+ this.onHide = onHide;
22
+ this.render();
23
+ }
24
+ render() {
25
+ this.inputEl = this.containerEl.createEl("input", {
26
+ type: "text",
27
+ cls: this.cssClass,
28
+ placeholder: this.placeholder,
29
+ });
30
+ this.inputEl.addEventListener("input", () => {
31
+ this.handleInputChange();
32
+ });
33
+ this.inputEl.addEventListener("keydown", (evt) => {
34
+ var _a;
35
+ if (evt.key === "Escape") {
36
+ // Only allow hiding if not persistently visible
37
+ if (!this.persistentlyVisible) {
38
+ this.hide();
39
+ }
40
+ else {
41
+ // Just blur the input if persistently visible
42
+ (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.blur();
43
+ }
44
+ }
45
+ else if (evt.key === "Enter") {
46
+ this.applyFilterImmediately();
47
+ }
48
+ });
49
+ }
50
+ handleInputChange() {
51
+ if (this.debounceTimer !== null) {
52
+ window.clearTimeout(this.debounceTimer);
53
+ }
54
+ this.debounceTimer = window.setTimeout(() => {
55
+ this.applyFilterImmediately();
56
+ }, this.debounceMs);
57
+ }
58
+ applyFilterImmediately() {
59
+ var _a, _b;
60
+ const newValue = (_b = (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.value.trim()) !== null && _b !== void 0 ? _b : "";
61
+ if (newValue !== this.currentValue) {
62
+ this.updateFilterValue(newValue);
63
+ }
64
+ }
65
+ updateFilterValue(value) {
66
+ this.currentValue = value;
67
+ this.onFilterChange();
68
+ }
69
+ getCurrentValue() {
70
+ return this.currentValue;
71
+ }
72
+ show() {
73
+ var _a;
74
+ this.containerEl.removeClass(this.hiddenClass);
75
+ (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.focus();
76
+ }
77
+ hide() {
78
+ var _a;
79
+ // Don't allow hiding if persistently visible
80
+ if (this.persistentlyVisible) {
81
+ return;
82
+ }
83
+ this.containerEl.addClass(this.hiddenClass);
84
+ if (this.inputEl) {
85
+ this.inputEl.value = "";
86
+ }
87
+ this.updateFilterValue("");
88
+ (_a = this.onHide) === null || _a === void 0 ? void 0 : _a.call(this);
89
+ }
90
+ focus() {
91
+ var _a;
92
+ (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.focus();
93
+ }
94
+ isVisible() {
95
+ return !this.containerEl.hasClass(this.hiddenClass);
96
+ }
97
+ setPersistentlyVisible(value) {
98
+ this.persistentlyVisible = value;
99
+ if (value) {
100
+ this.show();
101
+ }
102
+ else {
103
+ this.hide();
104
+ }
105
+ }
106
+ destroy() {
107
+ if (this.debounceTimer !== null) {
108
+ window.clearTimeout(this.debounceTimer);
109
+ this.debounceTimer = null;
110
+ }
111
+ this.containerEl.remove();
112
+ this.inputEl = null;
113
+ }
114
+ }
115
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/components/input-managers/base.ts"],"names":[],"mappings":"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","sourcesContent":["export type InputManagerFilterChangeCallback = () => void;\n\nconst DEFAULT_DEBOUNCE_MS = 150;\n\nexport abstract class InputManager {\n\tprotected containerEl: HTMLElement;\n\tprotected inputEl: HTMLInputElement | null = null;\n\tprotected debounceTimer: number | null = null;\n\tprotected currentValue = \"\";\n\tprotected persistentlyVisible = false;\n\tprotected onHide?: () => void;\n\tprotected hiddenClass: string;\n\tprotected debounceMs: number;\n\tprotected cssClass: string;\n\n\tconstructor(\n\t\tprotected parentEl: HTMLElement,\n\t\tprotected placeholder: string,\n\t\tprotected cssPrefix: string,\n\t\tprotected onFilterChange: InputManagerFilterChangeCallback,\n\t\tinitiallyVisible: boolean,\n\t\tonHide?: () => void,\n\t\tdebounceMs: number = DEFAULT_DEBOUNCE_MS\n\t) {\n\t\tthis.hiddenClass = `${cssPrefix}-hidden`;\n\t\tthis.debounceMs = debounceMs;\n\t\tthis.cssClass = `${cssPrefix}-input`;\n\n\t\tconst classes = initiallyVisible\n\t\t\t? `${cssPrefix}-container`\n\t\t\t: `${cssPrefix}-container ${this.hiddenClass}`;\n\n\t\tthis.containerEl = this.parentEl.createEl(\"div\", {\n\t\t\tcls: classes,\n\t\t});\n\n\t\tthis.onHide = onHide;\n\n\t\tthis.render();\n\t}\n\n\tprivate render(): void {\n\t\tthis.inputEl = this.containerEl.createEl(\"input\", {\n\t\t\ttype: \"text\",\n\t\t\tcls: this.cssClass,\n\t\t\tplaceholder: this.placeholder,\n\t\t});\n\n\t\tthis.inputEl.addEventListener(\"input\", () => {\n\t\t\tthis.handleInputChange();\n\t\t});\n\n\t\tthis.inputEl.addEventListener(\"keydown\", (evt) => {\n\t\t\tif (evt.key === \"Escape\") {\n\t\t\t\t// Only allow hiding if not persistently visible\n\t\t\t\tif (!this.persistentlyVisible) {\n\t\t\t\t\tthis.hide();\n\t\t\t\t} else {\n\t\t\t\t\t// Just blur the input if persistently visible\n\t\t\t\t\tthis.inputEl?.blur();\n\t\t\t\t}\n\t\t\t} else if (evt.key === \"Enter\") {\n\t\t\t\tthis.applyFilterImmediately();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate handleInputChange(): void {\n\t\tif (this.debounceTimer !== null) {\n\t\t\twindow.clearTimeout(this.debounceTimer);\n\t\t}\n\n\t\tthis.debounceTimer = window.setTimeout(() => {\n\t\t\tthis.applyFilterImmediately();\n\t\t}, this.debounceMs);\n\t}\n\n\tprotected applyFilterImmediately(): void {\n\t\tconst newValue = this.inputEl?.value.trim() ?? \"\";\n\n\t\tif (newValue !== this.currentValue) {\n\t\t\tthis.updateFilterValue(newValue);\n\t\t}\n\t}\n\n\tprotected updateFilterValue(value: string): void {\n\t\tthis.currentValue = value;\n\n\t\tthis.onFilterChange();\n\t}\n\n\tgetCurrentValue(): string {\n\t\treturn this.currentValue;\n\t}\n\n\tshow(): void {\n\t\tthis.containerEl.removeClass(this.hiddenClass);\n\n\t\tthis.inputEl?.focus();\n\t}\n\n\thide(): void {\n\t\t// Don't allow hiding if persistently visible\n\t\tif (this.persistentlyVisible) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.containerEl.addClass(this.hiddenClass);\n\n\t\tif (this.inputEl) {\n\t\t\tthis.inputEl.value = \"\";\n\t\t}\n\n\t\tthis.updateFilterValue(\"\");\n\n\t\tthis.onHide?.();\n\t}\n\n\tfocus(): void {\n\t\tthis.inputEl?.focus();\n\t}\n\n\tisVisible(): boolean {\n\t\treturn !this.containerEl.hasClass(this.hiddenClass);\n\t}\n\n\tsetPersistentlyVisible(value: boolean): void {\n\t\tthis.persistentlyVisible = value;\n\n\t\tif (value) {\n\t\t\tthis.show();\n\t\t} else {\n\t\t\tthis.hide();\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tif (this.debounceTimer !== null) {\n\t\t\twindow.clearTimeout(this.debounceTimer);\n\n\t\t\tthis.debounceTimer = null;\n\t\t}\n\n\t\tthis.containerEl.remove();\n\n\t\tthis.inputEl = null;\n\t}\n\n\tabstract shouldInclude(data: unknown): boolean;\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { InputManager } from "./base";
2
+ export declare class ExpressionFilterInputManager extends InputManager {
3
+ private compiledFunc;
4
+ private propertyMapping;
5
+ private lastWarnedExpression;
6
+ constructor(parentEl: HTMLElement, cssPrefix: string, onFilterChange: () => void, initiallyVisible?: boolean, placeholder?: string, onHide?: () => void, debounceMs?: number);
7
+ protected updateFilterValue(filterValue: string): void;
8
+ shouldInclude(event: {
9
+ meta?: Record<string, unknown>;
10
+ }): boolean;
11
+ }
12
+ //# sourceMappingURL=expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/components/input-managers/expression.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,qBAAa,4BAA6B,SAAQ,YAAY;IAC7D,OAAO,CAAC,YAAY,CAAkD;IAEtE,OAAO,CAAC,eAAe,CAA6B;IAEpD,OAAO,CAAC,oBAAoB,CAAuB;gBAGlD,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,IAAI,EAC1B,gBAAgB,GAAE,OAAe,EACjC,WAAW,GAAE,MAA4B,EACzC,MAAM,CAAC,EAAE,MAAM,IAAI,EACnB,UAAU,CAAC,EAAE,MAAM;IASpB,SAAS,CAAC,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAUtD,aAAa,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO;CAsDjE"}
@@ -0,0 +1,56 @@
1
+ import { buildPropertyMapping, sanitizeExpression } from "../../core/expression-utils";
2
+ import { InputManager } from "./base";
3
+ export class ExpressionFilterInputManager extends InputManager {
4
+ constructor(parentEl, cssPrefix, onFilterChange, initiallyVisible = false, placeholder = "Status === 'Done'", onHide, debounceMs) {
5
+ super(parentEl, placeholder, cssPrefix, onFilterChange, initiallyVisible, onHide, debounceMs);
6
+ this.compiledFunc = null;
7
+ this.propertyMapping = new Map();
8
+ this.lastWarnedExpression = null;
9
+ this.cssClass = `${cssPrefix}-expression-input`;
10
+ if (this.inputEl) {
11
+ this.inputEl.className = this.cssClass;
12
+ }
13
+ }
14
+ updateFilterValue(filterValue) {
15
+ super.updateFilterValue(filterValue);
16
+ this.compiledFunc = null;
17
+ this.propertyMapping.clear();
18
+ this.lastWarnedExpression = null;
19
+ }
20
+ shouldInclude(event) {
21
+ if (!this.currentValue)
22
+ return true;
23
+ const frontmatter = event.meta || {};
24
+ try {
25
+ const currentKeys = new Set(Object.keys(frontmatter));
26
+ const existingKeys = new Set(this.propertyMapping.keys());
27
+ const newKeys = [...currentKeys].filter((key) => !existingKeys.has(key));
28
+ if (newKeys.length > 0) {
29
+ const allKeys = new Set([...existingKeys, ...currentKeys]);
30
+ this.propertyMapping = buildPropertyMapping(Array.from(allKeys));
31
+ this.compiledFunc = null;
32
+ }
33
+ if (!this.compiledFunc) {
34
+ const sanitized = sanitizeExpression(this.currentValue, this.propertyMapping);
35
+ const params = Array.from(this.propertyMapping.values());
36
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval -- Dynamic function creation for expression evaluation with sanitized input
37
+ this.compiledFunc = new Function(...params, `"use strict"; return ${sanitized};`);
38
+ }
39
+ const values = Array.from(this.propertyMapping.keys()).map((key) => { var _a; return (_a = frontmatter[key]) !== null && _a !== void 0 ? _a : undefined; });
40
+ const result = this.compiledFunc(...values);
41
+ return result;
42
+ }
43
+ catch (error) {
44
+ if (error instanceof ReferenceError) {
45
+ const hasInequality = this.currentValue.includes("!==") || this.currentValue.includes("!=");
46
+ return hasInequality;
47
+ }
48
+ if (this.lastWarnedExpression !== this.currentValue) {
49
+ console.warn("Invalid filter expression:", this.currentValue, error);
50
+ this.lastWarnedExpression = this.currentValue;
51
+ }
52
+ return false;
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.js","sourceRoot":"","sources":["../../../src/components/input-managers/expression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,OAAO,4BAA6B,SAAQ,YAAY;IAO7D,YACC,QAAqB,EACrB,SAAiB,EACjB,cAA0B,EAC1B,mBAA4B,KAAK,EACjC,cAAsB,mBAAmB,EACzC,MAAmB,EACnB,UAAmB;QAEnB,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAfvF,iBAAY,GAA6C,IAAI,CAAC;QAE9D,oBAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE5C,yBAAoB,GAAkB,IAAI,CAAC;QAYlD,IAAI,CAAC,QAAQ,GAAG,GAAG,SAAS,mBAAmB,CAAC;QAChD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,CAAC;IACF,CAAC;IAES,iBAAiB,CAAC,WAAmB;QAC9C,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAErC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAE7B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAClC,CAAC;IAED,aAAa,CAAC,KAAyC;QACtD,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAEpC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAErC,IAAI,CAAC;YACJ,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAEtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;YAE1D,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAEzE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC;gBAE3D,IAAI,CAAC,eAAe,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAEjE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;gBAE9E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC;gBAEzD,0IAA0I;gBAC1I,IAAI,CAAC,YAAY,GAAG,IAAI,QAAQ,CAAC,GAAG,MAAM,EAAE,wBAAwB,SAAS,GAAG,CAEpE,CAAC;YACd,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CACzD,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,MAAA,WAAW,CAAC,GAAG,CAAC,mCAAI,SAAS,CAAA,EAAA,CACtC,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC;YAE5C,OAAO,MAAM,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;gBACrC,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAE5F,OAAO,aAAa,CAAC;YACtB,CAAC;YAED,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;gBAErE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,YAAY,CAAC;YAC/C,CAAC;YAED,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;CACD","sourcesContent":["import { buildPropertyMapping, sanitizeExpression } from \"../../core/expression-utils\";\n\nimport { InputManager } from \"./base\";\n\nexport class ExpressionFilterInputManager extends InputManager {\n\tprivate compiledFunc: ((...args: unknown[]) => boolean) | null = null;\n\n\tprivate propertyMapping = new Map<string, string>();\n\n\tprivate lastWarnedExpression: string | null = null;\n\n\tconstructor(\n\t\tparentEl: HTMLElement,\n\t\tcssPrefix: string,\n\t\tonFilterChange: () => void,\n\t\tinitiallyVisible: boolean = false,\n\t\tplaceholder: string = \"Status === 'Done'\",\n\t\tonHide?: () => void,\n\t\tdebounceMs?: number\n\t) {\n\t\tsuper(parentEl, placeholder, cssPrefix, onFilterChange, initiallyVisible, onHide, debounceMs);\n\t\tthis.cssClass = `${cssPrefix}-expression-input`;\n\t\tif (this.inputEl) {\n\t\t\tthis.inputEl.className = this.cssClass;\n\t\t}\n\t}\n\n\tprotected updateFilterValue(filterValue: string): void {\n\t\tsuper.updateFilterValue(filterValue);\n\n\t\tthis.compiledFunc = null;\n\n\t\tthis.propertyMapping.clear();\n\n\t\tthis.lastWarnedExpression = null;\n\t}\n\n\tshouldInclude(event: { meta?: Record<string, unknown> }): boolean {\n\t\tif (!this.currentValue) return true;\n\n\t\tconst frontmatter = event.meta || {};\n\n\t\ttry {\n\t\t\tconst currentKeys = new Set(Object.keys(frontmatter));\n\n\t\t\tconst existingKeys = new Set(this.propertyMapping.keys());\n\n\t\t\tconst newKeys = [...currentKeys].filter((key) => !existingKeys.has(key));\n\n\t\t\tif (newKeys.length > 0) {\n\t\t\t\tconst allKeys = new Set([...existingKeys, ...currentKeys]);\n\n\t\t\t\tthis.propertyMapping = buildPropertyMapping(Array.from(allKeys));\n\n\t\t\t\tthis.compiledFunc = null;\n\t\t\t}\n\n\t\t\tif (!this.compiledFunc) {\n\t\t\t\tconst sanitized = sanitizeExpression(this.currentValue, this.propertyMapping);\n\n\t\t\t\tconst params = Array.from(this.propertyMapping.values());\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-implied-eval -- Dynamic function creation for expression evaluation with sanitized input\n\t\t\t\tthis.compiledFunc = new Function(...params, `\"use strict\"; return ${sanitized};`) as (\n\t\t\t\t\t...args: unknown[]\n\t\t\t\t) => boolean;\n\t\t\t}\n\n\t\t\tconst values = Array.from(this.propertyMapping.keys()).map(\n\t\t\t\t(key) => frontmatter[key] ?? undefined\n\t\t\t);\n\n\t\t\tconst result = this.compiledFunc(...values);\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ReferenceError) {\n\t\t\t\tconst hasInequality = this.currentValue.includes(\"!==\") || this.currentValue.includes(\"!=\");\n\n\t\t\t\treturn hasInequality;\n\t\t\t}\n\n\t\t\tif (this.lastWarnedExpression !== this.currentValue) {\n\t\t\t\tconsole.warn(\"Invalid filter expression:\", this.currentValue, error);\n\n\t\t\t\tthis.lastWarnedExpression = this.currentValue;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export * from "./base";
2
+ export * from "./expression";
3
+ export * from "./search";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/input-managers/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./base";
2
+ export * from "./expression";
3
+ export * from "./search";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/input-managers/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC","sourcesContent":["export * from \"./base\";\nexport * from \"./expression\";\nexport * from \"./search\";\n"]}
@@ -0,0 +1,6 @@
1
+ import { InputManager } from "./base";
2
+ export declare class SearchFilterInputManager extends InputManager {
3
+ constructor(parentEl: HTMLElement, cssPrefix: string, onFilterChange: () => void, initiallyVisible?: boolean, placeholder?: string, onHide?: () => void, debounceMs?: number);
4
+ shouldInclude(value: string): boolean;
5
+ }
6
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/input-managers/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,qBAAa,wBAAyB,SAAQ,YAAY;gBAExD,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,IAAI,EAC1B,gBAAgB,GAAE,OAAe,EACjC,WAAW,GAAE,MAAqB,EAClC,MAAM,CAAC,EAAE,MAAM,IAAI,EACnB,UAAU,CAAC,EAAE,MAAM;IASpB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAKrC"}
@@ -0,0 +1,16 @@
1
+ import { InputManager } from "./base";
2
+ export class SearchFilterInputManager extends InputManager {
3
+ constructor(parentEl, cssPrefix, onFilterChange, initiallyVisible = false, placeholder = "Search ...", onHide, debounceMs) {
4
+ super(parentEl, placeholder, cssPrefix, onFilterChange, initiallyVisible, onHide, debounceMs);
5
+ this.cssClass = `${cssPrefix}-search-input`;
6
+ if (this.inputEl) {
7
+ this.inputEl.className = this.cssClass;
8
+ }
9
+ }
10
+ shouldInclude(value) {
11
+ if (!this.currentValue)
12
+ return true;
13
+ return value.toLowerCase().includes(this.currentValue.toLowerCase());
14
+ }
15
+ }
16
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/components/input-managers/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IACzD,YACC,QAAqB,EACrB,SAAiB,EACjB,cAA0B,EAC1B,mBAA4B,KAAK,EACjC,cAAsB,YAAY,EAClC,MAAmB,EACnB,UAAmB;QAEnB,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9F,IAAI,CAAC,QAAQ,GAAG,GAAG,SAAS,eAAe,CAAC;QAC5C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,CAAC;IACF,CAAC;IAED,aAAa,CAAC,KAAa;QAC1B,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAEpC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IACtE,CAAC;CACD","sourcesContent":["import { InputManager } from \"./base\";\n\nexport class SearchFilterInputManager extends InputManager {\n\tconstructor(\n\t\tparentEl: HTMLElement,\n\t\tcssPrefix: string,\n\t\tonFilterChange: () => void,\n\t\tinitiallyVisible: boolean = false,\n\t\tplaceholder: string = \"Search ...\",\n\t\tonHide?: () => void,\n\t\tdebounceMs?: number\n\t) {\n\t\tsuper(parentEl, placeholder, cssPrefix, onFilterChange, initiallyVisible, onHide, debounceMs);\n\t\tthis.cssClass = `${cssPrefix}-search-input`;\n\t\tif (this.inputEl) {\n\t\t\tthis.inputEl.className = this.cssClass;\n\t\t}\n\t}\n\n\tshouldInclude(value: string): boolean {\n\t\tif (!this.currentValue) return true;\n\n\t\treturn value.toLowerCase().includes(this.currentValue.toLowerCase());\n\t}\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type { EventRef } from "obsidian";
2
+ /**
3
+ * Base class that provides event registration and automatic cleanup.
4
+ * Similar to ItemView's registerEvent/registerDomEvent pattern.
5
+ *
6
+ * Subclasses should call cleanupEvents() in their destroy/cleanup method.
7
+ */
8
+ export declare abstract class RegisteredEventsComponent {
9
+ protected eventRefs: EventRef[];
10
+ protected eventCleanupFunctions: Array<() => void>;
11
+ /**
12
+ * Register an Obsidian event (workspace, vault, metadataCache, etc.)
13
+ * Event will be automatically cleaned up when destroy() is called
14
+ */
15
+ protected registerEvent<T extends keyof any>(emitter: {
16
+ on(event: T, callback: (...args: any[]) => void): void;
17
+ off(event: T, callback: (...args: any[]) => void): void;
18
+ }, event: T, callback: (...args: any[]) => void): void;
19
+ /**
20
+ * Register a DOM event (window, document, or element)
21
+ * Event will be automatically cleaned up when destroy() is called
22
+ */
23
+ protected registerDomEvent<K extends keyof WindowEventMap>(target: Window | Document | HTMLElement, event: K, callback: (evt: WindowEventMap[K]) => void): void;
24
+ /**
25
+ * Clean up all registered events.
26
+ * Should be called by subclass destroy() method.
27
+ */
28
+ protected cleanupEvents(): void;
29
+ }
30
+ //# sourceMappingURL=registered-events-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registered-events-component.d.ts","sourceRoot":"","sources":["../../src/components/registered-events-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,8BAAsB,yBAAyB;IAC9C,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAM;IACrC,SAAS,CAAC,qBAAqB,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IAExD;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,EAC1C,OAAO,EAAE;QACR,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;QACvD,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;KACxD,EACD,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAChC,IAAI;IAOP;;;OAGG;IACH,SAAS,CAAC,gBAAgB,CAAC,CAAC,SAAS,MAAM,cAAc,EACxD,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,EACvC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,GACxC,IAAI;IAOP;;;OAGG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;CAM/B"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Base class that provides event registration and automatic cleanup.
3
+ * Similar to ItemView's registerEvent/registerDomEvent pattern.
4
+ *
5
+ * Subclasses should call cleanupEvents() in their destroy/cleanup method.
6
+ */
7
+ export class RegisteredEventsComponent {
8
+ constructor() {
9
+ this.eventRefs = [];
10
+ this.eventCleanupFunctions = [];
11
+ }
12
+ /**
13
+ * Register an Obsidian event (workspace, vault, metadataCache, etc.)
14
+ * Event will be automatically cleaned up when destroy() is called
15
+ */
16
+ registerEvent(emitter, event, callback) {
17
+ emitter.on(event, callback);
18
+ this.eventCleanupFunctions.push(() => {
19
+ emitter.off(event, callback);
20
+ });
21
+ }
22
+ /**
23
+ * Register a DOM event (window, document, or element)
24
+ * Event will be automatically cleaned up when destroy() is called
25
+ */
26
+ registerDomEvent(target, event, callback) {
27
+ target.addEventListener(event, callback);
28
+ this.eventCleanupFunctions.push(() => {
29
+ target.removeEventListener(event, callback);
30
+ });
31
+ }
32
+ /**
33
+ * Clean up all registered events.
34
+ * Should be called by subclass destroy() method.
35
+ */
36
+ cleanupEvents() {
37
+ for (const cleanup of this.eventCleanupFunctions) {
38
+ cleanup();
39
+ }
40
+ this.eventCleanupFunctions = [];
41
+ }
42
+ }
43
+ //# sourceMappingURL=registered-events-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registered-events-component.js","sourceRoot":"","sources":["../../src/components/registered-events-component.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAgB,yBAAyB;IAA/C;QACW,cAAS,GAAe,EAAE,CAAC;QAC3B,0BAAqB,GAAsB,EAAE,CAAC;IA6CzD,CAAC;IA3CA;;;OAGG;IACO,aAAa,CACtB,OAGC,EACD,KAAQ,EACR,QAAkC;QAElC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE;YACpC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACO,gBAAgB,CACzB,MAAuC,EACvC,KAAQ,EACR,QAA0C;QAE1C,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAyB,CAAC,CAAC;QAC1D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE;YACpC,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAyB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACO,aAAa;QACtB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAClD,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC;IACjC,CAAC;CACD","sourcesContent":["import type { EventRef } from \"obsidian\";\n\n/**\n * Base class that provides event registration and automatic cleanup.\n * Similar to ItemView's registerEvent/registerDomEvent pattern.\n *\n * Subclasses should call cleanupEvents() in their destroy/cleanup method.\n */\nexport abstract class RegisteredEventsComponent {\n\tprotected eventRefs: EventRef[] = [];\n\tprotected eventCleanupFunctions: Array<() => void> = [];\n\n\t/**\n\t * Register an Obsidian event (workspace, vault, metadataCache, etc.)\n\t * Event will be automatically cleaned up when destroy() is called\n\t */\n\tprotected registerEvent<T extends keyof any>(\n\t\temitter: {\n\t\t\ton(event: T, callback: (...args: any[]) => void): void;\n\t\t\toff(event: T, callback: (...args: any[]) => void): void;\n\t\t},\n\t\tevent: T,\n\t\tcallback: (...args: any[]) => void\n\t): void {\n\t\temitter.on(event, callback);\n\t\tthis.eventCleanupFunctions.push(() => {\n\t\t\temitter.off(event, callback);\n\t\t});\n\t}\n\n\t/**\n\t * Register a DOM event (window, document, or element)\n\t * Event will be automatically cleaned up when destroy() is called\n\t */\n\tprotected registerDomEvent<K extends keyof WindowEventMap>(\n\t\ttarget: Window | Document | HTMLElement,\n\t\tevent: K,\n\t\tcallback: (evt: WindowEventMap[K]) => void\n\t): void {\n\t\ttarget.addEventListener(event, callback as EventListener);\n\t\tthis.eventCleanupFunctions.push(() => {\n\t\t\ttarget.removeEventListener(event, callback as EventListener);\n\t\t});\n\t}\n\n\t/**\n\t * Clean up all registered events.\n\t * Should be called by subclass destroy() method.\n\t */\n\tprotected cleanupEvents(): void {\n\t\tfor (const cleanup of this.eventCleanupFunctions) {\n\t\t\tcleanup();\n\t\t}\n\t\tthis.eventCleanupFunctions = [];\n\t}\n}\n"]}
@@ -0,0 +1,89 @@
1
+ import type { App, Plugin } from "obsidian";
2
+ import { Modal } from "obsidian";
3
+ /**
4
+ * Default URLs for the What's New modal.
5
+ * These can be overridden in the config.
6
+ */
7
+ export declare const DEFAULT_WHATS_NEW_LINKS: {
8
+ /**
9
+ * Default tools page showcasing all plugins and productivity software.
10
+ */
11
+ readonly TOOLS: "https://matejvavroproductivity.com/tools/";
12
+ /**
13
+ * Default YouTube channel with Obsidian tutorials and productivity tips.
14
+ * Includes subscription confirmation parameter.
15
+ */
16
+ readonly YOUTUBE: "https://www.youtube.com/@MatejVavroProductivity?sub_confirmation=1";
17
+ };
18
+ export interface WhatsNewModalConfig {
19
+ /**
20
+ * The CSS class prefix/suffix to use for styling.
21
+ * Example: "custom-calendar" will generate classes like "custom-calendar-whats-new-modal"
22
+ */
23
+ cssPrefix: string;
24
+ /**
25
+ * Display name of the plugin.
26
+ * Example: "Custom Calendar"
27
+ */
28
+ pluginName: string;
29
+ /**
30
+ * Raw changelog markdown content to parse.
31
+ */
32
+ changelogContent: string;
33
+ /**
34
+ * Links to external resources.
35
+ */
36
+ links: {
37
+ /**
38
+ * URL to support/donate page.
39
+ */
40
+ support: string;
41
+ /**
42
+ * URL to full changelog page.
43
+ */
44
+ changelog: string;
45
+ /**
46
+ * Base URL for documentation (used to resolve relative links in changelog).
47
+ * Example: "https://docs.example.com" or "https://docs.example.com/"
48
+ */
49
+ documentation: string;
50
+ /**
51
+ * URL to tools page showcasing all plugins and productivity tools.
52
+ * Defaults to DEFAULT_WHATS_NEW_LINKS.TOOLS if not provided.
53
+ */
54
+ tools?: string;
55
+ /**
56
+ * URL to YouTube channel with tutorials and productivity tips.
57
+ * Defaults to DEFAULT_WHATS_NEW_LINKS.YOUTUBE if not provided.
58
+ */
59
+ youtube?: string;
60
+ };
61
+ }
62
+ /**
63
+ * Generic "What's New" modal that displays changelog entries between versions.
64
+ * Supports custom CSS prefixes, plugin names, and configurable links.
65
+ */
66
+ export declare class WhatsNewModal extends Modal {
67
+ private plugin;
68
+ private config;
69
+ private fromVersion;
70
+ private toVersion;
71
+ constructor(app: App, plugin: Plugin, config: WhatsNewModalConfig, fromVersion: string, toVersion: string);
72
+ /**
73
+ * Helper to create CSS class names with the configured prefix.
74
+ */
75
+ private cls;
76
+ /**
77
+ * Helper to add CSS class to an element.
78
+ */
79
+ private addCls;
80
+ /**
81
+ * Makes external links in rendered markdown clickable by adding click handlers.
82
+ * Handles both absolute URLs (http/https) and relative URLs (starting with /).
83
+ * Relative URLs are resolved against the documentation base URL.
84
+ */
85
+ private makeExternalLinksClickable;
86
+ onOpen(): Promise<void>;
87
+ onClose(): void;
88
+ }
89
+ //# sourceMappingURL=whats-new-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whats-new-modal.d.ts","sourceRoot":"","sources":["../../src/components/whats-new-modal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAoB,KAAK,EAAE,MAAM,UAAU,CAAC;AAGnD;;;GAGG;AACH,eAAO,MAAM,uBAAuB;IACnC;;OAEG;;IAGH;;;OAGG;;CAEM,CAAC;AAEX,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,KAAK,EAAE;QACN;;WAEG;QACH,OAAO,EAAE,MAAM,CAAC;QAEhB;;WAEG;QACH,SAAS,EAAE,MAAM,CAAC;QAElB;;;WAGG;QACH,aAAa,EAAE,MAAM,CAAC;QAEtB;;;WAGG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACF;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAGtC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,SAAS;gBAJjB,GAAG,EAAE,GAAG,EACA,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,EAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM;IAK1B;;OAEG;IACH,OAAO,CAAC,GAAG;IAIX;;OAEG;IACH,OAAO,CAAC,MAAM;IAId;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAmC5B,MAAM;IA6IZ,OAAO;CAGP"}
@@ -0,0 +1,196 @@
1
+ import { __awaiter } from "tslib";
2
+ import { MarkdownRenderer, Modal } from "obsidian";
3
+ import { formatChangelogSections, getChangelogSince } from "../string/changelog-parser";
4
+ /**
5
+ * Default URLs for the What's New modal.
6
+ * These can be overridden in the config.
7
+ */
8
+ export const DEFAULT_WHATS_NEW_LINKS = {
9
+ /**
10
+ * Default tools page showcasing all plugins and productivity software.
11
+ */
12
+ TOOLS: "https://matejvavroproductivity.com/tools/",
13
+ /**
14
+ * Default YouTube channel with Obsidian tutorials and productivity tips.
15
+ * Includes subscription confirmation parameter.
16
+ */
17
+ YOUTUBE: "https://www.youtube.com/@MatejVavroProductivity?sub_confirmation=1",
18
+ };
19
+ /**
20
+ * Generic "What's New" modal that displays changelog entries between versions.
21
+ * Supports custom CSS prefixes, plugin names, and configurable links.
22
+ */
23
+ export class WhatsNewModal extends Modal {
24
+ constructor(app, plugin, config, fromVersion, toVersion) {
25
+ super(app);
26
+ this.plugin = plugin;
27
+ this.config = config;
28
+ this.fromVersion = fromVersion;
29
+ this.toVersion = toVersion;
30
+ }
31
+ /**
32
+ * Helper to create CSS class names with the configured prefix.
33
+ */
34
+ cls(suffix) {
35
+ return `${this.config.cssPrefix}-${suffix}`;
36
+ }
37
+ /**
38
+ * Helper to add CSS class to an element.
39
+ */
40
+ addCls(el, suffix) {
41
+ el.classList.add(this.cls(suffix));
42
+ }
43
+ /**
44
+ * Makes external links in rendered markdown clickable by adding click handlers.
45
+ * Handles both absolute URLs (http/https) and relative URLs (starting with /).
46
+ * Relative URLs are resolved against the documentation base URL.
47
+ */
48
+ makeExternalLinksClickable(container) {
49
+ const links = container.querySelectorAll("a[href]");
50
+ // Convert NodeList to Array for iteration
51
+ Array.from(links).forEach((link) => {
52
+ const href = link.getAttribute("href");
53
+ if (!href)
54
+ return;
55
+ let finalUrl = null;
56
+ // Handle absolute HTTP(S) links
57
+ if (href.startsWith("http://") || href.startsWith("https://")) {
58
+ finalUrl = href;
59
+ }
60
+ // Handle relative links (starting with /)
61
+ else if (href.startsWith("/")) {
62
+ // Get base documentation URL and ensure proper slash handling
63
+ const baseUrl = this.config.links.documentation;
64
+ const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
65
+ finalUrl = `${normalizedBase}${href}`;
66
+ }
67
+ // Add click handler for external links
68
+ if (finalUrl) {
69
+ link.addEventListener("click", (event) => {
70
+ event.preventDefault();
71
+ window.open(finalUrl, "_blank");
72
+ });
73
+ // Add visual indicator that it's an external link
74
+ link.classList.add("external-link");
75
+ }
76
+ });
77
+ }
78
+ onOpen() {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ var _a, _b;
81
+ const { contentEl } = this;
82
+ contentEl.empty();
83
+ this.addCls(contentEl, "whats-new-modal");
84
+ // Header section
85
+ const header = contentEl.createDiv({ cls: this.cls("whats-new-header") });
86
+ header.createEl("h2", {
87
+ text: `${this.config.pluginName} updated to v${this.toVersion}`,
88
+ });
89
+ header.createEl("p", {
90
+ text: `Changes since v${this.fromVersion}`,
91
+ cls: this.cls("whats-new-subtitle"),
92
+ });
93
+ // Support section
94
+ const supportSection = contentEl.createDiv({
95
+ cls: this.cls("whats-new-support"),
96
+ });
97
+ supportSection.createEl("h3", { text: "Support My Work" });
98
+ const supportText = supportSection.createEl("p");
99
+ supportText.createSpan({ text: "If you enjoy using this plugin, please consider " });
100
+ supportText.createEl("a", {
101
+ text: "supporting my work",
102
+ href: this.config.links.support,
103
+ });
104
+ supportText.createSpan({
105
+ text: ". Your support helps keep this plugin maintained and improved!",
106
+ });
107
+ // Discover more section
108
+ const discoverSection = contentEl.createDiv({
109
+ cls: this.cls("whats-new-discover"),
110
+ });
111
+ discoverSection.createEl("h3", { text: "Discover More" });
112
+ // Other tools
113
+ const toolsText = discoverSection.createEl("p");
114
+ toolsText.createSpan({ text: "🔧 Check out my " });
115
+ toolsText.createEl("a", {
116
+ text: "other plugins and productivity tools",
117
+ href: (_a = this.config.links.tools) !== null && _a !== void 0 ? _a : DEFAULT_WHATS_NEW_LINKS.TOOLS,
118
+ });
119
+ toolsText.createSpan({
120
+ text: " to enhance your workflow even further.",
121
+ });
122
+ // YouTube channel
123
+ const youtubeText = discoverSection.createEl("p");
124
+ youtubeText.createSpan({ text: "📺 Subscribe to my " });
125
+ youtubeText.createEl("a", {
126
+ text: "YouTube channel",
127
+ href: (_b = this.config.links.youtube) !== null && _b !== void 0 ? _b : DEFAULT_WHATS_NEW_LINKS.YOUTUBE,
128
+ });
129
+ youtubeText.createSpan({
130
+ text: " for Obsidian tutorials and productivity tips!",
131
+ });
132
+ contentEl.createEl("hr");
133
+ // Changelog content
134
+ const changelogSections = getChangelogSince(this.config.changelogContent, this.fromVersion, this.toVersion);
135
+ if (changelogSections.length === 0) {
136
+ contentEl.createEl("p", {
137
+ text: "No significant changes found in this update.",
138
+ cls: this.cls("whats-new-empty"),
139
+ });
140
+ }
141
+ else {
142
+ const changelogContainer = contentEl.createDiv({
143
+ cls: this.cls("whats-new-content"),
144
+ });
145
+ const markdownContent = formatChangelogSections(changelogSections);
146
+ yield MarkdownRenderer.render(this.app, markdownContent, changelogContainer, "/", this.plugin);
147
+ // Make external links clickable
148
+ this.makeExternalLinksClickable(changelogContainer);
149
+ }
150
+ // Action buttons
151
+ const buttonContainer = contentEl.createDiv({
152
+ cls: this.cls("whats-new-buttons"),
153
+ });
154
+ // Full changelog button
155
+ const changelogBtn = buttonContainer.createEl("button", {
156
+ text: "Full Changelog",
157
+ });
158
+ changelogBtn.addEventListener("click", () => {
159
+ window.open(this.config.links.changelog, "_blank");
160
+ });
161
+ // Documentation button
162
+ const docsBtn = buttonContainer.createEl("button", {
163
+ text: "Documentation",
164
+ });
165
+ docsBtn.addEventListener("click", () => {
166
+ window.open(this.config.links.documentation, "_blank");
167
+ });
168
+ // Tools button
169
+ const toolsBtn = buttonContainer.createEl("button", {
170
+ text: "My Tools",
171
+ });
172
+ toolsBtn.addEventListener("click", () => {
173
+ var _a;
174
+ window.open((_a = this.config.links.tools) !== null && _a !== void 0 ? _a : DEFAULT_WHATS_NEW_LINKS.TOOLS, "_blank");
175
+ });
176
+ // YouTube button
177
+ const youtubeBtn = buttonContainer.createEl("button", {
178
+ text: "YouTube Channel",
179
+ });
180
+ youtubeBtn.addEventListener("click", () => {
181
+ var _a;
182
+ window.open((_a = this.config.links.youtube) !== null && _a !== void 0 ? _a : DEFAULT_WHATS_NEW_LINKS.YOUTUBE, "_blank");
183
+ });
184
+ // Close button (always present)
185
+ const closeBtn = buttonContainer.createEl("button", {
186
+ text: "Close",
187
+ cls: this.cls("mod-cta"),
188
+ });
189
+ closeBtn.addEventListener("click", () => this.close());
190
+ });
191
+ }
192
+ onClose() {
193
+ this.contentEl.empty();
194
+ }
195
+ }
196
+ //# sourceMappingURL=whats-new-modal.js.map