@@ -32,12 +32,20 @@ export class DevtoolsSource extends Element {
3232 .cm-content {
3333 padding: 0 !important;
3434 }
35+
36+ .source-container {
37+ width: 100%;
38+ height: 100%;
39+ }
3540 `
3641 ]
3742
3843 @consume ( { context : sourceContext , subscribe : true } )
3944 sources : Record < string , string > = { }
4045
46+ #editorView?: EditorView
47+ #activeFile?: string
48+
4149 connectedCallback ( ) : void {
4250 super . connectedCallback ( )
4351 window . addEventListener (
@@ -46,49 +54,82 @@ export class DevtoolsSource extends Element {
4654 )
4755 }
4856
49- #renderEditor( filePath : string , highlightLine ?: number ) {
50- if ( ! this . sources ) {
57+ disconnectedCallback ( ) : void {
58+ super . disconnectedCallback ( )
59+ this . #editorView?. destroy ( )
60+ this . #editorView = undefined
61+ }
62+
63+ updated ( ) {
64+ const sourceFileNames = Object . keys ( this . sources || { } )
65+ if ( sourceFileNames . length === 0 ) {
5166 return
5267 }
53- const source = this . sources [ filePath ]
68+ // Mount or refresh the editor for the first source file
69+ this . #mountEditor( sourceFileNames [ 0 ] )
70+ }
71+
72+ #mountEditor( filePath : string , highlightLine ?: number ) {
73+ const source = this . sources ?. [ filePath ]
5474 if ( ! source ) {
5575 return
5676 }
5777
5878 const container =
59- this . shadowRoot ?. querySelector ( 'section' ) ||
60- this . shadowRoot ?. querySelector ( '.cm-editor' )
79+ this . shadowRoot ?. querySelector < HTMLElement > ( '.source-container' )
6180 if ( ! container ) {
6281 return
6382 }
6483
84+ // Reuse the existing editor if the file hasn't changed
85+ if ( this . #editorView && this . #activeFile === filePath ) {
86+ if ( highlightLine && highlightLine > 0 ) {
87+ this . #scrollToLine( this . #editorView, highlightLine )
88+ }
89+ return
90+ }
91+
92+ // Destroy previous editor instance before creating a new one
93+ this . #editorView?. destroy ( )
94+
6595 const opts : EditorViewConfig = {
6696 root : this . shadowRoot ! ,
6797 extensions : [ basicSetup , javascript ( ) , oneDark ] ,
6898 doc : source ,
69- selection : { anchor : 4 }
99+ parent : container
70100 }
71- const editorView = new EditorView ( opts )
72- container . replaceWith ( editorView . dom )
101+ this . # editorView = new EditorView ( opts )
102+ this . #activeFile = filePath
73103
74104 if ( highlightLine && highlightLine > 0 ) {
75- try {
76- const lineInfo = editorView . state . doc . line ( highlightLine )
77- requestAnimationFrame ( ( ) => {
78- editorView . dispatch ( {
79- selection : { anchor : lineInfo . from } ,
80- effects : EditorView . scrollIntoView ( lineInfo . from , { y : 'center' } )
81- } )
105+ this . #scrollToLine( this . #editorView, highlightLine )
106+ }
107+ }
108+
109+ #scrollToLine( editorView : EditorView , line : number ) {
110+ try {
111+ const lineInfo = editorView . state . doc . line ( line )
112+ requestAnimationFrame ( ( ) => {
113+ editorView . dispatch ( {
114+ selection : { anchor : lineInfo . from } ,
115+ effects : EditorView . scrollIntoView ( lineInfo . from , { y : 'center' } )
82116 } )
83- } catch {
84- /* ignore */
85- }
117+ } )
118+ } catch {
119+ /* ignore out-of-range line numbers */
86120 }
87121 }
88122
89- #highlightCallSource( ev : CustomEvent < string > ) {
90- const [ filePath , line ] = ev . detail . split ( ':' )
91- this . #renderEditor( filePath , parseInt ( line , 10 ) )
123+ #highlightCallSource( ev : Event ) {
124+ const [ filePath , line ] = ( ev as CustomEvent < string > ) . detail . split ( ':' )
125+ // If the source for this file is already loaded, mount and scroll immediately
126+ if ( this . sources ?. [ filePath ] ) {
127+ this . #mountEditor( filePath , parseInt ( line , 10 ) )
128+ } else {
129+ // Source not yet available — will be mounted in updated() once it arrives;
130+ // store desired highlight so we can apply it then.
131+ this . #activeFile = filePath
132+ }
92133 this . closest ( 'wdio-devtools-tabs' ) ?. activateTab ( 'Source' )
93134 }
94135
@@ -98,8 +139,7 @@ export class DevtoolsSource extends Element {
98139 return html `< wdio-devtools-placeholder > </ wdio-devtools-placeholder > `
99140 }
100141
101- this . #renderEditor( sourceFileNames [ 0 ] )
102- return html ` < section class ="p-2 "> loading...</ section > `
142+ return html `< div class ="source-container "> </ div > `
103143 }
104144}
105145
0 commit comments