зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1487301 - Part 2. Set ancestor limitter if no set yet. r=masayuki
The ancestor limiter is set by focus event handler of editor. But window that is run script has no focus, this event isn't fired by addRange etc. Some execCommand's commands such as 'forwardDelete' uses WillDeleteSelection then selection for deletion is set by selection controller (in TextEditor::ExtendSelectionForDelete). So, due to no ancestor limiter, caret (and any for delete commands such as CharacterExtendForDelete) can move to out of editor's root. So we should set ancestor limiter if nothing. If focus event is received by user interaction etc, limiter will be set again. Differential Revision: https://phabricator.services.mozilla.com/D6374 --HG-- extra : rebase_source : 240c3bc09b37d46d1ce3245bcca55cafc59454c5
This commit is contained in:
Родитель
eed71e1db2
Коммит
e851a155cb
|
@ -162,6 +162,41 @@ protected:
|
|||
HTMLEditor* mHTMLEditor;
|
||||
};
|
||||
|
||||
|
||||
class MOZ_RAII AutoSetTemporaryAncestorLimiter final
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
public:
|
||||
explicit AutoSetTemporaryAncestorLimiter(HTMLEditor& aHTMLEditor,
|
||||
Selection& aSelection,
|
||||
nsINode& aStartPointNode
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
if (aSelection.GetAncestorLimiter()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Element* root = aHTMLEditor.FindSelectionRoot(&aStartPointNode);
|
||||
if (root) {
|
||||
aHTMLEditor.InitializeSelectionAncestorLimit(aSelection, *root);
|
||||
mSelection = &aSelection;
|
||||
}
|
||||
}
|
||||
|
||||
~AutoSetTemporaryAncestorLimiter()
|
||||
{
|
||||
if (mSelection) {
|
||||
mSelection->SetAncestorLimiter(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<Selection> mSelection;
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* mozilla::HTMLEditRules
|
||||
********************************************************/
|
||||
|
@ -2405,6 +2440,13 @@ HTMLEditRules::WillDeleteSelection(nsIEditor::EDirection aAction,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// ExtendSelectionForDelete will use selection controller to set
|
||||
// selection for delete. But if focus event doesn't receive yet,
|
||||
// ancestor isn't set. So we must set root eleement of editor to
|
||||
// ancestor.
|
||||
AutoSetTemporaryAncestorLimiter autoSetter(HTMLEditorRef(), SelectionRef(),
|
||||
*startPoint.GetContainer());
|
||||
|
||||
rv = HTMLEditorRef().ExtendSelectionForDelete(&SelectionRef(), &aAction);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
|
|
|
@ -42,6 +42,7 @@ class nsRange;
|
|||
|
||||
namespace mozilla {
|
||||
class AutoSelectionSetterAfterTableEdit;
|
||||
class AutoSetTemporaryAncestorLimiter;
|
||||
class DocumentResizeEventListener;
|
||||
class EmptyEditableFunctor;
|
||||
class ResizerSelectionListener;
|
||||
|
@ -2397,6 +2398,7 @@ protected:
|
|||
ParagraphSeparator mDefaultParagraphSeparator;
|
||||
|
||||
friend class AutoSelectionSetterAfterTableEdit;
|
||||
friend class AutoSetTemporaryAncestorLimiter;
|
||||
friend class CSSEditUtils;
|
||||
friend class DocumentResizeEventListener;
|
||||
friend class EditorBase;
|
||||
|
|
Загрузка…
Ссылка в новой задаче