ponkotsu-md-editor 0.2.32 → 0.2.34

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b276d684730d179d1db2e788a37687db583b3257a073b48a9acaf6e2d4f5394
4
- data.tar.gz: 77d2db0430ffe4e4d5f0fa086b7852d010b55d948af6e239f58c75edf44306de
3
+ metadata.gz: e3b1c79f7f7011ffcd76111ea8598c5346790a17feb8c0a6e7f34b1ff7109176
4
+ data.tar.gz: 753c49c6d2c30d63059ff982b4f0620cecf94f6f1e5ef2b00f70814112dc35ee
5
5
  SHA512:
6
- metadata.gz: fcdf631c47e69110531971546ba898ee459619162ddfe0033e1915f24b1e33099bfca9d63207442e4f1cfed5a8c31a5d0ae291e717d12c9156709280b57e57ea
7
- data.tar.gz: 010aebf4daf0eea2e49cd28a29de89471e7f8c07b18827d086087fcd84bb8a4c009092f1a5c5c2c8e809dc03d1ef70b0f893cd50013f935da5cdf2d08a16303f
6
+ metadata.gz: 0337a5e3775a7b445a0eec9dfb92c2f3eeda5925fafdcb408496a2010bebb9bc0ab63d1689b45de015a0946c0a5c7674f1b0f8a76f1e9bd2b464e1828eaf8963
7
+ data.tar.gz: 719c69fa598fb5a7983cf8ab277c3d4246763569eeb1e72e9083bd9040fbbc37f0fadce92ddca229c3eae3719d1ad22d5d8431f198a5136a9c5ec90909b65ff8
@@ -117,28 +117,62 @@
117
117
  }, { passive: false });
118
118
  }
119
119
 
120
- const syncToHidden = () => {
121
- hiddenField.value = (textarea.innerText || '').replaceAll('\u00A0', ' ');
122
- };
120
+ const syncToHidden = (() => {
121
+ let lastValue = '';
122
+ let pendingUpdate = false;
123
+
124
+ return () => {
125
+ if (pendingUpdate) return;
126
+
127
+ // テキスト取得(innerTextよりtextContentの方が高速)
128
+ const currentText = (textarea.textContent || '').replaceAll('\u00A0', ' ');
129
+
130
+ // 変更がない場合はスキップ
131
+ if (currentText === lastValue) return;
132
+
133
+ pendingUpdate = true;
134
+ requestAnimationFrame(() => {
135
+ hiddenField.value = currentText;
136
+ lastValue = currentText;
137
+ pendingUpdate = false;
138
+ });
139
+ };
140
+ })();
123
141
 
124
142
  // 初期化時に同期
125
143
  syncToHidden();
126
144
 
127
- // フォーム送信時に確実に同期(最重要)
145
+ // フォーム送信時の処理を非同期化
128
146
  const form = textarea.closest('form');
129
147
  if (form) {
130
148
  form.addEventListener('submit', function(e) {
131
- syncToHidden();
132
- console.log('Form submitting with content length:', hiddenField.value.length);
149
+ e.preventDefault();
150
+
151
+ // 同期的に値を設定(確実性のため)
152
+ hiddenField.value = (textarea.textContent || '').replaceAll('\u00A0', ' ');
153
+
154
+ // 次のティックで送信
155
+ setTimeout(() => {
156
+ // console.log('Form submitting with content length:', hiddenField.value.length);
157
+ form.submit();
158
+ }, 0);
133
159
  });
134
160
  }
135
161
 
136
162
  // 初期状態でプレースホルダを表示するための空要素チェック
137
163
  function updatePlaceholderVisibility() {
138
- // <br>のみの場合も空とみなす
139
- if (textarea.innerHTML.trim() === '&nbsp;' || textarea.innerHTML.trim() === ''
140
- || textarea.innerHTML.trim() === '\<br\>'
141
- || textarea.innerHTML.trim() === '<div> </div>') {
164
+ // innerHTML を一度だけ取得してキャッシュ
165
+ const html = textarea.innerHTML.trim();
166
+
167
+ // 空判定を簡潔に
168
+ const isEmpty = html === '' ||
169
+ html === '&nbsp;' ||
170
+ html === '<br>' ||
171
+ html === '<div><br></div>' ||
172
+ html === '<div></div>' ||
173
+ html === '<div> </div>';
174
+
175
+ if (isEmpty) {
142
176
  textarea.classList.add('empty');
143
177
  } else {
144
178
  textarea.classList.remove('empty');
@@ -240,7 +274,7 @@
240
274
  }
241
275
 
242
276
  onReady(function() {
243
- console.log('Enhanced Markdown editor initializing...');
277
+ // console.log('Enhanced Markdown editor initializing...');
244
278
 
245
279
  // Get DOM elements
246
280
  const textarea = document.getElementById('editor_content');
@@ -306,7 +340,7 @@
306
340
  'Expected:' + expected + '\n' +
307
341
  'Actual:', actual);
308
342
  } else {
309
- console.log('Assertion passed:', message);
343
+ // console.log('Assertion passed:', message);
310
344
  }
311
345
  }
312
346
 
@@ -417,16 +451,16 @@
417
451
  }
418
452
 
419
453
  // === デバッグ出力 ===
