joplin-plugin-minimap 1.1.7 → 1.1.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joplin-plugin-minimap",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "A hover-to-expand table of contents minimap for the Joplin note viewer",
5
5
  "author": "lim0513",
6
6
  "homepage": "https://github.com/lim0513/joplin-minimap",
package/publish/index.js CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  // SettingItemType numeric values: Int=1, String=2, Bool=3 (no 'api' import in plain JS)
8
8
  const TYPE_INT = 1;
9
+ const TYPE_BOOL = 3;
9
10
 
10
11
  // Settings-screen strings, resolved from the app locale at registration time
11
12
  // (matching Joplin's own restart-on-language-switch behavior).
@@ -17,6 +18,8 @@ const SETTINGS_I18N = {
17
18
  panelWidthDesc: 'Maximum width of the hover-expanded table of contents. Default: 240.',
18
19
  rightOffset: 'Distance from right edge (px)',
19
20
  rightOffsetDesc: 'Gap between the minimap and the right edge of the viewer. Default: 6.',
21
+ showTodos: 'Show to-do markers',
22
+ showTodosDesc: 'Show a small red dot before a section\'s tick bar when it contains open to-dos. Default: on.',
20
23
  },
21
24
  zh_CN: {
22
25
  minHeadings: '最少标题数',
@@ -25,6 +28,8 @@ const SETTINGS_I18N = {
25
28
  panelWidthDesc: '悬停展开的目录面板最大宽度。默认 240。',
26
29
  rightOffset: '距右边缘距离(px)',
27
30
  rightOffsetDesc: '小地图与阅读器右边缘的间距。默认 6。',
31
+ showTodos: '显示待办标记',
32
+ showTodosDesc: '当章节内含未完成待办时,在该章节横线前显示一个小红点提醒。默认开启。',
28
33
  },
29
34
  zh_TW: {
30
35
  minHeadings: '最少標題數',
@@ -33,6 +38,8 @@ const SETTINGS_I18N = {
33
38
  panelWidthDesc: '懸停展開的目錄面板最大寬度。預設 240。',
34
39
  rightOffset: '距右邊緣距離(px)',
35
40
  rightOffsetDesc: '小地圖與檢視器右邊緣的間距。預設 6。',
41
+ showTodos: '顯示待辦標記',
42
+ showTodosDesc: '當章節內含未完成待辦時,在該章節橫線前顯示一個小紅點提醒。預設開啟。',
36
43
  },
37
44
  ru: {
38
45
  minHeadings: 'Минимум заголовков',
@@ -41,6 +48,8 @@ const SETTINGS_I18N = {
41
48
  panelWidthDesc: 'Максимальная ширина оглавления при наведении. По умолчанию: 240.',
42
49
  rightOffset: 'Отступ от правого края (px)',
43
50
  rightOffsetDesc: 'Зазор между миникартой и правым краем просмотра. По умолчанию: 6.',
51
+ showTodos: 'Показывать метки задач',
52
+ showTodosDesc: 'Показывать маленькую красную точку перед линией раздела, если в нём есть открытые задачи. По умолчанию: вкл.',
44
53
  },
45
54
  ja_JP: {
46
55
  minHeadings: '最小見出し数',
@@ -49,6 +58,8 @@ const SETTINGS_I18N = {
49
58
  panelWidthDesc: 'ホバーで展開する目次の最大幅。既定値:240。',
50
59
  rightOffset: '右端からの距離(px)',
51
60
  rightOffsetDesc: 'ミニマップとビューアー右端の間隔。既定値:6。',
61
+ showTodos: 'ToDoマーカーを表示',
62
+ showTodosDesc: '未完了のToDoを含むセクションの線の前に小さな赤い点を表示します。既定値:オン。',
52
63
  },
53
64
  };
54
65
 
@@ -100,6 +111,14 @@ joplin.plugins.register({
100
111
  label: t.rightOffset,
101
112
  description: t.rightOffsetDesc,
102
113
  },
114
+ 'minimapShowTodos': {
115
+ value: true,
116
+ type: TYPE_BOOL,
117
+ section: 'minimap',
118
+ public: true,
119
+ label: t.showTodos,
120
+ description: t.showTodosDesc,
121
+ },
103
122
  });
104
123
  } catch (error) {
105
124
  console.error('Joplin Minimap: registerSettings failed:', error);
@@ -117,6 +136,7 @@ joplin.plugins.register({
117
136
  minHeadings: await joplin.settings.value('minimapMinHeadings'),
118
137
  panelWidth: await joplin.settings.value('minimapPanelWidth'),
119
138
  rightOffset: await joplin.settings.value('minimapRightOffset'),
139
+ showTodos: await joplin.settings.value('minimapShowTodos'),
120
140
  };
121
141
  }
122
142
  return null;
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 1,
3
3
  "id": "com.github.joplin-minimap",
4
4
  "app_min_version": "2.8",
5
- "version": "1.1.7",
5
+ "version": "1.1.8",
6
6
  "name": "Joplin Minimap",
7
7
  "description": "A hover-to-expand table of contents minimap for the note viewer. Shows heading tick marks on the right edge; hover to expand into a full ToC, click to jump.",
8
8
  "author": "lim0513",
@@ -8,7 +8,7 @@
8
8
 
9
9
  // Defaults; overridden from Joplin's plugin settings (Tools > Options > Minimap)
10
10
  // when webviewApi is available in this webview.
11
- var settings = { minHeadings: 2, panelWidth: 240, rightOffset: 6 };
11
+ var settings = { minHeadings: 2, panelWidth: 240, rightOffset: 6, showTodos: true };
12
12
 
13
13
  function loadSettings() {
14
14
  if (typeof webviewApi === 'undefined' || !webviewApi.postMessage) {
@@ -47,7 +47,7 @@
47
47
  // then renders UNSTYLED as flow content below the note (looks like a
48
48
  // duplicated outline under the document). Keeping the CSS inline and
49
49
  // re-injecting guarantees the nav and its styling live and die together.
50
- var MINIMAP_CSS = "/* Joplin Minimap \u2014 collapsed tick bars, hover-expanded ToC panel.\n * Colors use currentColor / rgba so it follows both light and dark themes.\n */\n\n#jp-minimap {\n\tuser-select: none;\n\t-webkit-user-select: none;\n\tcaret-color: transparent;\n\tcursor: default;\n\tposition: fixed;\n\ttop: 50%;\n\tright: 6px;\n\ttransform: translateY(-50%);\n\tz-index: 9999;\n\tfont-size: 12.5px;\n\tline-height: 1.35;\n\tcolor: inherit;\n}\n\n.jp-mm-list {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-end;\n\tpadding: 8px 6px;\n\tmax-height: 84vh;\n\toverflow: hidden;\n\tborder-radius: 10px;\n\ttransition: background 0.15s ease, box-shadow 0.15s ease;\n}\n\n.jp-mm-item {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tpadding: 3px 4px;\n\tborder-radius: 6px;\n\ttext-decoration: none;\n\tcolor: inherit;\n\topacity: 0.5;\n\tcursor: pointer;\n\toutline: none;\n}\n\n/* ---- collapsed state: tick bars, width by heading level ---- */\n\n.jp-mm-bar {\n\tdisplay: block;\n\theight: 2px;\n\tborder-radius: 1px;\n\tbackground: currentColor;\n}\n\n.jp-mm-l1 .jp-mm-bar { width: 18px; }\n.jp-mm-l2 .jp-mm-bar { width: 13px; }\n.jp-mm-l3 .jp-mm-bar { width: 9px; }\n.jp-mm-l4 .jp-mm-bar { width: 7px; }\n.jp-mm-l5 .jp-mm-bar { width: 5px; }\n.jp-mm-l6 .jp-mm-bar { width: 5px; }\n\n.jp-mm-label { display: none; }\n\n/* ---- expanded state (hover) ---- */\n\n#jp-minimap:hover .jp-mm-list {\n\talign-items: stretch;\n\toverflow-y: auto;\n\toverscroll-behavior: contain;\n\tbackground: rgba(127, 127, 127, 0.16);\n\tbackdrop-filter: blur(10px);\n\t-webkit-backdrop-filter: blur(10px);\n\tbox-shadow: 0 6px 28px rgba(0, 0, 0, 0.28);\n}\n\n#jp-minimap:hover .jp-mm-bar { display: none; }\n\n#jp-minimap:hover .jp-mm-item { justify-content: flex-start; }\n\n#jp-minimap:hover .jp-mm-label {\n\tdisplay: block;\n\tmax-width: var(--jp-mm-width, 240px);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n/* indent by heading level when expanded */\n#jp-minimap:hover .jp-mm-l2 { padding-left: 16px; }\n#jp-minimap:hover .jp-mm-l3 { padding-left: 28px; }\n#jp-minimap:hover .jp-mm-l4 { padding-left: 40px; }\n#jp-minimap:hover .jp-mm-l5 { padding-left: 52px; }\n#jp-minimap:hover .jp-mm-l6 { padding-left: 52px; }\n\n/* ---- shared states ---- */\n\n.jp-mm-item:hover {\n\topacity: 1;\n\tbackground: rgba(127, 127, 127, 0.22);\n}\n\n.jp-mm-active { opacity: 1; }\n\n#jp-minimap:hover .jp-mm-active {\n\tbackground: rgba(127, 127, 127, 0.18);\n}\n\n/* No scrollbar in the expanded panel: the wheel handler owns scrolling,\n * and a visible scrollbar at the panel edge invites overlay-scrollbar\n * style hover/click interference. */\n.jp-mm-list::-webkit-scrollbar { display: none; }\n.jp-mm-list { scrollbar-width: none; }\n\n/* don't show over printed/exported output */\n@media print {\n\t#jp-minimap { display: none; }\n}\n";
50
+ var MINIMAP_CSS = "/* Joplin Minimap \u2014 collapsed tick bars, hover-expanded ToC panel.\n * Colors use currentColor / rgba so it follows both light and dark themes.\n */\n\n#jp-minimap {\n\tuser-select: none;\n\t-webkit-user-select: none;\n\tcaret-color: transparent;\n\tcursor: default;\n\tposition: fixed;\n\ttop: 50%;\n\tright: 6px;\n\ttransform: translateY(-50%);\n\tz-index: 9999;\n\tfont-size: 12.5px;\n\tline-height: 1.35;\n\tcolor: inherit;\n}\n\n.jp-mm-list {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-end;\n\tpadding: 8px 6px;\n\tmax-height: 84vh;\n\toverflow: hidden;\n\tborder-radius: 10px;\n\ttransition: background 0.15s ease, box-shadow 0.15s ease;\n}\n\n.jp-mm-item {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tpadding: 3px 4px;\n\tborder-radius: 6px;\n\ttext-decoration: none;\n\tcolor: inherit;\n\topacity: 0.5;\n\tcursor: pointer;\n\toutline: none;\n}\n\n/* ---- collapsed state: tick bars, width by heading level ---- */\n\n.jp-mm-bar {\n\tdisplay: block;\n\theight: 2px;\n\tborder-radius: 1px;\n\tbackground: currentColor;\n}\n\n.jp-mm-l1 .jp-mm-bar { width: 18px; }\n.jp-mm-l2 .jp-mm-bar { width: 13px; }\n.jp-mm-l3 .jp-mm-bar { width: 9px; }\n.jp-mm-l4 .jp-mm-bar { width: 7px; }\n.jp-mm-l5 .jp-mm-bar { width: 5px; }\n.jp-mm-l6 .jp-mm-bar { width: 5px; }\n\n.jp-mm-label { display: none; }\n\n/* ---- expanded state (hover) ---- */\n\n#jp-minimap:hover .jp-mm-list {\n\talign-items: stretch;\n\toverflow-y: auto;\n\toverscroll-behavior: contain;\n\tbackground: rgba(127, 127, 127, 0.16);\n\tbackdrop-filter: blur(10px);\n\t-webkit-backdrop-filter: blur(10px);\n\tbox-shadow: 0 6px 28px rgba(0, 0, 0, 0.28);\n}\n\n#jp-minimap:hover .jp-mm-bar { display: none; }\n\n#jp-minimap:hover .jp-mm-item { justify-content: flex-start; }\n\n#jp-minimap:hover .jp-mm-label {\n\tdisplay: block;\n\tmax-width: var(--jp-mm-width, 240px);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n/* indent by heading level when expanded */\n#jp-minimap:hover .jp-mm-l2 { padding-left: 16px; }\n#jp-minimap:hover .jp-mm-l3 { padding-left: 28px; }\n#jp-minimap:hover .jp-mm-l4 { padding-left: 40px; }\n#jp-minimap:hover .jp-mm-l5 { padding-left: 52px; }\n#jp-minimap:hover .jp-mm-l6 { padding-left: 52px; }\n\n/* ---- shared states ---- */\n\n.jp-mm-item:hover {\n\topacity: 1;\n\tbackground: rgba(127, 127, 127, 0.22);\n}\n\n.jp-mm-active { opacity: 1; }\n\n#jp-minimap:hover .jp-mm-active {\n\tbackground: rgba(127, 127, 127, 0.18);\n}\n\n/* No scrollbar in the expanded panel: the wheel handler owns scrolling,\n * and a visible scrollbar at the panel edge invites overlay-scrollbar\n * style hover/click interference. */\n.jp-mm-list::-webkit-scrollbar { display: none; }\n.jp-mm-list { scrollbar-width: none; }\n\n/* ---- open-to-do section dot: one muted red dot before the tick bar of\n * any section that contains at least one unchecked checkbox ---- */\n.jp-mm-dot {\n\tdisplay: block;\n\twidth: 4px;\n\theight: 4px;\n\tborder-radius: 50%;\n\tbackground: rgba(205, 97, 85, 0.85);\n\tmargin-right: 5px;\n\tflex: none;\n}\n\n/* don't show over printed/exported output */\n@media print {\n\t#jp-minimap { display: none; }\n}\n";
51
51
 
52
52
  function ensureStyle() {
53
53
  if (document.getElementById('jp-minimap-style')) return;
@@ -116,6 +116,23 @@
116
116
  );
117
117
  if (headings.length < settings.minHeadings) return;
118
118
 
119
+ // Which sections contain at least one OPEN checkbox: walk headings and
120
+ // checkboxes in one document-ordered pass, attributing each unchecked
121
+ // box to the nearest preceding heading. One dot per section, however
122
+ // many open to-dos it holds.
123
+ var sectionHasTodo = {};
124
+ if (settings.showTodos !== false) {
125
+ var walk = Array.prototype.slice.call(
126
+ root.querySelectorAll('h1, h2, h3, h4, h5, h6, input[type="checkbox"]')
127
+ );
128
+ var lastHeading = -1;
129
+ for (var wi = 0; wi < walk.length; wi++) {
130
+ var wn = walk[wi];
131
+ if (/^H[1-6]$/.test(wn.tagName)) lastHeading++;
132
+ else if (!wn.checked && lastHeading >= 0) sectionHasTodo[lastHeading] = true;
133
+ }
134
+ }
135
+
119
136
  var nav = document.createElement('nav');
120
137
  nav.id = 'jp-minimap';
121
138
  // Applied in BOTH collapsed and expanded states: shifting only on hover
@@ -156,6 +173,13 @@
156
173
  label.className = 'jp-mm-label';
157
174
  label.textContent = (h.textContent || '').trim();
158
175
 
176
+ // Muted red reminder dot before the bar (and before the label when
177
+ // expanded - same element, flex order does the work).
178
+ if (sectionHasTodo[index]) {
179
+ var dot = document.createElement('span');
180
+ dot.className = 'jp-mm-dot';
181
+ item.appendChild(dot);
182
+ }
159
183
  item.appendChild(bar);
160
184
  item.appendChild(label);
161
185
 
Binary file