@@ -13,8 +13,6 @@ import { LinkProcessor } from '../processors/clipboardLinkProcessor.js';
1313import { TextProcessor } from '../processors/clipboardTextProcessor.js' ;
1414
1515// Configuration
16- const EXCLUDED_HASH_TTL_MS = 5000 ;
17- const MAX_BLOCKED_HASHES = 50 ;
1816const MAX_RETRIES = 5 ;
1917const RETRY_DELAY_MS = 200 ;
2018
@@ -34,18 +32,18 @@ export class ClipboardMonitor {
3432 * @param {ExclusionUtils } exclusionUtils Utility for handling exclusion rules.
3533 * @param {string } imagesDir Path for generating color processor gradients.
3634 * @param {Function } onContentCaptured Callback for when content is captured.
35+ * @param {ClipboardCaptureGuardService } captureGuard Guard for suppression decisions.
3736 */
38- constructor ( exclusionUtils , imagesDir , onContentCaptured ) {
37+ constructor ( exclusionUtils , imagesDir , onContentCaptured , captureGuard ) {
3938 this . _exclusionUtils = exclusionUtils ;
4039 this . _imagesDir = imagesDir ;
4140 this . _onContentCaptured = onContentCaptured ;
41+ this . _captureGuard = captureGuard ;
4242
4343 this . _selection = null ;
4444 this . _isPaused = false ;
4545 this . _processClipboardTimeoutId = 0 ;
4646 this . _retryTimeoutId = 0 ;
47-
48- this . _blockedContentHashes = new Map ( ) ;
4947 }
5048
5149 /**
@@ -111,54 +109,61 @@ export class ClipboardMonitor {
111109 // Image
112110 const imageResult = await ImageProcessor . extract ( ) ;
113111 if ( imageResult ) {
114- this . _onContentCaptured ( imageResult ) ;
112+ if ( ! this . _shouldSuppress ( imageResult ) ) {
113+ this . _onContentCaptured ( imageResult ) ;
114+ }
115115 return ;
116116 }
117117
118118 // Text
119119 const textResult = await TextProcessor . extract ( ) ;
120120 if ( textResult ) {
121121 const text = textResult . text ;
122- const hash = this . _hashString ( text ) ;
123-
124- if ( this . _blockedContentHashes . has ( hash ) ) {
125- const expiry = this . _blockedContentHashes . get ( hash ) ;
126- if ( Date . now ( ) < expiry ) return ;
127- this . _blockedContentHashes . delete ( hash ) ;
128- }
129122
130123 const fileResult = await FileProcessor . process ( text ) ;
131124 if ( fileResult ) {
132- this . _onContentCaptured ( fileResult ) ;
125+ if ( ! this . _shouldSuppress ( fileResult ) ) {
126+ this . _onContentCaptured ( fileResult ) ;
127+ }
133128 return ;
134129 }
135130
136131 const linkResult = LinkProcessor . process ( text ) ;
137132 if ( linkResult ) {
138- this . _onContentCaptured ( linkResult ) ;
133+ if ( ! this . _shouldSuppress ( linkResult ) ) {
134+ this . _onContentCaptured ( linkResult ) ;
135+ }
139136 return ;
140137 }
141138
142139 const contactResult = await ContactProcessor . process ( text ) ;
143140 if ( contactResult ) {
144- this . _onContentCaptured ( contactResult ) ;
141+ if ( ! this . _shouldSuppress ( contactResult ) ) {
142+ this . _onContentCaptured ( contactResult ) ;
143+ }
145144 return ;
146145 }
147146
148147 const colorResult = ColorProcessor . process ( text , this . _imagesDir ) ;
149148 if ( colorResult ) {
150- this . _onContentCaptured ( colorResult ) ;
149+ if ( ! this . _shouldSuppress ( colorResult ) ) {
150+ this . _onContentCaptured ( colorResult ) ;
151+ }
151152 return ;
152153 }
153154
154155 const codeResult = CodeProcessor . process ( text ) ;
155156 if ( codeResult ) {
156- this . _onContentCaptured ( codeResult ) ;
157+ if ( ! this . _shouldSuppress ( codeResult ) ) {
158+ this . _onContentCaptured ( codeResult ) ;
159+ }
157160 return ;
158161 }
159162
160163 // Fallback
161- this . _onContentCaptured ( textResult ) ;
164+ if ( ! this . _shouldSuppress ( textResult ) ) {
165+ this . _onContentCaptured ( textResult ) ;
166+ }
162167 return ;
163168 }
164169
@@ -184,15 +189,7 @@ export class ClipboardMonitor {
184189 _hashAndBlockClipboardContent ( ) {
185190 clipboardGetText ( )
186191 . then ( ( text ) => {
187- if ( text ) {
188- const hash = this . _hashString ( text ) ;
189- this . _blockedContentHashes . set ( hash , Date . now ( ) + EXCLUDED_HASH_TTL_MS ) ;
190-
191- if ( this . _blockedContentHashes . size > MAX_BLOCKED_HASHES ) {
192- const first = this . _blockedContentHashes . keys ( ) . next ( ) . value ;
193- this . _blockedContentHashes . delete ( first ) ;
194- }
195- }
192+ if ( text ) this . _captureGuard ?. registerText ( text ) ;
196193 } )
197194 . catch ( ( ) => { } ) ;
198195 }
@@ -202,18 +199,19 @@ export class ClipboardMonitor {
202199 // ========================================================================
203200
204201 /**
205- * Generate a simple hash from a string .
202+ * Decide whether a capture should be suppressed and register allowed hashes .
206203 *
207- * @param {string } str Input string .
208- * @returns {number } Generated hash .
204+ * @param {Object } result Extracted result with hash .
205+ * @returns {boolean } True if suppressed .
209206 * @private
210207 */
211- _hashString ( str ) {
212- let hash = 5381 ;
213- for ( let i = 0 ; i < str . length ; i ++ ) {
214- hash = ( ( hash << 5 ) + hash + str . charCodeAt ( i ) ) | 0 ;
215- }
216- return hash ;
208+ _shouldSuppress ( result ) {
209+ if ( ! this . _captureGuard || ! result ?. hash ) return false ;
210+
211+ if ( this . _captureGuard . shouldBlockHash ( result . hash ) ) return true ;
212+
213+ this . _captureGuard . registerHash ( result . hash ) ;
214+ return false ;
217215 }
218216
219217 // ========================================================================
0 commit comments