@@ -184,6 +184,67 @@ define(function (require, exports, module) {
184184 } ) ;
185185 }
186186
187+ /**
188+ * this function is to clean up the empty lines after an element is removed
189+ * @param {Object } editor - the editor instance
190+ * @param {Object } range - the range where element was removed
191+ */
192+ function _cleanupAfterRemoval ( editor , range ) {
193+ const lineToCheck = range . from . line ;
194+
195+ // check if the line where element was removed is now empty
196+ if ( lineToCheck < editor . lineCount ( ) ) {
197+ const currentLineText = editor . getLine ( lineToCheck ) ;
198+ if ( currentLineText && currentLineText . trim ( ) === "" ) {
199+ // remove the empty line
200+ const lineStart = { line : lineToCheck , ch : 0 } ;
201+ const lineEnd = { line : lineToCheck + 1 , ch : 0 } ;
202+ editor . replaceRange ( "" , lineStart , lineEnd ) ;
203+ }
204+ }
205+
206+ // also we need to check the previous line if it became empty
207+ if ( lineToCheck > 0 ) {
208+ const prevLineText = editor . getLine ( lineToCheck - 1 ) ;
209+ if ( prevLineText && prevLineText . trim ( ) === "" ) {
210+ const lineStart = { line : lineToCheck - 1 , ch : 0 } ;
211+ const lineEnd = { line : lineToCheck , ch : 0 } ;
212+ editor . replaceRange ( "" , lineStart , lineEnd ) ;
213+ }
214+ }
215+ }
216+
217+ /**
218+ * this function is to make sure that we insert elements with proper indentation
219+ *
220+ * @param {Object } editor - the editor instance
221+ * @param {Object } insertPos - position where to insert
222+ * @param {Boolean } insertAfterMode - whether to insert after the position
223+ * @param {String } targetIndent - the indentation to use
224+ * @param {String } sourceText - the text to insert
225+ */
226+ function _insertElementWithIndentation ( editor , insertPos , insertAfterMode , targetIndent , sourceText ) {
227+ if ( insertAfterMode ) {
228+ // Insert after the target element
229+ editor . replaceRange ( "\n" + targetIndent + sourceText , insertPos ) ;
230+ } else {
231+ // Insert before the target element
232+ const insertLine = insertPos . line ;
233+ const lineStart = { line : insertLine , ch : 0 } ;
234+
235+ // Get current line content to preserve any existing indentation structure
236+ const currentLine = editor . getLine ( insertLine ) ;
237+
238+ if ( currentLine && currentLine . trim ( ) === "" ) {
239+ // the line is empty, replace it entirely
240+ editor . replaceRange ( targetIndent + sourceText , lineStart , { line : insertLine , ch : currentLine . length } ) ;
241+ } else {
242+ // the line has content, insert before it
243+ editor . replaceRange ( targetIndent + sourceText + "\n" , lineStart ) ;
244+ }
245+ }
246+ }
247+
187248 /**
188249 * This function is responsible for moving an element from one position to another in the source code
189250 * it is called when there is drag-drop in the live preview
@@ -203,14 +264,40 @@ define(function (require, exports, module) {
203264 return ;
204265 }
205266
206- // position of source and target elements in the editor
207- const sourceRange = HTMLInstrumentation . getPositionFromTagId ( editor , sourceId ) ;
208- const targetRange = HTMLInstrumentation . getPositionFromTagId ( editor , targetId ) ;
267+ // get the start range from the getPositionFromTagId function
268+ // and we get the end range from the findMatchingTag function
269+ // NOTE: we cannot get the end range from getPositionFromTagId
270+ // because on non-beautified code getPositionFromTagId may not provide correct end position
271+ const sourceStartRange = HTMLInstrumentation . getPositionFromTagId ( editor , sourceId ) ;
272+ if ( ! sourceStartRange ) {
273+ return ;
274+ }
275+
276+ const sourceEndRange = CodeMirror . findMatchingTag ( editor . _codeMirror , sourceStartRange . from ) ;
277+ if ( ! sourceEndRange ) {
278+ return ;
279+ }
280+
281+ const targetStartRange = HTMLInstrumentation . getPositionFromTagId ( editor , targetId ) ;
282+ if ( ! targetStartRange ) {
283+ return ;
284+ }
209285
210- if ( ! sourceRange || ! targetRange ) {
286+ const targetEndRange = CodeMirror . findMatchingTag ( editor . _codeMirror , targetStartRange . from ) ;
287+ if ( ! targetEndRange ) {
211288 return ;
212289 }
213290
291+ const sourceRange = {
292+ from : sourceStartRange . from ,
293+ to : sourceEndRange . close . to
294+ } ;
295+
296+ const targetRange = {
297+ from : targetStartRange . from ,
298+ to : targetEndRange . close . to
299+ } ;
300+
214301 const sourceText = editor . getTextBetween ( sourceRange . from , sourceRange . to ) ;
215302 const targetIndent = editor . getTextBetween ( { line : targetRange . from . line , ch : 0 } , targetRange . from ) ;
216303
@@ -223,57 +310,6 @@ define(function (require, exports, module) {
223310 sourceRange . from . line < targetRange . from . line ||
224311 ( sourceRange . from . line === targetRange . from . line && sourceRange . from . ch < targetRange . from . ch ) ;
225312
226- // this function is to clean up the empty lines after an element is removed
227- function cleanupAfterRemoval ( range ) {
228- const lineToCheck = range . from . line ;
229-
230- // check if the line where element was removed is now empty
231- if ( lineToCheck < editor . lineCount ( ) ) {
232- const currentLineText = editor . getLine ( lineToCheck ) ;
233- if ( currentLineText && currentLineText . trim ( ) === "" ) {
234- // remove the empty line
235- const lineStart = { line : lineToCheck , ch : 0 } ;
236- const lineEnd = { line : lineToCheck + 1 , ch : 0 } ;
237- editor . replaceRange ( "" , lineStart , lineEnd ) ;
238- }
239- }
240-
241- // also we need to check the previous line if it became empty
242- if ( lineToCheck > 0 ) {
243- const prevLineText = editor . getLine ( lineToCheck - 1 ) ;
244- if ( prevLineText && prevLineText . trim ( ) === "" ) {
245- const lineStart = { line : lineToCheck - 1 , ch : 0 } ;
246- const lineEnd = { line : lineToCheck , ch : 0 } ;
247- editor . replaceRange ( "" , lineStart , lineEnd ) ;
248- }
249- }
250- }
251-
252- // this function is to make sure that we insert elements with proper indentation
253- function insertElementWithIndentation ( insertPos , insertAfterMode , useTargetIndent ) {
254- const indent = useTargetIndent ? targetIndent : targetIndent ;
255-
256- if ( insertAfterMode ) {
257- // Insert after the target element
258- editor . replaceRange ( "\n" + indent + sourceText , insertPos ) ;
259- } else {
260- // Insert before the target element
261- const insertLine = insertPos . line ;
262- const lineStart = { line : insertLine , ch : 0 } ;
263-
264- // Get current line content to preserve any existing indentation structure
265- const currentLine = editor . getLine ( insertLine ) ;
266-
267- if ( currentLine && currentLine . trim ( ) === "" ) {
268- // the line is empty, replace it entirely
269- editor . replaceRange ( indent + sourceText , lineStart , { line : insertLine , ch : currentLine . length } ) ;
270- } else {
271- // the line has content, insert before it
272- editor . replaceRange ( indent + sourceText + "\n" , lineStart ) ;
273- }
274- }
275- }
276-
277313 // creating a batch operation so that undo in live preview works fine
278314 editor . document . batchOperation ( function ( ) {
279315 if ( sourceBeforeTarget ) {
@@ -283,17 +319,27 @@ define(function (require, exports, module) {
283319 line : targetRange . to . line ,
284320 ch : targetRange . to . ch
285321 } ;
286- insertElementWithIndentation ( insertPos , true , true ) ;
322+ _insertElementWithIndentation ( editor , insertPos , true , targetIndent , sourceText ) ;
287323 } else {
288324 // insert before target
289- insertElementWithIndentation ( targetRange . from , false , true ) ;
325+ _insertElementWithIndentation ( editor , targetRange . from , false , targetIndent , sourceText ) ;
290326 }
291327
292328 // Now remove the source element (NOTE: the positions have shifted)
293- const updatedSourceRange = HTMLInstrumentation . getPositionFromTagId ( editor , sourceId ) ;
294- if ( updatedSourceRange ) {
295- editor . replaceRange ( "" , updatedSourceRange . from , updatedSourceRange . to ) ;
296- cleanupAfterRemoval ( updatedSourceRange ) ;
329+ const updatedSourceStartRange = HTMLInstrumentation . getPositionFromTagId ( editor , sourceId ) ;
330+ if ( updatedSourceStartRange ) {
331+ const updatedSourceEndRange = CodeMirror . findMatchingTag (
332+ editor . _codeMirror , updatedSourceStartRange . from
333+ ) ;
334+
335+ if ( updatedSourceEndRange ) {
336+ const updatedSourceRange = {
337+ from : updatedSourceStartRange . from ,
338+ to : updatedSourceEndRange . close . to
339+ } ;
340+ editor . replaceRange ( "" , updatedSourceRange . from , updatedSourceRange . to ) ;
341+ _cleanupAfterRemoval ( editor , updatedSourceRange ) ;
342+ }
297343 }
298344 } else {
299345 // This handles the case when target is before source: remove first, then insert
@@ -302,23 +348,36 @@ define(function (require, exports, module) {
302348
303349 // Remove the source element first
304350 editor . replaceRange ( "" , sourceRange . from , sourceRange . to ) ;
305- cleanupAfterRemoval ( originalSourceRange ) ;
351+ _cleanupAfterRemoval ( editor , originalSourceRange ) ;
306352
307353 // Recalculate target range after source removal as the positions have shifted
308- const updatedTargetRange = HTMLInstrumentation . getPositionFromTagId ( editor , targetId ) ;
309- if ( ! updatedTargetRange ) {
354+ const updatedTargetStartRange = HTMLInstrumentation . getPositionFromTagId ( editor , targetId ) ;
355+ if ( ! updatedTargetStartRange ) {
310356 return ;
311357 }
312358
359+ const updatedTargetEndRange = CodeMirror . findMatchingTag (
360+ editor . _codeMirror , updatedTargetStartRange . from
361+ ) ;
362+
363+ if ( ! updatedTargetEndRange ) {
364+ return ;
365+ }
366+
367+ const updatedTargetRange = {
368+ from : updatedTargetStartRange . from ,
369+ to : updatedTargetEndRange . close . to
370+ } ;
371+
313372 if ( insertAfter ) {
314373 const insertPos = {
315374 line : updatedTargetRange . to . line ,
316375 ch : updatedTargetRange . to . ch
317376 } ;
318- insertElementWithIndentation ( insertPos , true , true ) ;
377+ _insertElementWithIndentation ( editor , insertPos , true , targetIndent , sourceText ) ;
319378 } else {
320379 // Insert before target
321- insertElementWithIndentation ( updatedTargetRange . from , false , true ) ;
380+ _insertElementWithIndentation ( editor , updatedTargetRange . from , false , targetIndent , sourceText ) ;
322381 }
323382 }
324383 } ) ;
0 commit comments