ponkotsu-md-editor 0.2.18 → 0.2.20
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 +48 -42
- 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: 0c897595252786887dcfec166c2a717f65b150fd422ac385b7cf0281e2e77040
|
|
4
|
+
data.tar.gz: 73b466149138e5873c694ae0f3a747dd3d1dc6f49ba4682458a6cec4aadb3def
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed5ab5578fcaf70912a62e9a5b759a0c15a728ea3eae70abe7e0d0529aa6fc79b1c0338b23b32c0b6c3d6efdad3b1ad516b5d1be351e04d9b836302b0264f6e9
|
|
7
|
+
data.tar.gz: e1fa5a62e8ce6a6e781c27dadf41b084567596e49995423082abba403143b32a65834f9f6d3e8f4d996f302887e8198ffc6186989bd6a15dfa929580efefc920
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
// _scanOffsetCacheをローカル変数として閉じる
|
|
5
|
+
let _scanOffsetCache = new Map();
|
|
6
|
+
|
|
4
7
|
// Debounce function for delayed execution
|
|
5
8
|
function debounce(func, wait) {
|
|
6
9
|
let timeout;
|
|
@@ -63,6 +66,50 @@
|
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
function scanOffset(pos) {
|
|
72
|
+
// キャッシュ取得
|
|
73
|
+
if (_scanOffsetCache.has(pos)) {
|
|
74
|
+
return _scanOffsetCache.get(pos);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const textarea = document.getElementById('editor_content');
|
|
78
|
+
|
|
79
|
+
// HTML全体を一度だけ取得(これは良い改善)
|
|
80
|
+
const fullHTML = textarea.innerHTML;
|
|
81
|
+
const fullText = textarea.innerText;
|
|
82
|
+
|
|
83
|
+
let offset = pos;
|
|
84
|
+
let lastAdded = -1;
|
|
85
|
+
let iterations = 0;
|
|
86
|
+
const MAX_ITERATIONS = 100; // より安全な上限
|
|
87
|
+
|
|
88
|
+
while (iterations < MAX_ITERATIONS) {
|
|
89
|
+
const htmlUpTo = fullHTML.substring(0, offset);
|
|
90
|
+
const textUpTo = fullText.substring(0, offset);
|
|
91
|
+
|
|
92
|
+
// 元の正規表現を維持(安全性優先)
|
|
93
|
+
const brCount = (htmlUpTo.match(/<br\s*\/?>(?![\w\W]*<)/g) || []).length;
|
|
94
|
+
const nlCount = (textUpTo.match(/\n/g) || []).length;
|
|
95
|
+
|
|
96
|
+
const added = brCount + nlCount;
|
|
97
|
+
if (added === lastAdded) break;
|
|
98
|
+
|
|
99
|
+
offset = pos + added;
|
|
100
|
+
lastAdded = added;
|
|
101
|
+
iterations++;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (iterations >= MAX_ITERATIONS) {
|
|
105
|
+
console.warn('scanOffset: Maximum iterations reached, possible infinite loop');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 結果をキャッシュ
|
|
109
|
+
_scanOffsetCache.set(pos, offset);
|
|
110
|
+
return offset;
|
|
111
|
+
}
|
|
112
|
+
|
|
66
113
|
onReady(function() {
|
|
67
114
|
console.log('Enhanced Markdown editor initializing...');
|
|
68
115
|
|
|
@@ -98,47 +145,6 @@
|
|
|
98
145
|
beforeEndRange.selectNodeContents(textarea);
|
|
99
146
|
beforeEndRange.setEnd(range.endContainer, range.endOffset);
|
|
100
147
|
let endPos = beforeEndRange.toString().length;
|
|
101
|
-
|
|
102
|
-
function scanOffset(pos) {
|
|
103
|
-
// キャッシュを追加
|
|
104
|
-
if (this._scanOffsetCache && this._scanOffsetCache.pos === pos) {
|
|
105
|
-
return this._scanOffsetCache.result;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// HTML全体を一度だけ取得(これは良い改善)
|
|
109
|
-
const fullHTML = textarea.innerHTML;
|
|
110
|
-
const fullText = textarea.innerText;
|
|
111
|
-
|
|
112
|
-
let offset = pos;
|
|
113
|
-
let lastAdded = -1;
|
|
114
|
-
let iterations = 0;
|
|
115
|
-
const MAX_ITERATIONS = 100; // より安全な上限
|
|
116
|
-
|
|
117
|
-
while (iterations < MAX_ITERATIONS) {
|
|
118
|
-
const htmlUpTo = fullHTML.substring(0, offset);
|
|
119
|
-
const textUpTo = fullText.substring(0, offset);
|
|
120
|
-
|
|
121
|
-
// 元の正規表現を維持(安全性優先)
|
|
122
|
-
const brCount = (htmlUpTo.match(/<br\s*\/?>(?![\w\W]*<)/g) || []).length;
|
|
123
|
-
const nlCount = (textUpTo.match(/\n/g) || []).length;
|
|
124
|
-
|
|
125
|
-
const added = brCount + nlCount;
|
|
126
|
-
if (added === lastAdded) break;
|
|
127
|
-
|
|
128
|
-
offset = pos + added;
|
|
129
|
-
lastAdded = added;
|
|
130
|
-
iterations++;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (iterations >= MAX_ITERATIONS) {
|
|
134
|
-
console.warn('scanOffset: Maximum iterations reached, possible infinite loop');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 結果をキャッシュ
|
|
138
|
-
this._scanOffsetCache = { pos: pos, result: offset };
|
|
139
|
-
|
|
140
|
-
return offset;
|
|
141
|
-
}
|
|
142
148
|
startPos = scanOffset(startPos);
|
|
143
149
|
endPos = scanOffset(endPos);
|
|
144
150
|
// -----------------------------------
|
|
@@ -1385,7 +1391,7 @@
|
|
|
1385
1391
|
if (isContentEditable) {
|
|
1386
1392
|
const selection = getContentEditableSelection(activeElement);
|
|
1387
1393
|
selectedText = selection.selectedText;
|
|
1388
|
-
} else
|
|
1394
|
+
} else {
|
|
1389
1395
|
selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
|
|
1390
1396
|
}
|
|
1391
1397
|
|