420
- console.log('[DEBUG] getContentEditableSelection');
421
- console.log('fullText:', JSON.stringify(fullText));
422
- console.log('startPos:', startPos, 'endPos:', endPos);
423
- console.log('selectedText:', JSON.stringify(selectedText));
424
- console.log('rangeText:', JSON.stringify(rangeText));
425
- console.log('textNodes:', textNodes.map(n => n.textContent));
426
- console.log('range.startContainer:', range.startContainer);
427
- console.log('range.startOffset:', range.startOffset);
428
- console.log('range.endContainer:', range.endContainer);
429
- console.log('range.endOffset:', range.endOffset);
454
+ // console.log('[DEBUG] getContentEditableSelection');
455
+ // console.log('fullText:', JSON.stringify(fullText));
456
+ // console.log('startPos:', startPos, 'endPos:', endPos);
457
+ // console.log('selectedText:', JSON.stringify(selectedText));
458
+ // console.log('rangeText:', JSON.stringify(rangeText));
459
+ // console.log('textNodes:', textNodes.map(n => n.textContent));
460
+ // console.log('range.startContainer:', range.startContainer);
461
+ // console.log('range.startOffset:', range.startOffset);
462
+ // console.log('range.endContainer:', range.endContainer);
463
+ // console.log('range.endOffset:', range.endOffset);
430
464
  // ===================
431
465
 
432
466
  return {
@@ -864,6 +898,8 @@
864
898
  }
865
899
  }
866
900
 
901
+ const MAX_CACHE_SIZE = 500;
902
+
867
903
  function analyzeHtml(target, isCountEmptyDiv = false) {
868
904
 
869
905
  const cacheKey = `${target}_${isCountEmptyDiv}`;
@@ -937,9 +973,13 @@
937
973
  }
938
974
  }
939
975
 
940
- if (analyzeHtmlCache.size > 100) {
941
- const firstKey = analyzeHtmlCache.keys().next().value;
942
- analyzeHtmlCache.delete(firstKey);
976
+ if (analyzeHtmlCache.size > MAX_CACHE_SIZE) {
977
+ // 古いエントリを複数削除(より効率的)
978
+ const deleteCount = Math.floor(MAX_CACHE_SIZE * 0.2); // 20%削除
979
+ const keys = Array.from(analyzeHtmlCache.keys());
980
+ for (let i = 0; i < deleteCount; i++) {
981
+ analyzeHtmlCache.delete(keys[i]);
982
+ }
943
983
  }
944
984
 
945
985
  analyzeHtmlCache.set(cacheKey, lines);
@@ -1030,10 +1070,10 @@
1030
1070
  const endOffset = getOffsetInContainer(textarea, range.endContainer, range.endOffset);
1031
1071
 
1032
1072
  // === デバッグ出力(削除可能)===
1033
- console.log('DOM-based text:', JSON.stringify(domBasedText));
1034
- console.log('beginEndLenStrings:', beginEndLenStrings);
1035
- console.log('Selection offsets:', startOffset, endOffset);
1036
- console.log('Selected text should be:', JSON.stringify(domBasedText.substring(startOffset, endOffset)));
1073
+ // console.log('DOM-based text:', JSON.stringify(domBasedText));
1074
+ // console.log('beginEndLenStrings:', beginEndLenStrings);
1075
+ // console.log('Selection offsets:', startOffset, endOffset);
1076
+ // console.log('Selected text should be:', JSON.stringify(domBasedText.substring(startOffset, endOffset)));
1037
1077
  // =============================
1038
1078
 
1039
1079
  const startPos = getLineAndCharIndex(textarea, startOffset);
@@ -1228,10 +1268,10 @@
1228
1268
  const range = selection.getRangeAt(0);
1229
1269
  const selectedText = range.toString();
1230
1270
 
1231
- console.log('Markdown apply debug:');
1232
- console.log('Selected text:', JSON.stringify(selectedText));
1233
- console.log('Before markup:', JSON.stringify(before));
1234
- console.log('After markup:', JSON.stringify(after));
1271
+ // console.log('Markdown apply debug:');
1272
+ // console.log('Selected text:', JSON.stringify(selectedText));
1273
+ // console.log('Before markup:', JSON.stringify(before));
1274
+ // console.log('After markup:', JSON.stringify(after));
1235
1275
 
1236
1276
  if (selectedText.length === 0) {
1237
1277
  // No selection - insert markers at cursor position
@@ -1261,7 +1301,7 @@
1261
1301
  newSelection.removeAllRanges();
1262
1302
  newSelection.addRange(newRange);
1263
1303
 
1264
- console.log('DOM replacement completed successfully');
1304
+ // console.log('DOM replacement completed successfully');
1265
1305
 
1266
1306
  // Fire input event for change detection
1267
1307
  element.dispatchEvent(new Event('input', { bubbles: true }));
@@ -1645,7 +1685,7 @@
1645
1685
  script.onload = () => {
1646
1686
  this.loaded = true;
1647
1687
  this.loading = false;
1648
- console.log('Twitter widgets.js loaded successfully');
1688
+ // console.log('Twitter widgets.js loaded successfully');
1649
1689
  resolve();
1650
1690
  };
1651
1691
 
@@ -1676,7 +1716,7 @@
1676
1716
 
1677
1717
  if (window.twttr && window.twttr.widgets) {
1678
1718
  await window.twttr.widgets.load(container);
1679
- console.log('Twitter widgets initialized');
1719
+ // console.log('Twitter widgets initialized');
1680
1720
  }
1681
1721
  } catch (error) {
1682
1722
  console.error('Failed to initialize Twitter widgets:', error);
@@ -2199,7 +2239,7 @@
2199
2239
  });
2200
2240
  }
2201
2241
 
2202
- console.log('ponkotsu Markdown editor initialized successfully');
2242
+ // console.log('ponkotsu Markdown editor initialized successfully');
2203
2243
  });
2204
2244
 
2205
2245
  // Enhanced error handling
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PonkotsuMdEditor
4
- VERSION = "0.2.32"
4
+ VERSION = "0.2.34"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ponkotsu-md-editor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.32
4
+ version: 0.2.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - dhq_boiler