@@ -290,14 +290,12 @@ export function isElemVisible(el: HTMLElement): boolean {
290290export function replaceTextareaSelection ( textarea : HTMLTextAreaElement , text : string ) {
291291 const before = textarea . value . slice ( 0 , textarea . selectionStart ?? undefined ) ;
292292 const after = textarea . value . slice ( textarea . selectionEnd ?? undefined ) ;
293- let success = true ;
293+ let success = false ;
294294
295295 textarea . contentEditable = 'true' ;
296296 try {
297297 success = document . execCommand ( 'insertText' , false , text ) ; // eslint-disable-line @typescript-eslint/no-deprecated
298- } catch {
299- success = false ;
300- }
298+ } catch { } // ignore the error if execCommand is not supported or failed
301299 textarea . contentEditable = 'false' ;
302300
303301 if ( success && ! textarea . value . slice ( 0 , textarea . selectionStart ?? undefined ) . endsWith ( text ) ) {
@@ -310,11 +308,10 @@ export function replaceTextareaSelection(textarea: HTMLTextAreaElement, text: st
310308 }
311309}
312310
313- // Warning: Do not enter any unsanitized variables here
314311export function createElementFromHTML < T extends HTMLElement > ( htmlString : string ) : T {
315312 htmlString = htmlString . trim ( ) ;
316- // some tags like "tr" are special, it must use a correct parent container to create
317- // eslint-disable-next-line github/unescaped-html-literal -- FIXME: maybe we need to use other approaches to create elements from HTML, e.g. using DOMParser
313+ // There is no way to create some elements without a proper parent, jQuery's approach: https://github.com/jquery/jquery/blob/main/src/manipulation/wrapMap.js
314+ // eslint-disable-next-line github/unescaped-html-literal
318315 if ( htmlString . startsWith ( '<tr' ) ) {
319316 const container = document . createElement ( 'table' ) ;
320317 container . innerHTML = htmlString ;
@@ -364,14 +361,19 @@ export function addDelegatedEventListener<T extends HTMLElement, E extends Event
364361 const elem = ( e . target as HTMLElement ) . closest ( selector ) ;
365362 // It strictly checks "parent contains the target elem" to avoid side effects of selector running on outside the parent.
366363 // Keep in mind that the elem could have been removed from parent by other event handlers before this event handler is called.
367- // For example: tippy popup item, the tippy popup could be hidden and removed from DOM before this.
368- // It is caller's responsibility make sure the elem is still in parent's DOM when this event handler is called.
364+ // For example, tippy popup item, the tippy popup could be hidden and removed from DOM before this.
365+ // It is the caller's responsibility to make sure the elem is still in parent's DOM when this event handler is called.
369366 if ( ! elem || ( parent !== document && ! parent . contains ( elem ) ) ) return ;
370367 listener ( elem as T , e as E ) ;
371368 } , options ) ;
372369}
373370
374- /** Returns whether a click event is a left-click without any modifiers held */
371+ // Returns whether a click event is a left-click without any modifiers held
375372export function isPlainClick ( e : MouseEvent ) {
376373 return e . button === 0 && ! e . ctrlKey && ! e . metaKey && ! e . altKey && ! e . shiftKey ;
377374}
375+
376+ let uniqueIdCounter = 0 ;
377+ export function generateUniqueId ( prefix : string = '' ) : string {
378+ return `${ prefix } ${ uniqueIdCounter ++ } ` ;
379+ }
0 commit comments