feat(cafe24): HTML 편집기 Shift+Delete 줄 삭제
커서가 있는 줄(선택이 있으면 그 줄들)을 통째로 지운다. 윈도우 기본 동작인
"잘라내기"를 대신한다.
- 줄바꿈까지 함께 지워 빈 줄이 남지 않게 한다. 마지막 줄이면 대신 앞의
줄바꿈을 지운다(문서 끝에 빈 줄이 생기지 않게).
- 커서는 지운 자리로 올라온 줄의 같은 칸에 둔다(칸이 모자라면 줄 끝).
- 빈 문자열은 insertText 가 브라우저에 따라 무시되므로 applyEdit 이
execCommand("delete") 로 갈라진다. Ctrl+Z 는 그대로 동작한다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -78,7 +78,7 @@
|
|||||||
<input type="hidden" name="list_query" value="{{ list_query }}" />
|
<input type="hidden" name="list_query" value="{{ list_query }}" />
|
||||||
|
|
||||||
<div class="cf24-editor-bar">
|
<div class="cf24-editor-bar">
|
||||||
<span class="cf24-muted">상세설명 HTML · {{ desc.description | length }}자 · PC/모바일 공통 · Ctrl+/ 주석 · Alt+↑↓ 줄 이동</span>
|
<span class="cf24-muted">상세설명 HTML · {{ desc.description | length }}자 · PC/모바일 공통 · Ctrl+/ 주석 · Alt+↑↓ 줄 이동 · Shift+Del 줄 삭제</span>
|
||||||
<span class="cf24-editor-bar-right">
|
<span class="cf24-editor-bar-right">
|
||||||
<input class="cf24-memo" type="text" name="memo" maxlength="200"
|
<input class="cf24-memo" type="text" name="memo" maxlength="200"
|
||||||
placeholder="변경 메모 (버전 이력에 남습니다)" />
|
placeholder="변경 메모 (버전 이력에 남습니다)" />
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
<pre class="cf24-code-hl" id="cf24-hl-pc" aria-hidden="true"></pre>
|
<pre class="cf24-code-hl" id="cf24-hl-pc" aria-hidden="true"></pre>
|
||||||
<textarea id="cf24-html-pc" class="cf24-code-input" name="html" wrap="off"
|
<textarea id="cf24-html-pc" class="cf24-code-input" name="html" wrap="off"
|
||||||
spellcheck="false" autocapitalize="off" autocorrect="off"
|
spellcheck="false" autocapitalize="off" autocorrect="off"
|
||||||
title="Tab 들여쓰기 · Ctrl+/ 주석 토글 · Alt+↑/↓ 줄 이동 · Alt+Shift+↑/↓ 줄 복사 (선택이 없으면 커서가 있는 줄)">{{ html_pc }}</textarea>
|
title="Tab 들여쓰기 · Ctrl+/ 주석 토글 · Alt+↑/↓ 줄 이동 · Alt+Shift+↑/↓ 줄 복사 · Shift+Delete 줄 삭제 (선택이 없으면 커서가 있는 줄)">{{ html_pc }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -209,7 +209,12 @@
|
|||||||
ta.selectionStart = from;
|
ta.selectionStart = from;
|
||||||
ta.selectionEnd = to;
|
ta.selectionEnd = to;
|
||||||
var inserted = false;
|
var inserted = false;
|
||||||
try { inserted = document.execCommand("insertText", false, text); } catch (err) { inserted = false; }
|
try {
|
||||||
|
// 빈 문자열은 insertText 가 브라우저에 따라 무시된다 — 삭제는 delete 로.
|
||||||
|
inserted = text === ""
|
||||||
|
? document.execCommand("delete")
|
||||||
|
: document.execCommand("insertText", false, text);
|
||||||
|
} catch (err) { inserted = false; }
|
||||||
if (!inserted) ta.value = value.slice(0, from) + text + value.slice(to);
|
if (!inserted) ta.value = value.slice(0, from) + text + value.slice(to);
|
||||||
ta.selectionStart = selStart;
|
ta.selectionStart = selStart;
|
||||||
ta.selectionEnd = selEnd;
|
ta.selectionEnd = selEnd;
|
||||||
@@ -288,6 +293,25 @@
|
|||||||
applyEdit(r.from, r.to, text, r.start + shift, r.end + shift);
|
applyEdit(r.from, r.to, text, r.start + shift, r.end + shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shift+Delete — 커서가 있는 줄(선택이 있으면 그 줄들)을 통째로 지운다.
|
||||||
|
줄바꿈까지 같이 지워야 빈 줄이 남지 않는다. 마지막 줄이면 대신 앞의
|
||||||
|
줄바꿈을 지운다(문서 끝에 빈 줄이 생기지 않게). */
|
||||||
|
function deleteLines() {
|
||||||
|
var r = lineRange();
|
||||||
|
var from = r.from, to = r.to;
|
||||||
|
if (to < r.value.length) to += 1;
|
||||||
|
else if (from > 0) from -= 1;
|
||||||
|
if (from === to) return; // 빈 문서 — 지울 것이 없다
|
||||||
|
|
||||||
|
var rest = r.value.slice(0, from) + r.value.slice(to);
|
||||||
|
// 커서는 지운 자리로 올라온 줄의 같은 칸에 둔다(칸이 모자라면 줄 끝).
|
||||||
|
var lineFrom = rest.lastIndexOf("\n", from - 1) + 1;
|
||||||
|
var lineTo = rest.indexOf("\n", lineFrom);
|
||||||
|
if (lineTo === -1) lineTo = rest.length;
|
||||||
|
var col = Math.min(Math.max(0, r.start - r.from), lineTo - lineFrom);
|
||||||
|
applyEdit(from, to, "", lineFrom + col, lineFrom + col);
|
||||||
|
}
|
||||||
|
|
||||||
ta.addEventListener("scroll", sync);
|
ta.addEventListener("scroll", sync);
|
||||||
ta.addEventListener("input", function () { dirty = true; refresh(); });
|
ta.addEventListener("input", function () { dirty = true; refresh(); });
|
||||||
ta.addEventListener("keydown", function (e) {
|
ta.addEventListener("keydown", function (e) {
|
||||||
@@ -307,6 +331,13 @@
|
|||||||
else moveLines(isDown);
|
else moveLines(isDown);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Shift+Delete — 줄 삭제. (윈도우 기본 동작인 "잘라내기"를 대신한다)
|
||||||
|
if (e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey &&
|
||||||
|
(e.key === "Delete" || e.code === "Delete")) {
|
||||||
|
e.preventDefault();
|
||||||
|
deleteLines();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Tab 은 포커스 이동이 아니라 들여쓰기로 쓴다.
|
// Tab 은 포커스 이동이 아니라 들여쓰기로 쓴다.
|
||||||
if (e.key !== "Tab") return;
|
if (e.key !== "Tab") return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
Reference in New Issue
Block a user