kingkont 0.7.88 → 0.7.89
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 +1 -1
- package/renderer/settings.js +25 -1
- package/renderer/styles.css +11 -3
package/package.json
CHANGED
package/renderer/settings.js
CHANGED
|
@@ -123,6 +123,25 @@ function renderLabelNodeBody(node, body) {
|
|
|
123
123
|
ed.textContent = node.text || '';
|
|
124
124
|
applyLabelStyle(ed, node.textStyle);
|
|
125
125
|
|
|
126
|
+
// Принудительно держим класс is-empty синхронизированным с textContent.
|
|
127
|
+
// CSS-селектор :empty не годится — после стирания всего текста браузер
|
|
128
|
+
// часто оставляет <br> внутри contenteditable, и :empty перестаёт
|
|
129
|
+
// матчить → плейсхолдер пропадал, инлайн-блок схлопывался по ширине,
|
|
130
|
+
// юзер кликал мимо и терял фокус. Класс на основе textContent надёжнее.
|
|
131
|
+
const syncEmpty = () => {
|
|
132
|
+
const empty = !ed.textContent || ed.textContent.length === 0;
|
|
133
|
+
ed.classList.toggle('is-empty', empty);
|
|
134
|
+
// Если контент стал «пустым», но в DOM остался шум (br/пустые text-node) —
|
|
135
|
+
// чистим innerHTML, чтобы курсор спокойно стоял в начале без артефактов.
|
|
136
|
+
// НЕ делаем если уже пусто — иначе зацикливание input-события.
|
|
137
|
+
if (empty && ed.innerHTML !== '' && ed.isContentEditable) {
|
|
138
|
+
// Сохраняем фокус: clearing innerHTML на сфокусированном
|
|
139
|
+
// contenteditable не должен дёргать blur, но сохраним ranged selection.
|
|
140
|
+
ed.innerHTML = '';
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
syncEmpty();
|
|
144
|
+
|
|
126
145
|
const enterEditMode = () => {
|
|
127
146
|
if (ed.isContentEditable) return;
|
|
128
147
|
ed.contentEditable = 'plaintext-only';
|
|
@@ -141,6 +160,7 @@ function renderLabelNodeBody(node, body) {
|
|
|
141
160
|
// closest('[contenteditable]') в обработчиках вне (dblclick/contextmenu)
|
|
142
161
|
// не матчился — и ПКМ снова открывал наш node-menu.
|
|
143
162
|
ed.removeAttribute('contenteditable');
|
|
163
|
+
syncEmpty();
|
|
144
164
|
};
|
|
145
165
|
|
|
146
166
|
ed.addEventListener('dblclick', e => {
|
|
@@ -148,7 +168,11 @@ function renderLabelNodeBody(node, body) {
|
|
|
148
168
|
enterEditMode();
|
|
149
169
|
});
|
|
150
170
|
ed.addEventListener('blur', exitEditMode);
|
|
151
|
-
ed.addEventListener('input', () => {
|
|
171
|
+
ed.addEventListener('input', () => {
|
|
172
|
+
node.text = ed.textContent;
|
|
173
|
+
syncEmpty();
|
|
174
|
+
scheduleSave();
|
|
175
|
+
});
|
|
152
176
|
ed.addEventListener('keydown', e => {
|
|
153
177
|
if (e.key === 'Escape') { e.preventDefault(); ed.blur(); }
|
|
154
178
|
});
|
package/renderer/styles.css
CHANGED
|
@@ -510,15 +510,23 @@
|
|
|
510
510
|
всё равно имеет высоту хотя бы одной строки выбранного шрифта. */
|
|
511
511
|
min-height: 1.5em;
|
|
512
512
|
}
|
|
513
|
-
|
|
513
|
+
/* Плейсхолдер показываем по классу is-empty (а не :empty pseudo) —
|
|
514
|
+
selector :empty ломается когда браузер оставляет <br> в contenteditable
|
|
515
|
+
после Cmd+A/Backspace. JS ставит/снимает класс по textContent. */
|
|
516
|
+
.node.label-node .label-text.is-empty::before {
|
|
514
517
|
content: attr(data-placeholder);
|
|
515
518
|
color: rgba(200,200,200,0.55);
|
|
516
519
|
}
|
|
520
|
+
/* Гарантированный размер пустой ноды — чтобы юзер не терял её визуально
|
|
521
|
+
(кликабельная область + плейсхолдер). */
|
|
522
|
+
.node.label-node .label-text.is-empty {
|
|
523
|
+
min-width: 240px;
|
|
524
|
+
}
|
|
517
525
|
/* Когда label пустая — рисуем подсказывающий dashed-контур, чтобы юзер
|
|
518
526
|
видел что нода существует (текст-плейсхолдер мог быть не замечен).
|
|
519
527
|
При наличии текста — никакой рамки, чисто подпись на холсте. */
|
|
520
|
-
.node.label-node:has(.label-text
|
|
521
|
-
outline: 1px dashed rgba(200,200,200,0.
|
|
528
|
+
.node.label-node:has(.label-text.is-empty) {
|
|
529
|
+
outline: 1px dashed rgba(200,200,200,0.35);
|
|
522
530
|
outline-offset: 1px;
|
|
523
531
|
border-radius: 3px;
|
|
524
532
|
}
|