diff --git a/ts/quill/signal-clipboard/util.dom.ts b/ts/quill/signal-clipboard/util.dom.ts index 8632ac4022..4ef2ef1d78 100644 --- a/ts/quill/signal-clipboard/util.dom.ts +++ b/ts/quill/signal-clipboard/util.dom.ts @@ -47,7 +47,7 @@ export function createEventHandler({ // clipboardData at all, all other data is reset. event.clipboardData?.setData('text/plain', plaintext); - event.clipboardData?.setData('text/signal', container.innerHTML); + event.clipboardData?.setData('text/signal', container.getHTML()); if (deleteSelection) { selection.deleteFromDocument(); diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 91dbd22740..5e2bb73b2b 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -810,1595 +810,5 @@ "path": "node_modules/react-blurhash/docs/demo.f335462148ad584661d8.js", "reasonCategory": "usageTrusted", "updated": "2024-11-14T18:53:33.345Z" - }, - { - "rule": "React-useRef", - "path": "ts/axo/AriaClickable.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-08-28T23:36:44.974Z" - }, - { - "rule": "React-useRef", - "path": "ts/axo/AriaClickable.dom.tsx", - "line": " const onTriggerStateUpdateRef = useRef(onTriggerStateUpdate);", - "reasonCategory": "usageTrusted", - "updated": "2025-08-28T23:36:44.974Z" - }, - { - "rule": "React-useRef", - "path": "ts/axo/AxoContextMenu.dom.tsx", - "line": " useRef(getTriggerElement);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-11T22:17:13.219Z" - }, - { - "rule": "React-useRef", - "path": "ts/axo/AxoDropdownMenu.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-05T21:09:43.372Z" - }, - { - "rule": "React-useRef", - "path": "ts/axo/AxoTooltip.dom.tsx", - "line": " const triggerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2026-02-09T21:54:48.020Z" - }, - { - "rule": "React-useRef", - "path": "ts/calling/useGetCallingFrameBuffer.std.ts", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-10-01T20:11:56Z", - "reasonDetail": "Doesn't touch the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/AutoSizeInput.dom.tsx", - "line": " const hiddenRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-01-11T16:58:57.146Z", - "reasonDetail": "Needs access to a hidden span element to get its width" - }, - { - "rule": "React-useRef", - "path": "ts/components/AutoSizeTextArea.dom.tsx", - "line": " const ownRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-03-26T17:14:14.370Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/AvatarEditor.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-24T03:40:20.019Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/AvatarTextEditor.dom.tsx", - "line": " const measureElRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-04T18:18:09.236Z", - "reasonDetail": "Only used for measurement. Doesn't modify the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/AvatarTextEditor.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-04T22:02:17.074Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/AvatarTextEditor.dom.tsx", - "line": " const onDoneRef = useRef(onDone);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-05T23:40:55.699Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/AvatarUploadButton.dom.tsx", - "line": " const fileInputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-03T21:17:38.615Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallManager.dom.tsx", - "line": " const imageDataCache = React.useRef(new Map());", - "reasonCategory": "usageTrusted", - "updated": "2024-05-06T20:18:59.647Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallNeedPermissionScreen.dom.tsx", - "line": " const autoCloseAtRef = useRef(Date.now() + AUTO_CLOSE_MS);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallReactionBurst.dom.tsx", - "line": " const timeouts = useRef>(new Map());", - "reasonCategory": "usageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "For hiding call reaction bursts after timeouts." - }, - { - "rule": "React-useRef", - "path": "ts/components/CallReactionBurst.dom.tsx", - "line": " const burstsShown = useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "In wrapping function, track bursts so we can hide on unmount." - }, - { - "rule": "React-useRef", - "path": "ts/components/CallReactionBurst.dom.tsx", - "line": " const shownBursts = useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "Keep track of shown reaction bursts." - }, - { - "rule": "React-useRef", - "path": "ts/components/CallReactionBurstEmoji.dom.tsx", - "line": " const containerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "For determining position of container for animations." - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const burstsShown = useRef>(new Map());", - "reasonCategory": "sageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "Recent bursts shown for burst behavior like throttling." - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const toastRegionRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-11-14T23:29:51.425Z", - "reasonDetail": "For calling reactions toasts" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const reactionPickerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-11-14T23:29:51.425Z", - "reasonDetail": "To render the reaction picker in the CallScreen" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const burstRegionRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-12-21T11:13:56.623Z", - "reasonDetail": "Calling reactions bursts" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const reactionsShown = useRef<", - "reasonCategory": "usageTrusted", - "updated": "2024-01-06T00:59:20.678Z", - "reasonDetail": "Recent reactions shown for reactions burst" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const reactButtonRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-01-16T22:59:06.336Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const reactionPickerContainerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-01-16T22:59:06.336Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const localPreviewRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-30T20:46:48.849Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallScreen.dom.tsx", - "line": " const lonelyCallPreviewRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-30T20:46:48.849Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingPendingParticipants.dom.tsx", - "line": " const expandedListRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-06-28T01:22:22.509Z", - "reasonDetail": "For outside click handling" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingPip.dom.tsx", - "line": " const videoContainerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingPip.dom.tsx", - "line": " const lonelyCallPreviewRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-30T20:46:48.849Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingPip.dom.tsx", - "line": " const localPreviewRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-30T20:46:48.849Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingRaisedHandsList.dom.tsx", - "line": " const prevShownRaisedHandsCountRef = useRef(raisedHandsCount);", - "reasonCategory": "usageTrusted", - "updated": "2026-01-09T21:23:45.188Z", - "reasonDetail": "Maintain last shown raised hand count to prevent 0" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingRaisedHandsList.dom.tsx", - "line": " const prevShownSyncedLocalHandRaisedRef = useRef(", - "reasonCategory": "usageTrusted", - "updated": "2026-01-09T21:23:45.188Z", - "reasonDetail": "Maintain last shown raised hands to prevent 0" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToast.dom.tsx", - "line": " const shownToasts = React.useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2023-10-04T20:50:45.297Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToast.dom.tsx", - "line": " const timeouts = React.useRef>(new Map());", - "reasonCategory": "usageTrusted", - "updated": "2023-10-10T17:05:02.468Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToast.dom.tsx", - "line": " const timeoutsStatus = React.useRef<'active' | 'paused'>('active');", - "reasonCategory": "usageTrusted", - "updated": "2023-10-10T17:05:02.468Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToast.dom.tsx", - "line": " const toastsShown = useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2023-10-10T17:05:02.468Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToast.dom.tsx", - "line": " const toastId = useRef(uuid());", - "reasonCategory": "usageTrusted", - "updated": "2023-11-14T16:52:45.342Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToastManager.dom.tsx", - "line": " const toastRegionRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-10-26T13:57:41.860Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToastManager.dom.tsx", - "line": " const toastLastShownAt = useRef(0);", - "reasonCategory": "usageTrusted", - "updated": "2024-01-12T18:56:18.138Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallingToastManager.dom.tsx", - "line": " const handsForLastShownToast = useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2024-01-12T18:56:18.138Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const infiniteLoaderRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-08-02T00:21:37.858Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const listRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-08-02T00:21:37.858Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const prevOptionsRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-08-18T19:09:30.283Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const getCallHistoryGroupsCountRef = useRef(getCallHistoryGroupsCount);", - "reasonCategory": "usageTrusted", - "updated": "2023-11-27T20:25:10.634Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const getCallHistoryGroupsRef = useRef(getCallHistoryGroups);", - "reasonCategory": "usageTrusted", - "updated": "2023-11-27T20:25:10.634Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const searchStateItemsRef = useRef | null>(", - "reasonCategory": "usageTrusted", - "updated": "2024-05-16T02:10:00.652Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const peekQueueRef = useRef>(new Set());", - "reasonCategory": "usageTrusted", - "updated": "2024-05-16T02:10:00.652Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const peekQueueArgsRef = useRef>(", - "reasonCategory": "usageTrusted", - "updated": "2024-05-16T02:10:00.652Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const inactiveCallLinksPeekedAtRef = useRef>(new Map());", - "reasonCategory": "usageTrusted", - "updated": "2024-05-16T02:10:00.652Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CallsList.preload.tsx", - "line": " const peekQueueTimerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-05-16T02:10:00.652Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CaptchaDialog.dom.tsx", - "line": " const buttonRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionArea.dom.tsx", - "line": " const inputApiRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-09-23T00:07:11.885Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionArea.dom.tsx", - "line": " const fileInputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-09-23T00:07:11.885Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionArea.dom.tsx", - "line": " const photoVideoInputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-10-27T16:28:11.852Z", - "reasonDetail": "Ref for photo/video file input element" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const callbacksRef = React.useRef(unstaleCallbacks);", - "reasonCategory": "usageTrusted", - "updated": "2021-04-21T21:35:38.757Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const emojiCompletionRef = React.useRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const mentionCompletionRef = React.useRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const quillRef = React.useRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const propsRef = React.useRef(props);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const memberRepositoryRef = React.useRef(", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionInput.dom.tsx", - "line": " const canSendRef = React.useRef(false);", - "reasonCategory": "usageTrusted", - "updated": "2022-06-25T00:06:19.860Z", - "reasonDetail": "Not used for DOM manipulation" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionRecording.dom.tsx", - "line": " const startTime = useRef(Date.now());", - "reasonCategory": "usageTrusted", - "updated": "2023-02-26T23:17:41.234Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionRecording.dom.tsx", - "line": " const drift = useRef(0);", - "reasonCategory": "usageTrusted", - "updated": "2023-02-26T23:20:28.848Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionRecordingDraft.dom.tsx", - "line": " const timeout = useRef(undefined);", - "reasonCategory": "usageTrusted", - "updated": "2023-02-26T23:20:28.848Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CompositionTextArea.dom.tsx", - "line": " const inputApiRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2025-04-01T21:15:44.903Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ContactPills.dom.tsx", - "line": " const elRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ContextMenu.dom.tsx", - "line": " const virtualElement = useRef(generateVirtualElement(0, 0));", - "reasonCategory": "usageTrusted", - "updated": "2022-08-19T17:09:38.534Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/CustomizingPreferredReactionsModal.dom.tsx", - "line": " const pickerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-04-07T19:15:28.908Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/DirectCallRemoteParticipant.dom.tsx", - "line": " const remoteVideoRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/EditHistoryMessagesModal.dom.tsx", - "line": " const containerElementRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-03-25T01:59:04.590Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ForwardMessagesModal.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/GradientDial.dom.tsx", - "line": " const containerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/GroupCallOverflowArea.dom.tsx", - "line": " const overflowRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/GroupCallRemoteParticipant.dom.tsx", - "line": " const lastReceivedVideoAt = useRef(-Infinity);", - "reasonCategory": "usageTrusted", - "updated": "2021-06-17T20:46:02.342Z", - "reasonDetail": "Doesn't reference the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/GroupCallRemoteParticipant.dom.tsx", - "line": " const remoteVideoRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/GroupCallRemoteParticipant.dom.tsx", - "line": " const canvasContextRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/GroupCallRemoteParticipant.dom.tsx", - "line": " const imageDataRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-12-10T23:24:31.237Z", - "reasonDetail": "Doesn't touch the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/ImageOrBlurhash.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-08-05T17:07:11.678Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/IncomingCallBar.dom.tsx", - "line": " const initialTitleRef = useRef(title);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-16T20:52:11.043Z", - "reasonDetail": "Doesn't interact with the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/Input.dom.tsx", - "line": " const innerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Input.dom.tsx", - "line": " const valueOnKeydownRef = useRef(value);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Input.dom.tsx", - "line": " const selectionStartOnKeydownRef = useRef(value.length);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/LeftPane.dom.tsx", - "line": " const measureRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-08-09T21:48:42.602Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/LeftPaneSearchInput.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-02-11T20:49:03.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const containerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-23T18:39:37.081Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const imageRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-09-24T00:03:36.061Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const animateRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-10-11T21:21:08.188Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const dragCacheRef = useRef<", - "reasonCategory": "usageTrusted", - "updated": "2021-10-11T21:21:08.188Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const zoomCacheRef = useRef<", - "reasonCategory": "usageTrusted", - "updated": "2021-10-11T21:21:08.188Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Lightbox.dom.tsx", - "line": " const downloadToastTimeout = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2025-01-06T03:53:58.093Z", - "reasonDetail": "usageTrusted" - }, - { - "rule": "React-useRef", - "path": "ts/components/ListView.dom.tsx", - "line": " const listRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-11-11T17:11:07.659Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/MediaEditor.dom.tsx", - "line": " const inputApiRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-09-11T20:19:18.681Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/MediaEditor.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T22:29:15.758Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/MediaEditor.dom.tsx", - "line": " const initialSnapshotTaken = useRef(false);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-19T18:44:48.727Z", - "reasonDetail": "Tracking whether initial snapshot has been taken" - }, - { - "rule": "React-useRef", - "path": "ts/components/MediaQualitySelector.dom.tsx", - "line": " const buttonRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-06-14T22:04:43.988Z", - "reasonDetail": "Handling outside click" - }, - { - "rule": "React-useRef", - "path": "ts/components/Modal.dom.tsx", - "line": " const modalRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-08-05T00:22:31.660Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Modal.dom.tsx", - "line": " const bodyRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Modal.dom.tsx", - "line": " const bodyInnerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ModalContainer.dom.tsx", - "line": " const containerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-10-14T16:39:48.461Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ModalHost.dom.tsx", - "line": " const containerRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-09-14T16:20:15.384Z", - "reasonDetail": "Holds a reference to a container element to prevent outside clicks" - }, - { - "rule": "React-useRef", - "path": "ts/components/PollCreateModal.dom.tsx", - "line": " const optionRefsMap = useRef>(", - "reasonCategory": "usageTrusted", - "updated": "2025-11-02T17:27:24.705Z", - "reasonDetail": "Map of refs for poll option inputs to manage focus" - }, - { - "rule": "React-useRef", - "path": "ts/components/PollCreateModal.dom.tsx", - "line": " const questionInputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-02T17:27:24.705Z", - "reasonDetail": "Ref for question input to manage focus on validation errors" - }, - { - "rule": "React-useRef", - "path": "ts/components/Preferences.dom.tsx", - "line": " const settingsPaneRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-04-21T02:12:22.352Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesDonateFlow.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-06-26T23:23:57.292Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesInternal.dom.tsx", - "line": " const prevAbortControlerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-08-20T18:18:34.081Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesLocalBackups.dom.tsx", - "line": " const backupKeyTextareaRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-05-30T22:48:14.420Z", - "reasonDetail": "For focusing the settings backup key viewer textarea" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesNotificationProfiles.dom.tsx", - "line": " const tryClose = React.useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-08-25T21:04:21.643Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesNotificationProfiles.dom.tsx", - "line": " const selectedHour = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-09-05T21:41:09.931Z", - "reasonDetail": "Holding on to element for focus" - }, - { - "rule": "React-useRef", - "path": "ts/components/PreferencesNotificationProfiles.dom.tsx", - "line": " const selectedMinute = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-09-05T21:41:09.931Z", - "reasonDetail": "Holding on to element for scrolling into view" - }, - { - "rule": "React-useRef", - "path": "ts/components/ProfileEditor.dom.tsx", - "line": " const focusInputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/ProfileEditor.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-24T03:23:25.769Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/QrCode.dom.tsx", - "line": " const elRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-01-04T21:43:17.517Z", - "reasonDetail": "Used to change the style in non-production builds." - }, - { - "rule": "React-useRef", - "path": "ts/components/SafetyTipsModal.dom.tsx", - "line": " const scrollEndTimer = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-03-08T01:48:15.330Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Slider.dom.tsx", - "line": " const diff = useRef(0);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Slider.dom.tsx", - "line": " const handleRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Slider.dom.tsx", - "line": " const sliderRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StandaloneRegistration.dom.tsx", - "line": " const elemRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-11-30T10:15:33.662Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StandaloneRegistration.dom.tsx", - "line": " const pluginRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2024-11-16T00:33:41.092Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoriesSettingsModal.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T22:29:15.758Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryImage.dom.tsx", - "line": " const videoRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-04-29T23:54:21.656Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryProgressSegment.dom.tsx", - "line": " const onFinishRef = useRef(onFinish);", - "reasonCategory": "usageTrusted", - "updated": "2024-08-13T20:48:09.226Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryViewsNRepliesModal.dom.tsx", - "line": " const inputApiRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2022-02-15T17:57:06.507Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryViewsNRepliesModal.dom.tsx", - "line": " const containerElementRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-08-04T00:52:01.080Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryViewsNRepliesModal.dom.tsx", - "line": " const shouldScrollToBottomRef = useRef(true);", - "reasonCategory": "usageTrusted", - "updated": "2022-10-05T18:51:56.411Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryViewsNRepliesModal.dom.tsx", - "line": " const bottomRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-10-05T18:51:56.411Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/StoryViewsNRepliesModal.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T23:20:52.448Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/TextAttachment.dom.tsx", - "line": " const linkPreview = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-04-06T00:59:17.194Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/TextAttachment.dom.tsx", - "line": " const textEditorRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-06-16T23:23:32.306Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/TextAttachment.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/TextStoryCreator.dom.tsx", - "line": " const textEditorRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2022-06-16T23:23:32.306Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/TextStoryCreator.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T22:29:15.758Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/Tooltip.dom.tsx", - "line": " const wrapperRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/Tooltip.dom.tsx", - "line": " const timeoutRef = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-08-10T00:23:35.320Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/UsernameEditor.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-28T00:57:39.376Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/UsernameLinkEditor.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-28T00:57:39.376Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/ConversationHeader.dom.tsx", - "line": " const headerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2024-03-15T18:29:48.327Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/GIF.dom.tsx", - "line": " const videoRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/GroupDescription.dom.tsx", - "line": " const textRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/InlineNotificationWrapper.dom.tsx", - "line": " const focusRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-04-12T15:51:28.066Z" - }, - { - "rule": "React-createRef", - "path": "ts/components/conversation/Message.dom.tsx", - "line": " React.createRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-03-05T19:57:01.431Z", - "reasonDetail": "Used for detecting clicks outside reaction viewer" - }, - { - "rule": "React-createRef", - "path": "ts/components/conversation/Message.dom.tsx", - "line": " public focusRef: React.RefObject = React.createRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-03-05T19:57:01.431Z", - "reasonDetail": "Used for managing focus only" - }, - { - "rule": "React-createRef", - "path": "ts/components/conversation/Message.dom.tsx", - "line": " public audioButtonRef: React.RefObject = React.createRef();", - "reasonCategory": "usageTrusted", - "updated": "2021-03-05T19:57:01.431Z", - "reasonDetail": "Used for propagating click from the Message to MessageAudio's button" - }, - { - "rule": "React-createRef", - "path": "ts/components/conversation/Message.dom.tsx", - "line": " #metadataRef: React.RefObject = React.createRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-06-30T22:12:49.259Z", - "reasonDetail": "Used for excluding the message metadata from triple-click selections." - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/Message.dom.tsx", - "line": " const reactionsContainerRefMerger = useRef(createRefMerger());", - "reasonCategory": "usageTrusted", - "updated": "2025-06-05T12:55:51.245Z", - "reasonDetail": "Used for merging refs for reactions container" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/MessageContextMenu.dom.tsx", - "line": " const shouldReturnFocusToTrigger = useRef(true);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-19T16:03:53.849Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/MessageDetail.dom.tsx", - "line": " const messageDetailRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-09-11T22:53:43.464Z", - "reasonDetail": "Used to pass ref of MessageDetail to Message. Used for ReactionViewer overflow detection." - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/Quote.dom.tsx", - "line": " const imageRef = useRef(new Image());", - "reasonCategory": "usageTrusted", - "updated": "2021-01-20T21:30:08.430Z", - "reasonDetail": "Doesn't touch the DOM." - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/TypingBubble.dom.tsx", - "line": " const prevTypingContactIds = React.useRef<", - "reasonCategory": "usageTrusted", - "updated": "2023-09-28T21:48:57.488Z", - "reasonDetail": "Used to track change of typing contacts while a conversation is actively viewed." - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/WaveformScrubber.dom.tsx", - "line": " const waveformRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-02-26T23:20:28.848Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx", - "line": " const focusDescriptionRef = useRef(", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx", - "line": " const startingTitleRef = useRef(externalTitle);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx", - "line": " const startingAvatarUrlRef = useRef(externalAvatarUrl);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx", - "line": " const tryClose = useRef<() => void | undefined>();", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T23:20:52.448Z", - "reasonDetail": "Holding on to a close function" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/conversation-details/GroupMemberLabelEditor.dom.tsx", - "line": " const messageContainer = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2026-02-03T20:48:35.470Z", - "reasonDetail": "A container passed to " - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/media-gallery/MediaGallery.dom.tsx", - "line": " const focusRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2019-11-01T22:46:33.013Z", - "reasonDetail": "Used for setting focus only" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/pinned-messages/PinnedMessagesPanel.dom.tsx", - "line": " const containerElementRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-20T18:33:59.075Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/conversation/poll-message/PollMessageContents.dom.tsx", - "line": " const pendingCheckTimer = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-11-06T20:28:00.760Z", - "reasonDetail": "Ref for timer" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/FunGif.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-03-21T23:22:07.920Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/FunGif.dom.tsx", - "line": " const timerRef = useRef>();", - "reasonCategory": "usageTrusted", - "updated": "2025-03-21T23:22:07.920Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/FunGif.dom.tsx", - "line": " const videoRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-03-24T18:57:50.198Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunImage.dom.tsx", - "line": " const imageRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunScroller.dom.tsx", - "line": " const scrollerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunScroller.dom.tsx", - "line": " const scrollerInnerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunScroller.dom.tsx", - "line": " const observerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunScroller.dom.tsx", - "line": " const onScrollChangeRef = useRef(props.onScrollSectionChange);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunScroller.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunSubNav.dom.tsx", - "line": " const outerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunSubNav.dom.tsx", - "line": " const innerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunSubNav.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/base/FunTooltip.dom.tsx", - "line": " const ref = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-05-30T20:26:57.154Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/data/infinite.std.ts", - "line": " const loaderRef = useRef(options.loader);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/data/infinite.std.ts", - "line": " const hasNextPageRef = useRef(options.hasNextPage);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/data/infinite.std.ts", - "line": " const querySignalRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/data/infinite.std.ts", - "line": " const stateRef = useRef(state);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/keyboard/FunKeyboard.dom.tsx", - "line": " const keyboardRef = useRef(props.keyboard);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/keyboard/FunKeyboard.dom.tsx", - "line": " const onStateChangeRef = useRef(props.onStateChange);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/panels/FunPanelEmojis.dom.tsx", - "line": " const scrollerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/panels/FunPanelEmojis.dom.tsx", - "line": " const popoverTriggerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-04-10T18:24:54.606Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/panels/FunPanelGifs.dom.tsx", - "line": " const scrollerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/fun/panels/FunPanelStickers.dom.tsx", - "line": " const scrollerRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-02-19T20:14:46.879Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/chatFolders/PreferencesEditChatFoldersPage.dom.tsx", - "line": " const didSaveOrDiscardChangesRef = useRef(false);", - "reasonCategory": "usageTrusted", - "updated": "2025-09-24T17:08:10.620Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/chatFolders/PreferencesEditChatFoldersPage.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-10-09T23:03:57.441Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/donations/DonateInputAmount.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-08-01T20:31:42.993Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/donations/DonateInputCardCvc.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-07-17T19:33:27.401Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/donations/DonateInputCardExp.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-07-17T19:33:27.401Z" - }, - { - "rule": "React-useRef", - "path": "ts/components/preferences/donations/DonateInputCardNumber.dom.tsx", - "line": " const inputRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2025-07-17T19:33:27.401Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useConfirmDiscard.dom.tsx", - "line": " const confirmDiscardPromise = useRef<", - "reasonCategory": "usageTrusted", - "updated": "2025-05-19T22:29:15.758Z", - "reasonDetail": "Holding on to a promise" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useDocumentKeyDown.dom.ts", - "line": " const listenerRef = useRef(listener);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-09T15:37:49.757Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useIntersectionObserver.std.ts", - "line": " const unobserveRef = useRef<(() => unknown) | null>(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-09-17T20:16:37.959Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useIsMounted.std.ts", - "line": " const isMounted = useRef(false);", - "reasonCategory": "usageTrusted", - "updated": "2023-10-04T20:50:45.297Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useNavBlocker.std.ts", - "line": " const nameRef = useRef(name);", - "reasonCategory": "usageTrusted", - "updated": "2025-09-24T17:08:10.620Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useNavBlocker.std.ts", - "line": " const shouldBlockRef = useRef(shouldBlock);", - "reasonCategory": "usageTrusted", - "updated": "2025-09-24T17:08:10.620Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/usePrevious.std.ts", - "line": " const previousValueRef = useRef(initialValue);", - "reasonCategory": "usageTrusted", - "updated": "2021-09-17T20:16:37.959Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useRestoreFocus.dom.ts", - "line": " const toFocusRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useRestoreFocus.dom.ts", - "line": " const lastFocusedRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-07-30T16:57:33.618Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useRestoreFocus.dom.ts", - "line": " const toFocusRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-10-22T00:52:39.251Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useRestoreFocus.dom.ts", - "line": " const lastFocusedRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2021-10-22T00:52:39.251Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useScrollLock.dom.tsx", - "line": " const onUserInterruptRef = useRef(onUserInterrupt);", - "reasonCategory": "usageTrusted", - "updated": "2023-09-19T17:05:51.321Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " const sizeRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " const onSizeChangeRef = useRef(onSizeChange);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " const ref = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " * const scrollerRef = useRef()", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " * const scrollerInnerRef = useRef()", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " const scrollRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/hooks/useSizeObserver.dom.tsx", - "line": " const onScrollChangeRef = useRef(onScrollChange);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-25T21:55:26.191Z" - }, - { - "rule": "React-useRef", - "path": "ts/quill/formatting/menu.dom.tsx", - "line": " const buttonRef = React.useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-04-22T00:07:56.294Z", - "reasonDetail": "Popper needs to reference the button" - }, - { - "rule": "React-useRef", - "path": "ts/quill/formatting/menu.dom.tsx", - "line": " const fadeOutTimerRef = React.useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-08-02T19:01:24.771Z", - "reasonDetail": "We need a persistent timer to know when to remove after fade-out" - }, - { - "rule": "React-useRef", - "path": "ts/quill/formatting/menu.dom.tsx", - "line": " const hoverTimerRef = React.useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-08-02T19:01:24.771Z", - "reasonDetail": "We need a persistent timer to track long-hovers" - }, - { - "rule": "DOM-innerHTML", - "path": "ts/quill/signal-clipboard/util.dom.ts", - "line": " event.clipboardData?.setData('text/signal', container.innerHTML);", - "reasonCategory": "regexMatchedSafeCode", - "updated": "2023-06-02T00:37:19.861Z", - "reasonDetail": "Reading from innerHTML, not setting it" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/ChatsTab.preload.tsx", - "line": " const lastOpenedConversationId = useRef();", - "reasonCategory": "usageTrusted", - "updated": "2023-08-25T17:37:23.002Z" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/ConversationPanel.preload.tsx", - "line": " const animateRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-13T23:34:39.367Z" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/ConversationPanel.preload.tsx", - "line": " const overlayRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-13T23:34:39.367Z" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/ConversationPanel.preload.tsx", - "line": " const focusRef = useRef(null);", - "reasonCategory": "usageTrusted", - "updated": "2023-07-13T23:34:39.367Z" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/ConversationPanel.preload.tsx", - "line": " const wasAnimatedRef = useRef(wasAnimated);", - "reasonCategory": "usageTrusted", - "updated": "2023-08-20T22:14:52.008Z" - }, - { - "rule": "React-useRef", - "path": "ts/state/smart/PinnedMessagesBar.preload.tsx", - "line": " const onCurrentChangeRef = useRef(onCurrentChange);", - "reasonCategory": "usageTrusted", - "updated": "2025-12-15T18:22:14.286Z" - }, - { - "rule": "DOM-innerHTML", - "path": "ts/windows/loading/start.dom.ts", - "line": " message.innerHTML = window.SignalContext.i18n('icu:optimizingApplication');", - "reasonCategory": "usageTrusted", - "updated": "2021-09-17T21:02:59.414Z" } ] diff --git a/ts/util/lint/linter.node.ts b/ts/util/lint/linter.node.ts index da16af10d4..39196a7693 100644 --- a/ts/util/lint/linter.node.ts +++ b/ts/util/lint/linter.node.ts @@ -25,6 +25,17 @@ const basePath = join(__dirname, '../../..'); const searchPattern = normalizePath(join(basePath, '**/*.{js,ts,tsx}')); +const THIRD_PARTY_PATHS = ['node_modules/', 'js/', 'components/']; + +function pathStartsWithOneOf( + filePath: string, + pathPrefixes: ReadonlyArray +): boolean { + return pathPrefixes.some(pathPrefix => { + return filePath.startsWith(pathPrefix); + }); +} + const excludedFilesRegexp = RegExp( [ '^release/', @@ -399,8 +410,15 @@ async function main(argv: ReadonlyArray): Promise { const lines = (await fs.promises.readFile(file, ENCODING)).split(/\r?\n/); rules.forEach((rule: RuleType) => { + if ( + rule.excludeOurCode && + !pathStartsWithOneOf(relativePath, THIRD_PARTY_PATHS) + ) { + return; + } + const excludedModules = rule.excludedModules || []; - if (excludedModules.some(module => relativePath.startsWith(module))) { + if (pathStartsWithOneOf(relativePath, excludedModules)) { return; } diff --git a/ts/util/lint/rules.json b/ts/util/lint/rules.json index 5c90114461..36cdbe8816 100644 --- a/ts/util/lint/rules.json +++ b/ts/util/lint/rules.json @@ -23,6 +23,7 @@ "name": "React-ref", "expression": "\\bref(\\s)*=\\b", "reason": "Potential XSS", + "excludeOurCode": true, "excludedModules": [ "node_modules/react-dom", "node_modules/tslint-microsoft-contrib", @@ -33,6 +34,7 @@ "name": "React-createRef", "expression": "\\bcreateRef\\(", "reason": "Potential XSS", + "excludeOurCode": true, "excludedModules": [ "node_modules/react/", "node_modules/react-dom", @@ -44,6 +46,7 @@ "name": "React-useRef", "expression": "\\buseRef(\\(|<)", "reason": "Potential XSS", + "excludeOurCode": true, "excludedModules": ["node_modules/react/", "node_modules/react-dom"] }, { diff --git a/ts/util/lint/types.std.ts b/ts/util/lint/types.std.ts index 56626af84b..4d25373e7d 100644 --- a/ts/util/lint/types.std.ts +++ b/ts/util/lint/types.std.ts @@ -52,6 +52,7 @@ export type RuleType = { expression?: string; reason: string; regex: RegExp; + excludeOurCode?: boolean; excludedModules?: Array; }; diff --git a/ts/windows/loading/start.dom.ts b/ts/windows/loading/start.dom.ts index e079e76919..ced8c177fa 100644 --- a/ts/windows/loading/start.dom.ts +++ b/ts/windows/loading/start.dom.ts @@ -4,5 +4,5 @@ import '../sandboxedInit.dom.js'; const message = document.getElementById('message'); if (message) { - message.innerHTML = window.SignalContext.i18n('icu:optimizingApplication'); + message.innerText = window.SignalContext.i18n('icu:optimizingApplication'); }