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