Skip to content

Commit 92ed8b3

Browse files
committed
fix: fix architecture of move function by using the getMatchingTag function to get the end pos
1 parent 9cf2933 commit 92ed8b3

File tree

1 file changed

+125
-66
lines changed

1 file changed

+125
-66
lines changed

src/LiveDevelopment/LivePreviewEdit.js

Lines changed: 125 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)