@@ -103,11 +103,15 @@ function replaceInInputShadow(
103103
104104function getValue ( node : Element | Node , config : SearchReplaceConfig ) : string {
105105 const nodeElement = getElementFromNode ( node )
106- console . log ( 'nodeElement' , nodeElement )
107106 // if it's an input or a textarea, take the value
108107 if ( nodeElement && ( nodeElement . nodeName === 'INPUT' || nodeElement . nodeName === 'TEXTAREA' ) ) {
109108 return nodeElement [ 'value' ]
110109 }
110+ // if it's an iframe with srcdoc, take the srcdoc
111+ if ( nodeElement && nodeElement . nodeName === 'IFRAME' && nodeElement . hasAttribute ( 'srcdoc' ) ) {
112+ return nodeElement [ 'srcdoc' ]
113+ }
114+
111115 // if it's a contenteditable div, take the outerHTML if we're replacing HTML, otherwise take the innerHTML
112116 if ( nodeElement && nodeElement . nodeName . match ( / D I V | B O D Y / g) && nodeElement . hasAttribute ( 'contenteditable' ) ) {
113117 console . log ( 'returning outer / innerHTML' )
@@ -189,12 +193,10 @@ function containsAncestor(element: Element, results: Map<Element, SearchReplaceR
189193function countOccurrences ( el : HTMLElement , config : SearchReplaceConfig ) : number {
190194 let target = getValue ( el , config )
191195
192- if ( config . hiddenContent && config . searchTarget === 'innerText' ) {
196+ if ( config . hiddenContent && config . searchTarget === 'innerText' && el . tagName !== 'IFRAME' ) {
193197 // textContent contains text of visible and hidden elements
194- console . log ( 'using textContent' )
195198 target = ( el as HTMLElement ) . textContent || ''
196199 }
197- console . log ( 'counting in' , target )
198200 const matches = target . match ( config . globalSearchPattern ) || [ ]
199201 return matches . length
200202}
@@ -233,6 +235,7 @@ function replaceInNodeOrElement(
233235 replaced = true
234236 }
235237 if ( replaced ) {
238+ console . log ( 'adding' , config . replaceAll ? occurrences . length : 1 , 'to replaced count' )
236239 replacementCount = config . replaceAll ? occurrences . length : 1 // adds one to replaced count if a replacement was made, adds occurrences if a global replace is made
237240 }
238241 nodeElement ?. dispatchEvent ( new Event ( 'input' , { bubbles : true } ) )
@@ -392,7 +395,7 @@ function replaceInner(
392395 }
393396
394397 const occurrences = countOccurrences ( element , config )
395- console . log ( 'occurrences' , occurrences , element )
398+ console . log ( 'occurrences' , occurrences )
396399 elementsChecked = updateResults ( elementsChecked , element , false , occurrences , 0 )
397400
398401 const ancestorChecked = containsAncestor ( element , elementsChecked )
@@ -527,6 +530,24 @@ function equivalentInIgnoredElements(ignoredElements: Set<Element>, element: Ele
527530 return false
528531}
529532
533+ function replaceInSrcDocIframe (
534+ config : SearchReplaceConfig ,
535+ iframe : HTMLIFrameElement ,
536+ searchReplaceResult : SearchReplaceResult ,
537+ elementsChecked : Map < Element , SearchReplaceResult >
538+ ) : ReplaceFunctionReturnType {
539+ const occurrences = countOccurrences ( iframe , config )
540+ console . log ( "occurrences in iframe's srcdoc" , occurrences )
541+ elementsChecked = updateResults ( elementsChecked , iframe , false , occurrences , 0 )
542+ searchReplaceResult . count . original = searchReplaceResult . count . original + occurrences
543+ if ( config . replace && occurrences ) {
544+ iframe . srcdoc = iframe . srcdoc . replace ( config . searchPattern , config . replaceTerm )
545+ console . log ( 'adding' , config . replaceAll ? occurrences : 1 , 'to replaced count' )
546+ searchReplaceResult . count . replaced += config . replaceAll ? occurrences : 1
547+ }
548+ return { searchReplaceResult, elementsChecked }
549+ }
550+
530551function replaceInHTML (
531552 config : SearchReplaceConfig ,
532553 document : Document ,
@@ -535,7 +556,6 @@ function replaceInHTML(
535556 elementsChecked : Map < Element , SearchReplaceResult >
536557) : ReplaceFunctionReturnType {
537558 for ( const [ originalIndex , originalElement ] of originalElements . entries ( ) ) {
538- console . log ( 'replacing in element' , originalElement )
539559 let clonedElement = originalElement . cloneNode ( true ) as HTMLElement
540560
541561 const { clonedElementRemoved, removedSet } = copyElementAndRemoveSelectedElements (
@@ -544,9 +564,11 @@ function replaceInHTML(
544564 // - match the element filter, but are not blob iframes, nor are WYSIWYG iframes.
545565 // Removes SCRIPT, STYLE, IFRAME, etc.
546566 // - match the input filter, as these are handled later
567+ // - are already in the elementsChecked map
547568 ( el : HTMLElement ) =>
548569 ( ! ! el . nodeName . match ( config . elementFilter ) && ! isBlobIframe ( el ) && ! isWYSIWYGEditorIframe ( el ) ) ||
549- isInputElement ( el ) ,
570+ isInputElement ( el ) ||
571+ elementsChecked . has ( el ) ,
550572 false
551573 )
552574 clonedElement = clonedElementRemoved as HTMLElement
@@ -671,7 +693,7 @@ export async function searchReplace(
671693 shadowRoots,
672694 }
673695 // we check other places if text was not replaced in a text editor
674- let result : ReplaceFunctionReturnType
696+ let result : ReplaceFunctionReturnType = { searchReplaceResult , elementsChecked }
675697 if ( inputFieldsOnly ) {
676698 result = replaceInputFields ( config , document , searchReplaceResult , elementsChecked )
677699 if ( config . replaceNext && result . searchReplaceResult . replaced ) {
@@ -680,17 +702,27 @@ export async function searchReplace(
680702 } else {
681703 const startingElement = document . body || document . querySelector ( 'div' )
682704
683- const searchableIframes = ( await getSearchableIframes ( window , document ) )
684- . map ( getInitialIframeElement )
685- . filter ( notEmpty )
686- console . log ( 'searchable iframes' , searchableIframes )
687- result = replaceInHTML (
688- config ,
689- document ,
690- [ startingElement , ...searchableIframes ] ,
691- searchReplaceResult ,
692- elementsChecked
693- )
705+ const searchableIframesInitial = await getSearchableIframes ( window , document )
706+ const srcDocIframes = searchableIframesInitial . filter ( ( iframe ) => iframe . hasAttribute ( 'srcdoc' ) )
707+ srcDocIframes . map ( ( iframe ) => {
708+ const srcDocResult = replaceInSrcDocIframe (
709+ config ,
710+ iframe ,
711+ result . searchReplaceResult ,
712+ result . elementsChecked
713+ )
714+ result . searchReplaceResult = srcDocResult . searchReplaceResult
715+ result . elementsChecked = srcDocResult . elementsChecked
716+ } )
717+ console . log ( JSON . stringify ( result . searchReplaceResult ) )
718+ console . log ( 'searchableIframesInitial' , searchableIframesInitial )
719+ const searchableIframes = searchableIframesInitial . filter ( ( iframe : HTMLIFrameElement ) => {
720+ return iframe . srcdoc === '' || iframe . srcdoc === undefined
721+ } )
722+ const searchable = searchableIframes . map ( getInitialIframeElement ) . filter ( notEmpty )
723+ console . log ( 'searchableIframes' , searchableIframes )
724+ console . log ( 'searchable' , searchable )
725+ result = replaceInHTML ( config , document , [ startingElement , ...searchable ] , searchReplaceResult , elementsChecked )
694726 }
695727
696728 return result
0 commit comments