ponkotsu-md-editor 0.1.14 → 0.1.15
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/markdown_editor.js +93 -33
- data/lib/ponkotsu/md/editor/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29d6bd2ad67f2660ed6e4f5f06a74c651e83df68d222ffcf46ac1d1e494bd24f
|
|
4
|
+
data.tar.gz: e32efc8ec6b6aa356c22bd947fcdee62eaf5ae59f3d1ce044aeae16915d69053
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc5903d157a698f86923edaa038ea904ac8f0cf0043a746fb7e57c1eb5653a309c57f855cd647705035ae4b28a4802d8979918560e0a047ebbcbd6a23c99fb6d
|
|
7
|
+
data.tar.gz: 2c4b514c879389f11f958ca95b8221c8bc2b5befc723b873798500bf79efcad1ed25a7dc0a7d9cc859c39ab224f4250df342a40b85e84f3bbc6880562b7ed715
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
let isPreviewMode = false;
|
|
32
32
|
|
|
33
|
-
// contenteditable
|
|
33
|
+
// contenteditable要素用の選択範囲取得・設定機能(改行対応版)
|
|
34
34
|
function getContentEditableSelection(element) {
|
|
35
35
|
const selection = window.getSelection();
|
|
36
36
|
if (selection.rangeCount === 0) {
|
|
@@ -39,28 +39,52 @@
|
|
|
39
39
|
|
|
40
40
|
const range = selection.getRangeAt(0);
|
|
41
41
|
|
|
42
|
-
//
|
|
43
|
-
const
|
|
42
|
+
// テキストノードを順次処理して正確な位置を計算
|
|
43
|
+
const walker = document.createTreeWalker(
|
|
44
|
+
element,
|
|
45
|
+
NodeFilter.SHOW_TEXT,
|
|
46
|
+
null,
|
|
47
|
+
false
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
let currentOffset = 0;
|
|
51
|
+
let startOffset = 0;
|
|
52
|
+
let endOffset = 0;
|
|
53
|
+
let foundStart = false;
|
|
54
|
+
let foundEnd = false;
|
|
55
|
+
|
|
56
|
+
let node;
|
|
57
|
+
while (node = walker.nextNode()) {
|
|
58
|
+
const nodeText = node.textContent;
|
|
59
|
+
const nodeLength = nodeText.length;
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
// 開始位置の検出
|
|
62
|
+
if (!foundStart && node === range.startContainer) {
|
|
63
|
+
startOffset = currentOffset + range.startOffset;
|
|
64
|
+
foundStart = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 終了位置の検出
|
|
68
|
+
if (!foundEnd && node === range.endContainer) {
|
|
69
|
+
endOffset = currentOffset + range.endOffset;
|
|
70
|
+
foundEnd = true;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
currentOffset += nodeLength;
|
|
75
|
+
}
|
|
50
76
|
|
|
51
|
-
//
|
|
77
|
+
// 選択されたテキストを取得
|
|
52
78
|
const selectedText = range.toString();
|
|
53
|
-
const end = start + selectedText.length;
|
|
54
79
|
|
|
55
80
|
return {
|
|
56
|
-
start:
|
|
57
|
-
end:
|
|
81
|
+
start: startOffset,
|
|
82
|
+
end: endOffset,
|
|
58
83
|
selectedText: selectedText
|
|
59
84
|
};
|
|
60
85
|
}
|
|
61
86
|
|
|
62
87
|
function setContentEditableSelection(element, start, end) {
|
|
63
|
-
const textNodes = [];
|
|
64
88
|
const walker = document.createTreeWalker(
|
|
65
89
|
element,
|
|
66
90
|
NodeFilter.SHOW_TEXT,
|
|
@@ -68,43 +92,79 @@
|
|
|
68
92
|
false
|
|
69
93
|
);
|
|
70
94
|
|
|
71
|
-
let node;
|
|
72
|
-
while (node = walker.nextNode()) {
|
|
73
|
-
textNodes.push(node);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
95
|
let currentOffset = 0;
|
|
77
|
-
let startNode = null,
|
|
78
|
-
let endNode = null,
|
|
96
|
+
let startNode = null, startNodeOffset = 0;
|
|
97
|
+
let endNode = null, endNodeOffset = 0;
|
|
79
98
|
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
let node;
|
|
100
|
+
while (node = walker.nextNode()) {
|
|
101
|
+
const nodeText = node.textContent;
|
|
102
|
+
const nodeLength = nodeText.length;
|
|
82
103
|
|
|
104
|
+
// 開始位置の設定
|
|
83
105
|
if (startNode === null && currentOffset + nodeLength >= start) {
|
|
84
|
-
startNode =
|
|
85
|
-
|
|
106
|
+
startNode = node;
|
|
107
|
+
startNodeOffset = start - currentOffset;
|
|
86
108
|
}
|
|
87
109
|
|
|
110
|
+
// 終了位置の設定
|
|
88
111
|
if (endNode === null && currentOffset + nodeLength >= end) {
|
|
89
|
-
endNode =
|
|
90
|
-
|
|
112
|
+
endNode = node;
|
|
113
|
+
endNodeOffset = end - currentOffset;
|
|
91
114
|
break;
|
|
92
115
|
}
|
|
93
116
|
|
|
94
117
|
currentOffset += nodeLength;
|
|
95
118
|
}
|
|
96
119
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
// 範囲が見つからない場合の処理
|
|
121
|
+
if (!startNode || !endNode) {
|
|
122
|
+
// 要素の最後にカーソルを設定
|
|
123
|
+
const lastWalker = document.createTreeWalker(
|
|
124
|
+
element,
|
|
125
|
+
NodeFilter.SHOW_TEXT,
|
|
126
|
+
null,
|
|
127
|
+
false
|
|
128
|
+
);
|
|
129
|
+
let lastNode = null;
|
|
130
|
+
while (lastNode = lastWalker.nextNode()) {
|
|
131
|
+
// 最後のテキストノードを取得
|
|
132
|
+
}
|
|
133
|
+
if (lastNode) {
|
|
134
|
+
startNode = endNode = lastNode;
|
|
135
|
+
startNodeOffset = endNodeOffset = lastNode.textContent.length;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
101
138
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
139
|
+
if (startNode && endNode) {
|
|
140
|
+
try {
|
|
141
|
+
const range = document.createRange();
|
|
142
|
+
range.setStart(startNode, Math.min(startNodeOffset, startNode.textContent.length));
|
|
143
|
+
range.setEnd(endNode, Math.min(endNodeOffset, endNode.textContent.length));
|
|
144
|
+
|
|
145
|
+
const selection = window.getSelection();
|
|
146
|
+
selection.removeAllRanges();
|
|
147
|
+
selection.addRange(range);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
console.warn('Failed to set selection:', e);
|
|
150
|
+
// フォールバック: 要素の最後にカーソルを設定
|
|
151
|
+
element.focus();
|
|
152
|
+
}
|
|
105
153
|
}
|
|
106
154
|
}
|
|
107
155
|
|
|
156
|
+
// contenteditable要素用のテキスト取得機能(改行保持版)
|
|
157
|
+
function getContentEditableText(element) {
|
|
158
|
+
// innerTextを使用して改行を保持
|
|
159
|
+
return element.innerText || element.textContent || '';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// contenteditable要素用のテキスト設定機能(改行保持版)
|
|
163
|
+
function setContentEditableText(element, text) {
|
|
164
|
+
// innerTextを使用して改行を正確に設定
|
|
165
|
+
element.innerText = text;
|
|
166
|
+
}
|
|
167
|
+
|
|
108
168
|
// Markdownテキスト挿入機能
|
|
109
169
|
window.insertMarkdown = function(before, after) {
|
|
110
170
|
after = after || '';
|