From 61ef12c3aade2c08cd04b0cb9f97ac7f8b413d5f Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 11 Dec 2023 05:36:02 +0000 Subject: [PATCH] Bug 1764895 - part 2: Make comm-central stop using `nsIEditor.setShouldTxnSetSelection` r=mkmelin It'll be removed and `nsIEditor.insertNode()` and `nsIEditor.deleteNode()` have new optional parameter which if you set to true, selection won't be modified by the editor (except `beforeinput` and `input` event listeners). Differential Revision: https://phabricator.services.mozilla.com/D196006 --HG-- extra : amend_source : 4ac61cde6cdb49db4b77406c55442b762faee442 --- .../compose/content/dialogs/EdImageProps.js | 4 +-- .../compose/content/dialogs/EdLinkProps.js | 9 ++++-- .../dialogs/content/EdDialogCommon.js | 30 ++++++++++--------- .../dialogs/content/EdFieldSetProps.js | 21 ++++++++----- .../dialogs/content/EdImageProps.js | 4 +-- .../dialogs/content/EdInputImage.js | 4 +-- .../dialogs/content/EdLabelProps.js | 12 ++++---- .../components/dialogs/content/EdLinkProps.js | 9 ++++-- .../dialogs/content/EdSelectProps.js | 16 ++++++---- .../dialogs/content/EdTextAreaProps.js | 16 ++++++---- 10 files changed, 70 insertions(+), 55 deletions(-) diff --git a/mail/components/compose/content/dialogs/EdImageProps.js b/mail/components/compose/content/dialogs/EdImageProps.js index 80963feafe..de58e5d105 100644 --- a/mail/components/compose/content/dialogs/EdImageProps.js +++ b/mail/components/compose/content/dialogs/EdImageProps.js @@ -253,9 +253,7 @@ function onAccept(event) { if (gImageMap && gInsertNewIMap) { // Insert the ImageMap element at beginning of document var body = editor.rootElement; - editor.setShouldTxnSetSelection(false); - editor.insertNode(gImageMap, body, 0); - editor.setShouldTxnSetSelection(true); + editor.insertNode(gImageMap, body, 0, true /* preserve selection */); } } catch (e) { dump(e); diff --git a/mail/components/compose/content/dialogs/EdLinkProps.js b/mail/components/compose/content/dialogs/EdLinkProps.js index 6842efc611..41daf56c3e 100644 --- a/mail/components/compose/content/dialogs/EdLinkProps.js +++ b/mail/components/compose/content/dialogs/EdLinkProps.js @@ -302,9 +302,12 @@ function onAccept(event) { // Insert the anchor into the document, // but don't let the transaction change the selection - gActiveEditor.setShouldTxnSetSelection(false); - gActiveEditor.insertNode(anchorNode, gHNodeArray[href], 0); - gActiveEditor.setShouldTxnSetSelection(true); + gActiveEditor.insertNode( + anchorNode, + gHNodeArray[href], + 0, + true /* preserve selection */ + ); } } gActiveEditor.endTransaction(); diff --git a/suite/editor/components/dialogs/content/EdDialogCommon.js b/suite/editor/components/dialogs/content/EdDialogCommon.js index c6b7c63778..bbc4b505e5 100644 --- a/suite/editor/components/dialogs/content/EdDialogCommon.js +++ b/suite/editor/components/dialogs/content/EdDialogCommon.js @@ -520,8 +520,9 @@ function PrependHeadElement(element) { var editor = GetCurrentEditor(); try { // Use editor's undoable transaction - // XXX Here tried to prevent updating Selection with unknown 4th argument, - // but nsIEditor.setShouldTxnSetSelection is not used for that. + // XXX Here tried to prevent updating Selection with unknown 4th argument + // before bug 1764895, but nsIEditor.setShouldTxnSetSelection was not + // used for that. editor.insertNode(element, head, 0); } catch (e) {} } @@ -538,8 +539,9 @@ function AppendHeadElement(element) { var editor = GetCurrentEditor(); try { // Use editor's undoable transaction - // XXX Here tried to prevent updating Selection with unknown 4th argument, - // but nsIEditor.setShouldTxnSetSelection is not used for that. + // XXX Here tried to prevent updating Selection with unknown 4th argument + // before bug 1764895, but nsIEditor.setShouldTxnSetSelection was not + // used for that. editor.insertNode(element, head, position); } catch (e) {} } @@ -768,26 +770,26 @@ function InsertElementAroundSelection(element) { } // Now insert the node - // XXX Here tried to prevent updating Selection with unknown 4th argument, - // but nsIEditor.setShouldTxnSetSelection is not used for that. + // XXX Here tried to prevent updating Selection with unknown 4th argument + // before bug 1764895, but nsIEditor.setShouldTxnSetSelection was not + // used for that. editor.insertNode(element, range.commonAncestorContainer, offset); offset = element.childNodes.length; - if (!editor.nodeIsBlock(element)) { - editor.setShouldTxnSetSelection(false); - } // Move all the old child nodes to the element + const preserveSelection = !editor.nodeIsBlock(element); var empty = true; while (start != end) { var next = start.nextSibling; - editor.deleteNode(start); - editor.insertNode(start, element, element.childNodes.length); + editor.deleteNode(start, preserveSelection); + editor.insertNode(start, element, element.childNodes.length, preserveSelection); empty = false; start = next; } - if (!editor.nodeIsBlock(element)) { - editor.setShouldTxnSetSelection(true); - } else { + // FYI: nsIHTMLEditor.nodeIsBlock may return different value if it's moved + // or removed from the old position or the style has been changed. + // Therefore, the result may be different from `!preserveSelection`. + if (editor.nodeIsBlock(element)) { // Also move a trailing
if (start && start.localName == "br") { editor.deleteNode(start); diff --git a/suite/editor/components/dialogs/content/EdFieldSetProps.js b/suite/editor/components/dialogs/content/EdFieldSetProps.js index 1799a2b28f..da3562058f 100644 --- a/suite/editor/components/dialogs/content/EdFieldSetProps.js +++ b/suite/editor/components/dialogs/content/EdFieldSetProps.js @@ -167,26 +167,31 @@ function onAccept() { } InsertElementAroundSelection(fieldsetElement); } else if (gDialog.editText.checked) { - editor.setShouldTxnSetSelection(false); - if (gDialog.legendText.value) { if (newLegend) { - editor.insertNode(legendElement, fieldsetElement, 0); + editor.insertNode( + legendElement, + fieldsetElement, + 0, + true /* preserve selection */ + ); } else { while (legendElement.firstChild) { - editor.deleteNode(legendElement.lastChild); + editor.deleteNode( + legendElement.lastChild, + true /* preserve selection */ + ); } } editor.insertNode( editor.document.createTextNode(gDialog.legendText.value), legendElement, - 0 + 0, + true /* preserve selection */ ); } else if (!newLegend) { - editor.deleteNode(legendElement); + editor.deleteNode(legendElement, true /* preserve selection */); } - - editor.setShouldTxnSetSelection(true); } } finally { editor.endTransaction(); diff --git a/suite/editor/components/dialogs/content/EdImageProps.js b/suite/editor/components/dialogs/content/EdImageProps.js index 5b73488dcb..806580bfed 100644 --- a/suite/editor/components/dialogs/content/EdImageProps.js +++ b/suite/editor/components/dialogs/content/EdImageProps.js @@ -258,9 +258,7 @@ function onAccept(event) { if (gImageMap && gInsertNewIMap) { // Insert the ImageMap element at beginning of document var body = editor.rootElement; - editor.setShouldTxnSetSelection(false); - editor.insertNode(gImageMap, body, 0); - editor.setShouldTxnSetSelection(true); + editor.insertNode(gImageMap, body, 0, true /* preserve selection */); } } catch (e) { dump(e); diff --git a/suite/editor/components/dialogs/content/EdInputImage.js b/suite/editor/components/dialogs/content/EdInputImage.js index 556acc7b13..e8624c1139 100644 --- a/suite/editor/components/dialogs/content/EdInputImage.js +++ b/suite/editor/components/dialogs/content/EdInputImage.js @@ -173,9 +173,7 @@ function onAccept(event) { if (gImageMap && gInsertNewIMap) { // Insert the ImageMap element at beginning of document var body = editor.rootElement; - editor.setShouldTxnSetSelection(false); - editor.insertNode(gImageMap, body, 0); - editor.setShouldTxnSetSelection(true); + editor.insertNode(gImageMap, body, 0, true /* preserve selection */); } } catch (e) {} diff --git a/suite/editor/components/dialogs/content/EdLabelProps.js b/suite/editor/components/dialogs/content/EdLabelProps.js index ec96878ea6..3de1147358 100644 --- a/suite/editor/components/dialogs/content/EdLabelProps.js +++ b/suite/editor/components/dialogs/content/EdLabelProps.js @@ -93,20 +93,20 @@ function onAccept() { try { if (gDialog.editText.checked) { - editor.setShouldTxnSetSelection(false); - while (labelElement.firstChild) { - editor.deleteNode(labelElement.firstChild); + editor.deleteNode( + labelElement.firstChild, + true /* preserve selection */ + ); } if (gDialog.labelText.value) { editor.insertNode( editor.document.createTextNode(gDialog.labelText.value), labelElement, - 0 + 0, + true /* preserve selection */ ); } - - editor.setShouldTxnSetSelection(true); } editor.cloneAttributes(labelElement, globalElement); diff --git a/suite/editor/components/dialogs/content/EdLinkProps.js b/suite/editor/components/dialogs/content/EdLinkProps.js index 6504496a51..b4bf3e8295 100644 --- a/suite/editor/components/dialogs/content/EdLinkProps.js +++ b/suite/editor/components/dialogs/content/EdLinkProps.js @@ -314,9 +314,12 @@ function onAccept(event) { // Insert the anchor into the document, // but don't let the transaction change the selection - gActiveEditor.setShouldTxnSetSelection(false); - gActiveEditor.insertNode(anchorNode, gHNodeArray[href], 0); - gActiveEditor.setShouldTxnSetSelection(true); + gActiveEditor.insertNode( + anchorNode, + gHNodeArray[href], + 0, + true /* preserve selection */ + ); } } gActiveEditor.endTransaction(); diff --git a/suite/editor/components/dialogs/content/EdSelectProps.js b/suite/editor/components/dialogs/content/EdSelectProps.js index c03fd73a67..1366fc1d9a 100644 --- a/suite/editor/components/dialogs/content/EdSelectProps.js +++ b/suite/editor/components/dialogs/content/EdSelectProps.js @@ -617,10 +617,11 @@ function onAccept() { editor.insertElementAtSelection(selectElement, true); } - editor.setShouldTxnSetSelection(false); - while (selectElement.lastChild) { - editor.deleteNode(selectElement.lastChild); + editor.deleteNode( + selectElement.lastChild, + true /* preserver selection */ + ); } var offset = 0; @@ -628,11 +629,14 @@ function onAccept() { if (itemArray[i].level > 1) { selectElement.lastChild.appendChild(itemArray[i].element); } else { - editor.insertNode(itemArray[i].element, selectElement, offset++); + editor.insertNode( + itemArray[i].element, + selectElement, + offset++, + true /* preserve selection */ + ); } } - - editor.setShouldTxnSetSelection(true); } finally { editor.endTransaction(); } diff --git a/suite/editor/components/dialogs/content/EdTextAreaProps.js b/suite/editor/components/dialogs/content/EdTextAreaProps.js index da33ab60c9..94b744da59 100644 --- a/suite/editor/components/dialogs/content/EdTextAreaProps.js +++ b/suite/editor/components/dialogs/content/EdTextAreaProps.js @@ -151,17 +151,21 @@ function onAccept() { // undoably set value var initialText = gDialog.textareaValue.value; if (initialText != textareaElement.value) { - editor.setShouldTxnSetSelection(false); - while (textareaElement.hasChildNodes()) { - editor.deleteNode(textareaElement.lastChild); + editor.deleteNode( + textareaElement.lastChild, + true /* preserve selection */ + ); } if (initialText) { var textNode = editor.document.createTextNode(initialText); - editor.insertNode(textNode, textareaElement, 0); + editor.insertNode( + textNode, + textareaElement, + 0, + true /* preserve selection */ + ); } - - editor.setShouldTxnSetSelection(true); } } finally { editor.endTransaction();