Skip to content

Commit e350756

Browse files
committed
feat: element selection and content editable setting
1 parent d942ece commit e350756

File tree

2 files changed

+124
-18
lines changed

2 files changed

+124
-18
lines changed

src/LiveDevelopment/BrowserScripts/LiveDevProtocolRemote.js

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -390,25 +390,50 @@
390390
function onDocumentClick(event) {
391391
// Get the user's current selection
392392
const selection = window.getSelection();
393-
394-
// Check if there is a selection
395-
if (selection.toString().length > 0) {
396-
// if there is any selection like text or others, we don't see it as a live selection event
397-
// Eg: user may selects ome text in live preview to copy, in which case we should nt treat it
398-
// as a live select.
399-
return;
400-
}
401393
var element = event.target;
402394
if (element && element.hasAttribute('data-brackets-id')) {
403-
MessageBroker.send({
404-
"tagId": element.getAttribute('data-brackets-id'),
405-
"nodeID": element.id,
406-
"nodeClassList": element.classList,
407-
"nodeName": element.nodeName,
408-
"allSelectors": _getAllInheritedSelectorsInOrder(element),
409-
"contentEditable": element.contentEditable === 'true',
410-
"clicked": true
411-
});
395+
// Check if it's a double-click for direct editing
396+
if (event.detail === 2 && element.textContent && !['INPUT', 'TEXTAREA', 'SELECT'].includes(element.tagName)) {
397+
// Double-click detected, enable direct editing
398+
// Make the element editable
399+
if (window._LD && window._LD.DOMEditHandler) {
400+
// Use the existing DOMEditHandler to handle the edit
401+
window._LD.startEditing(element);
402+
} else {
403+
MessageBroker.send({
404+
"tagId": element.getAttribute('data-brackets-id'),
405+
"nodeID": element.id,
406+
"nodeClassList": element.classList,
407+
"nodeName": element.nodeName,
408+
"allSelectors": _getAllInheritedSelectorsInOrder(element),
409+
"contentEditable": element.contentEditable === 'true',
410+
"clicked": true,
411+
"edit": true
412+
});
413+
}
414+
415+
// Prevent default behavior and stop propagation
416+
event.preventDefault();
417+
event.stopPropagation();
418+
} else {
419+
// Regular click, just send the information
420+
// Check if there is a selection
421+
if (selection.toString().length > 0) {
422+
// if there is any selection like text or others, we don't see it as a live selection event
423+
// Eg: user may selects ome text in live preview to copy, in which case we should nt treat it
424+
// as a live select.
425+
return;
426+
}
427+
MessageBroker.send({
428+
"tagId": element.getAttribute('data-brackets-id'),
429+
"nodeID": element.id,
430+
"nodeClassList": element.classList,
431+
"nodeName": element.nodeName,
432+
"allSelectors": _getAllInheritedSelectorsInOrder(element),
433+
"contentEditable": element.contentEditable === 'true',
434+
"clicked": true
435+
});
436+
}
412437
}
413438
}
414439
window.document.addEventListener("click", onDocumentClick);

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,85 @@ function RemoteFunctions(config) {
11561156
return JSON.stringify(config);
11571157
}
11581158

1159+
// Function to handle direct editing of elements in the live preview
1160+
function startEditing(element) {
1161+
if (!element) {
1162+
return;
1163+
}
1164+
1165+
// Make the element editable
1166+
element.setAttribute("contenteditable", "true");
1167+
element.focus();
1168+
1169+
// Save the original content for potential cancellation
1170+
element._originalContent = element.innerHTML;
1171+
1172+
// Add event listeners for editing
1173+
function onBlur() {
1174+
finishEditing(element);
1175+
}
1176+
1177+
function onKeyDown(event) {
1178+
if (event.key === "Escape") {
1179+
// Cancel editing
1180+
element.innerHTML = element._originalContent;
1181+
finishEditing(element);
1182+
event.preventDefault();
1183+
} else if (event.key === "Enter" && !event.shiftKey) {
1184+
// Finish editing on Enter (unless Shift is held)
1185+
finishEditing(element);
1186+
event.preventDefault();
1187+
}
1188+
}
1189+
1190+
element.addEventListener("blur", onBlur);
1191+
element.addEventListener("keydown", onKeyDown);
1192+
1193+
// Store the event listeners for later removal
1194+
element._editListeners = {
1195+
blur: onBlur,
1196+
keydown: onKeyDown
1197+
};
1198+
}
1199+
1200+
// Function to finish editing and apply changes
1201+
function finishEditing(element) {
1202+
if (!element || !element.hasAttribute("contenteditable")) {
1203+
return;
1204+
}
1205+
1206+
// Remove contenteditable attribute
1207+
element.removeAttribute("contenteditable");
1208+
1209+
// Remove event listeners
1210+
if (element._editListeners) {
1211+
element.removeEventListener("blur", element._editListeners.blur);
1212+
element.removeEventListener("keydown", element._editListeners.keydown);
1213+
delete element._editListeners;
1214+
}
1215+
1216+
// Get the new content
1217+
const newContent = element.innerHTML;
1218+
1219+
// If content has changed, send the edit to the editor
1220+
if (newContent !== element._originalContent && element.hasAttribute("data-brackets-id")) {
1221+
const tagId = element.getAttribute("data-brackets-id");
1222+
1223+
// Create a text edit operation
1224+
// const edit = {
1225+
// type: "textReplace",
1226+
// parentID: element.parentNode.getAttribute("data-brackets-id"),
1227+
// tagID: tagId,
1228+
// content: newContent
1229+
// };
1230+
//
1231+
// todo: send the edited text to phoenix to change in text editor
1232+
}
1233+
1234+
// Clean up
1235+
delete element._originalContent;
1236+
}
1237+
11591238
// init
11601239
_editHandler = new DOMEditHandler(window.document);
11611240

@@ -1182,6 +1261,8 @@ function RemoteFunctions(config) {
11821261
"redrawHighlights" : redrawHighlights,
11831262
"applyDOMEdits" : applyDOMEdits,
11841263
"getSimpleDOM" : getSimpleDOM,
1185-
"updateConfig" : updateConfig
1264+
"updateConfig" : updateConfig,
1265+
"startEditing" : startEditing,
1266+
"finishEditing" : finishEditing
11861267
};
11871268
}

0 commit comments

Comments
 (0)