@@ -73,6 +73,129 @@ suite('playground-code-editor', () => {
7373 } ) ;
7474 } ) ;
7575
76+ test ( 'does NOT dispatch change event when switching documentKey and value together' , async ( ) => {
77+ const editor = document . createElement ( 'playground-code-editor' ) ;
78+ const DOCUMENT_KEY1 = { doc : 1 } ;
79+ const DOCUMENT_KEY2 = { doc : 2 } ;
80+
81+ editor . value = 'document 1' ;
82+ editor . documentKey = DOCUMENT_KEY1 ;
83+ container . appendChild ( editor ) ;
84+ await editor . updateComplete ;
85+ await raf ( ) ;
86+
87+ let changeCount = 0 ;
88+ editor . addEventListener ( 'change' , ( ) => {
89+ changeCount ++ ;
90+ } ) ;
91+
92+ // This simulates what playground-file-editor does when switching files
93+ // Both value AND documentKey change together in a single update
94+ editor . value = 'document 2' ;
95+ editor . documentKey = DOCUMENT_KEY2 ;
96+
97+ // Wait for Lit's update cycle
98+ await editor . updateComplete ;
99+ await raf ( ) ;
100+
101+ // Wait for any potential async change events
102+ await wait ( 100 ) ;
103+
104+ // Switch back - this is where the bug manifests in lit.dev
105+ editor . value = 'document 1 modified' ;
106+ editor . documentKey = DOCUMENT_KEY1 ;
107+ await editor . updateComplete ;
108+ await raf ( ) ;
109+ await wait ( 100 ) ;
110+
111+ assert . equal (
112+ changeCount ,
113+ 0 ,
114+ 'Switching documentKey and value together should not fire change event'
115+ ) ;
116+ } ) ;
117+
118+ test ( 'does NOT dispatch change event when switching documentKey' , async ( ) => {
119+ const editor = document . createElement ( 'playground-code-editor' ) ;
120+ const DOCUMENT_KEY1 = { dockey : 1 } ;
121+ const DOCUMENT_KEY2 = { dockey : 2 } ;
122+
123+ editor . value = 'document 1' ;
124+ editor . documentKey = DOCUMENT_KEY1 ;
125+ container . appendChild ( editor ) ;
126+ await editor . updateComplete ;
127+ await raf ( ) ;
128+
129+ let changeCount = 0 ;
130+ editor . addEventListener ( 'change' , ( ) => changeCount ++ ) ;
131+
132+ // Switch to a different document - should NOT fire change event
133+ editor . value = 'document 2' ;
134+ editor . documentKey = DOCUMENT_KEY2 ;
135+ await editor . updateComplete ;
136+ await raf ( ) ;
137+
138+ assert . equal (
139+ changeCount ,
140+ 0 ,
141+ 'Switching documentKey should not fire change event'
142+ ) ;
143+
144+ // Switch back to first document - should NOT fire change event
145+ editor . value = 'document 1' ;
146+ editor . documentKey = DOCUMENT_KEY1 ;
147+ await editor . updateComplete ;
148+ await raf ( ) ;
149+
150+ assert . equal (
151+ changeCount ,
152+ 0 ,
153+ 'Switching back to original documentKey should not fire change event'
154+ ) ;
155+ } ) ;
156+
157+ test ( 'dispatches change event only for user edits, not programmatic changes' , async ( ) => {
158+ const editor = document . createElement ( 'playground-code-editor' ) ;
159+ editor . value = 'foo' ;
160+ container . appendChild ( editor ) ;
161+ await editor . updateComplete ;
162+ await raf ( ) ;
163+
164+ const editorInternals = editor as unknown as {
165+ _editorView : EditorView ;
166+ } ;
167+
168+ let changeCount = 0 ;
169+ editor . addEventListener ( 'change' , ( ) => changeCount ++ ) ;
170+
171+ // Programmatic change - should NOT fire
172+ editor . value = 'bar' ;
173+ await editor . updateComplete ;
174+ await raf ( ) ;
175+ assert . equal ( changeCount , 0 , 'No change event after programmatic update' ) ;
176+
177+ // User edit via CodeMirror - SHOULD fire
178+ editorInternals . _editorView . dispatch ( {
179+ changes : {
180+ from : 0 ,
181+ to : editorInternals . _editorView . state . doc . length ,
182+ insert : 'baz' ,
183+ } ,
184+ } ) ;
185+ await raf ( ) ;
186+ assert . equal ( changeCount , 1 , 'Change event fired after user edit' ) ;
187+
188+ // Another programmatic change - should NOT fire
189+ editor . value = 'qux' ;
190+ await editor . updateComplete ;
191+ await raf ( ) ;
192+ assert . equal (
193+ changeCount ,
194+ 1 ,
195+ 'No additional change event after another programmatic update'
196+ ) ;
197+ } ) ;
198+
76199 suite ( 'history' , ( ) => {
77200 let editor : PlaygroundCodeEditor ;
78201 let editorInternals : {
0 commit comments