/** * Enter a block where the selection will be preserved against the adverse effects of dom * mutation. * * <p>Must be balanced with a call to either {@link #restoreSelection()} or {@link * #restoreSelection(DocOp)} * * <p>Code that mutates the HTML dom must be guarded by calls to save and restore. */ public void saveSelection() { if (editingConcerns != null && savedSelectionDepth == 0) { needToRestoreSelection = false; SelectionHelper helper = editingConcerns.getSelectionHelper(); // Sometimes the document is not in an editing context, in which // case there is no selection helper. if (helper != null) { FocusedPointRange<Node> htmlSelection = NativeSelectionUtil.get(); if (htmlSelection != null) { savedSelectionAnchor = htmlSelection.getAnchor(); if (savedSelectionAnchor.isInTextNode()) { savedSelectionAnchorTextNodelet = savedSelectionAnchor.getContainer().cast(); savedSelectionAnchorOffset = savedSelectionAnchor.getTextOffset(); } savedSelectionFocus = htmlSelection.getFocus(); if (savedSelectionFocus.isInTextNode()) { savedSelectionFocusTextNodelet = savedSelectionFocus.getContainer().cast(); savedSelectionFocusOffset = savedSelectionFocus.getTextOffset(); } savedSelection = helper.getSelectionRange(); } } } savedSelectionDepth++; }
/** * Same as {@link #restoreSelection()}, but if the selection is actually required to be explicitly * set, transform its saved location with the given modifier. */ public void restoreSelection(DocOp modifier) { savedSelectionDepth--; if (editingConcerns != null && savedSelectionDepth == 0) { try { if (savedSelection != null) { // selectionChangedInappropriately() only deals with selection boundaries. If we had // a ranged selection, and we're in a browser where changing it internally matters, // then just always restore the selection. This is safe to do w.r.t. IMEs because it's // unlikely to have a ranged selection during an uncommitted IME state. needToRestoreSelection |= QuirksConstants.RANGED_SELECTION_AFFECTED_BY_INTERNAL_CHANGED && !savedSelection.isCollapsed(); if (needToRestoreSelection || selectionChangedInappropriately()) { if (modifier != null) { savedSelection = RangeHelper.applyModifier(savedSelection, modifier); } EditorStaticDeps.logger.trace().log("Restoring selection"); if (document.size() >= 4) { editingConcerns.getSelectionHelper().setSelectionRange(savedSelection); } } else { EditorStaticDeps.logger.trace().log("Not restoring selection"); } } } finally { savedSelection = null; savedSelectionAnchor = null; savedSelectionAnchorTextNodelet = null; savedSelectionAnchorOffset = 0; savedSelectionFocus = null; savedSelectionFocusTextNodelet = null; savedSelectionFocusOffset = 0; } } }