ZHIWEI666 commited on
Commit
6c745f8
·
verified ·
1 Parent(s): a47251f

Upload 104 files

Browse files
前端页面/social/评论与互动组件.js CHANGED
@@ -29,6 +29,7 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
29
  let currentReplyTarget = null;
30
  let sending = false, deleting = false, blocked = false, scope = null, constructing = true, observer;
31
  let active = true, generation = 0, writePending = false;
 
32
  const account = currentUser?.account || null;
33
  const matches = captureRequestSession();
34
  const sessionMatches = () => matches() && (getUser()?.account || null) === account;
@@ -56,6 +57,40 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
56
  inputArea.setAttribute('aria-busy', String(busy));
57
  listArea.querySelectorAll('.reply-btn,.delete-btn').forEach(button => { button.disabled = busy || blocked; });
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  function unconfirmed() {
60
  blocked = true;
61
  notice.textContent = t('social.comment_unconfirmed');
@@ -227,6 +262,7 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
227
  const text = inputField.value.trim();
228
  if (!text) return;
229
 
 
230
  const operationGeneration = generation;
231
  sending = true;
232
  const submittedValue = inputField.value;
@@ -270,6 +306,7 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
270
  else unconfirmed();
271
  } finally {
272
  if (current() && operationGeneration === generation) { writePending = false; sending = false; setControls(); }
 
273
  }
274
  };
275
 
@@ -282,6 +319,7 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
282
  invalidate: () => { notice.textContent = t('auth.session_changed'); container.append(notice); }
283
  });
284
  scope.addCleanup(() => {
 
285
  active = false; generation++;
286
  observer?.disconnect(); confirmationAbort.abort();
287
  inputField.value = ''; currentReplyTarget = null; commentsData = [];
@@ -291,6 +329,7 @@ export function createCommentSection(itemId, commentsData, currentUser, onCountC
291
  const next = !!value;
292
  if (next === active) return;
293
  if (next && !scope.isCurrent()) return;
 
294
  generation++;
295
  active = next;
296
  if (!next) {
 
29
  let currentReplyTarget = null;
30
  let sending = false, deleting = false, blocked = false, scope = null, constructing = true, observer;
31
  let active = true, generation = 0, writePending = false;
32
+ let sendFocus = null;
33
  const account = currentUser?.account || null;
34
  const matches = captureRequestSession();
35
  const sessionMatches = () => matches() && (getUser()?.account || null) === account;
 
57
  inputArea.setAttribute('aria-busy', String(busy));
58
  listArea.querySelectorAll('.reply-btn,.delete-btn').forEach(button => { button.disabled = busy || blocked; });
59
  }
60
+ function clearSendFocus(record = sendFocus) {
61
+ if (!record || record !== sendFocus) return;
62
+ document.removeEventListener('focusin', record.onFocus, true);
63
+ document.removeEventListener('pointerdown', record.onPointer, true);
64
+ sendFocus = null;
65
+ }
66
+ function captureSendFocus() {
67
+ clearSendFocus();
68
+ if (document.activeElement !== submitBtn) return null;
69
+ const record = { generation };
70
+ record.onFocus = event => {
71
+ if (event.target !== submitBtn && event.target !== document.body) clearSendFocus(record);
72
+ };
73
+ record.onPointer = () => clearSendFocus(record);
74
+ sendFocus = record;
75
+ document.addEventListener('focusin', record.onFocus, true);
76
+ document.addEventListener('pointerdown', record.onPointer, true);
77
+ return record;
78
+ }
79
+ function restoreSendFocus(record) {
80
+ if (!record || record !== sendFocus) return;
81
+ const target = blocked ? notice : inputField;
82
+ const owned = current() && record.generation === generation && document.hasFocus()
83
+ && (document.activeElement === document.body || document.activeElement === submitBtn)
84
+ && !container.closest('[inert], [hidden], [aria-hidden="true"]')
85
+ && target.isConnected && target.getClientRects().length > 0
86
+ && getComputedStyle(target).visibility !== 'hidden';
87
+ clearSendFocus(record);
88
+ if (owned) {
89
+ if (target === notice) notice.tabIndex = -1;
90
+ target.focus({ preventScroll: true });
91
+ }
92
+ }
93
+
94
  function unconfirmed() {
95
  blocked = true;
96
  notice.textContent = t('social.comment_unconfirmed');
 
262
  const text = inputField.value.trim();
263
  if (!text) return;
264
 
265
+ const focusRecord = captureSendFocus();
266
  const operationGeneration = generation;
267
  sending = true;
268
  const submittedValue = inputField.value;
 
306
  else unconfirmed();
307
  } finally {
308
  if (current() && operationGeneration === generation) { writePending = false; sending = false; setControls(); }
309
+ restoreSendFocus(focusRecord);
310
  }
311
  };
312
 
 
319
  invalidate: () => { notice.textContent = t('auth.session_changed'); container.append(notice); }
320
  });
321
  scope.addCleanup(() => {
322
+ clearSendFocus();
323
  active = false; generation++;
324
  observer?.disconnect(); confirmationAbort.abort();
325
  inputField.value = ''; currentReplyTarget = null; commentsData = [];
 
329
  const next = !!value;
330
  if (next === active) return;
331
  if (next && !scope.isCurrent()) return;
332
+ clearSendFocus();
333
  generation++;
334
  active = next;
335
  if (!next) {