mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
b0345ff809
35 changed files with 789 additions and 133 deletions
|
|
@ -1771,6 +1771,9 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
|||
// (Do this in a script runner, since our caller might have a script
|
||||
// blocker on the stack.)
|
||||
nsContentUtils::AddScriptRunner(new XBLConstructorRunner(mDocument));
|
||||
|
||||
// XBLConstructorRunner might destroy us.
|
||||
NS_ENSURE_STATE(!mHaveShutDown);
|
||||
}
|
||||
|
||||
NS_ASSERTION(rootFrame, "How did that happen?");
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@
|
|||
struct CachedOffsetForFrame;
|
||||
class nsAutoScrollTimer;
|
||||
class nsIContentIterator;
|
||||
class nsIDocument;
|
||||
class nsIEditor;
|
||||
class nsIFrame;
|
||||
class nsIHTMLEditor;
|
||||
class nsFrameSelection;
|
||||
class nsPIDOMWindowOuter;
|
||||
struct SelectionDetails;
|
||||
class nsCopySupport;
|
||||
class nsHTMLCopyEncoder;
|
||||
|
|
@ -170,13 +174,19 @@ public:
|
|||
uint32_t FocusOffset();
|
||||
|
||||
bool IsCollapsed() const;
|
||||
void Collapse(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
|
||||
void CollapseToStart(mozilla::ErrorResult& aRv);
|
||||
void CollapseToEnd(mozilla::ErrorResult& aRv);
|
||||
// *JS() methods are mapped to Selection.*().
|
||||
// They may move focus only when the range represents normal selection.
|
||||
// These methods shouldn't be used by non-JS callers.
|
||||
void CollapseJS(nsINode& aNode, uint32_t aOffset,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void CollapseToStartJS(mozilla::ErrorResult& aRv);
|
||||
void CollapseToEndJS(mozilla::ErrorResult& aRv);
|
||||
|
||||
void Extend(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
|
||||
void ExtendJS(nsINode& aNode, uint32_t aOffset,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void SelectAllChildrenJS(nsINode& aNode, mozilla::ErrorResult& aRv);
|
||||
|
||||
void SelectAllChildren(nsINode& aNode, mozilla::ErrorResult& aRv);
|
||||
void DeleteFromDocument(mozilla::ErrorResult& aRv);
|
||||
|
||||
uint32_t RangeCount() const
|
||||
|
|
@ -187,7 +197,7 @@ public:
|
|||
void GetType(nsAString& aOutType) const;
|
||||
|
||||
nsRange* GetRangeAt(uint32_t aIndex, mozilla::ErrorResult& aRv);
|
||||
void AddRange(nsRange& aRange, mozilla::ErrorResult& aRv);
|
||||
void AddRangeJS(nsRange& aRange, mozilla::ErrorResult& aRv);
|
||||
void RemoveRange(nsRange& aRange, mozilla::ErrorResult& aRv);
|
||||
void RemoveAllRanges(mozilla::ErrorResult& aRv);
|
||||
|
||||
|
|
@ -207,9 +217,9 @@ public:
|
|||
void Modify(const nsAString& aAlter, const nsAString& aDirection,
|
||||
const nsAString& aGranularity, mozilla::ErrorResult& aRv);
|
||||
|
||||
void SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode& aFocusNode, uint32_t aFocusOffset,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void SetBaseAndExtentJS(nsINode& aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode& aFocusNode, uint32_t aFocusOffset,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
bool GetInterlinePosition(mozilla::ErrorResult& aRv);
|
||||
void SetInterlinePosition(bool aValue, mozilla::ErrorResult& aRv);
|
||||
|
|
@ -243,6 +253,17 @@ public:
|
|||
int16_t aVPercent, int16_t aHPercent,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// Non-JS callers should use the following methods.
|
||||
void Collapse(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
|
||||
void CollapseToStart(mozilla::ErrorResult& aRv);
|
||||
void CollapseToEnd(mozilla::ErrorResult& aRv);
|
||||
void Extend(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
|
||||
void AddRange(nsRange& aRange, mozilla::ErrorResult& aRv);
|
||||
void SelectAllChildren(nsINode& aNode, mozilla::ErrorResult& aRv);
|
||||
void SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode& aFocusNode, uint32_t aFocusOffset,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void AddSelectionChangeBlocker();
|
||||
void RemoveSelectionChangeBlocker();
|
||||
bool IsBlockingSelectionChangeEvents() const;
|
||||
|
|
@ -265,7 +286,8 @@ public:
|
|||
mSelectionType = aSelectionType;
|
||||
}
|
||||
|
||||
nsresult NotifySelectionListeners();
|
||||
nsresult NotifySelectionListeners(bool aCalledByJS);
|
||||
nsresult NotifySelectionListeners();
|
||||
|
||||
friend struct AutoUserInitiated;
|
||||
struct MOZ_RAII AutoUserInitiated
|
||||
|
|
@ -341,6 +363,43 @@ private:
|
|||
*/
|
||||
nsresult AddItemInternal(nsRange* aRange, int32_t* aOutIndex);
|
||||
|
||||
nsIDocument* GetDocument() const;
|
||||
nsPIDOMWindowOuter* GetWindow() const;
|
||||
nsIEditor* GetEditor() const;
|
||||
|
||||
/**
|
||||
* GetCommonEditingHostForAllRanges() returns common editing host of all
|
||||
* ranges if there is. If at least one of the ranges is in non-editable
|
||||
* element, returns nullptr. See following examples for the detail:
|
||||
*
|
||||
* <div id="a" contenteditable>
|
||||
* an[cestor
|
||||
* <div id="b" contenteditable="false">
|
||||
* non-editable
|
||||
* <div id="c" contenteditable>
|
||||
* desc]endant
|
||||
* in this case, this returns div#a because div#c is also in div#a.
|
||||
*
|
||||
* <div id="a" contenteditable>
|
||||
* an[ce]stor
|
||||
* <div id="b" contenteditable="false">
|
||||
* non-editable
|
||||
* <div id="c" contenteditable>
|
||||
* de[sc]endant
|
||||
* in this case, this returns div#a because second range is also in div#a
|
||||
* and common ancestor of the range (i.e., div#c) is editable.
|
||||
*
|
||||
* <div id="a" contenteditable>
|
||||
* an[ce]stor
|
||||
* <div id="b" contenteditable="false">
|
||||
* [non]-editable
|
||||
* <div id="c" contenteditable>
|
||||
* de[sc]endant
|
||||
* in this case, this returns nullptr because the second range is in
|
||||
* non-editable area.
|
||||
*/
|
||||
Element* GetCommonEditingHostForAllRanges();
|
||||
|
||||
// These are the ranges inside this selection. They are kept sorted in order
|
||||
// of DOM start position.
|
||||
//
|
||||
|
|
@ -371,6 +430,12 @@ private:
|
|||
*/
|
||||
bool mUserInitiated;
|
||||
|
||||
/**
|
||||
* When the selection change is caused by a call of Selection API,
|
||||
* mCalledByJS is true. Otherwise, false.
|
||||
*/
|
||||
bool mCalledByJS;
|
||||
|
||||
// Non-zero if we don't want any changes we make to the selection to be
|
||||
// visible to content. If non-zero, content won't be notified about changes.
|
||||
uint32_t mSelectionChangeBlockerCount;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
|
@ -84,6 +85,7 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
|||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
|
@ -1199,7 +1201,7 @@ Selection::ToString(nsAString& aReturn)
|
|||
aReturn.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
shell->FlushPendingNotifications(Flush_Style);
|
||||
shell->FlushPendingNotifications(Flush_Frames);
|
||||
|
||||
return ToStringWithFormat("text/plain",
|
||||
nsIDocumentEncoder::SkipInvisibleContent,
|
||||
|
|
@ -1876,6 +1878,7 @@ printf(" * TakeFocus - moving into new cell\n");
|
|||
// Don't notify selection listeners if batching is on:
|
||||
if (GetBatching())
|
||||
return NS_OK;
|
||||
// Be aware, the Selection instance may be destroyed after this call.
|
||||
return NotifySelectionListeners(SelectionType::eNormal);
|
||||
}
|
||||
|
||||
|
|
@ -1916,6 +1919,7 @@ nsFrameSelection::SetDragState(bool aState)
|
|||
mDragSelectingCells = false;
|
||||
// Notify that reason is mouse up.
|
||||
PostReason(nsISelectionListener::MOUSEUP_REASON);
|
||||
// Be aware, the Selection instance may be destroyed after this call.
|
||||
NotifySelectionListeners(SelectionType::eNormal);
|
||||
}
|
||||
}
|
||||
|
|
@ -2410,6 +2414,7 @@ nsFrameSelection::EndBatchChanges(int16_t aReason)
|
|||
int16_t postReason = PopReason() | aReason;
|
||||
PostReason(postReason);
|
||||
mChangesDuringBatching = false;
|
||||
// Be aware, the Selection instance may be destroyed after this call.
|
||||
NotifySelectionListeners(SelectionType::eNormal);
|
||||
}
|
||||
}
|
||||
|
|
@ -2421,7 +2426,8 @@ nsFrameSelection::NotifySelectionListeners(SelectionType aSelectionType)
|
|||
int8_t index = GetIndexFromSelectionType(aSelectionType);
|
||||
if (index >=0 && mDomSelections[index])
|
||||
{
|
||||
return mDomSelections[index]->NotifySelectionListeners();
|
||||
RefPtr<Selection> selection = mDomSelections[index];
|
||||
return selection->NotifySelectionListeners();
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
@ -3473,6 +3479,7 @@ Selection::Selection()
|
|||
, mDirection(eDirNext)
|
||||
, mSelectionType(SelectionType::eNormal)
|
||||
, mUserInitiated(false)
|
||||
, mCalledByJS(false)
|
||||
, mSelectionChangeBlockerCount(0)
|
||||
{
|
||||
}
|
||||
|
|
@ -3483,6 +3490,7 @@ Selection::Selection(nsFrameSelection* aList)
|
|||
, mDirection(eDirNext)
|
||||
, mSelectionType(SelectionType::eNormal)
|
||||
, mUserInitiated(false)
|
||||
, mCalledByJS(false)
|
||||
, mSelectionChangeBlockerCount(0)
|
||||
{
|
||||
}
|
||||
|
|
@ -4943,7 +4951,10 @@ Selection::RemoveAllRanges(ErrorResult& aRv)
|
|||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
frameSelection->ClearTableCellSelection();
|
||||
|
||||
// Be aware, this instance may be destroyed after this call.
|
||||
// XXX Why doesn't this call Selection::NotifySelectionListener() directly?
|
||||
result = frameSelection->NotifySelectionListeners(GetType());
|
||||
|
||||
// Also need to notify the frames!
|
||||
// PresShell::CharacterDataChanged should do that on DocumentChanged
|
||||
if (NS_FAILED(result)) {
|
||||
|
|
@ -4966,6 +4977,14 @@ Selection::AddRange(nsIDOMRange* aDOMRange)
|
|||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
Selection::AddRangeJS(nsRange& aRange, ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
AddRange(aRange, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::AddRange(nsRange& aRange, ErrorResult& aRv)
|
||||
{
|
||||
|
|
@ -5020,6 +5039,8 @@ Selection::AddRangeInternal(nsRange& aRange, nsIDocument* aDocument,
|
|||
if (!mFrameSelection)
|
||||
return;//nothing to do
|
||||
|
||||
// Be aware, this instance may be destroyed after this call.
|
||||
// XXX Why doesn't this call Selection::NotifySelectionListener() directly?
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
result = frameSelection->NotifySelectionListeners(GetType());
|
||||
if (NS_FAILED(result)) {
|
||||
|
|
@ -5115,6 +5136,9 @@ Selection::RemoveRange(nsRange& aRange, ErrorResult& aRv)
|
|||
|
||||
if (!mFrameSelection)
|
||||
return;//nothing to do
|
||||
|
||||
// Be aware, this instance may be destroyed after this call.
|
||||
// XXX Why doesn't this call Selection::NotifySelectionListener() directly?
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
rv = frameSelection->NotifySelectionListeners(GetType());
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
@ -5140,6 +5164,14 @@ Selection::CollapseNative(nsINode* aParentNode, int32_t aOffset)
|
|||
return Collapse(aParentNode, aOffset);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::CollapseJS(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
Collapse(aNode, aOffset, aRv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Selection::Collapse(nsINode* aParentNode, int32_t aOffset)
|
||||
{
|
||||
|
|
@ -5222,6 +5254,9 @@ Selection::Collapse(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
|
|||
}
|
||||
setAnchorFocusRange(0);
|
||||
selectFrames(presContext, range, true);
|
||||
|
||||
// Be aware, this instance may be destroyed after this call.
|
||||
// XXX Why doesn't this call Selection::NotifySelectionListener() directly?
|
||||
result = frameSelection->NotifySelectionListeners(GetType());
|
||||
if (NS_FAILED(result)) {
|
||||
aRv.Throw(result);
|
||||
|
|
@ -5240,6 +5275,14 @@ Selection::CollapseToStart()
|
|||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
Selection::CollapseToStartJS(ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
CollapseToStart(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::CollapseToStart(ErrorResult& aRv)
|
||||
{
|
||||
|
|
@ -5281,6 +5324,14 @@ Selection::CollapseToEnd()
|
|||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
Selection::CollapseToEndJS(ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
CollapseToEnd(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::CollapseToEnd(ErrorResult& aRv)
|
||||
{
|
||||
|
|
@ -5495,6 +5546,14 @@ Selection::ExtendNative(nsINode* aParentNode, int32_t aOffset)
|
|||
return Extend(aParentNode, aOffset);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::ExtendJS(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
Extend(aNode, aOffset, aRv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Selection::Extend(nsINode* aParentNode, int32_t aOffset)
|
||||
{
|
||||
|
|
@ -5773,6 +5832,9 @@ Selection::Extend(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
|
|||
printf ("Sel. Extend to %p %s %d\n", content.get(),
|
||||
nsAtomCString(content->NodeInfo()->NameAtom()).get(), aOffset);
|
||||
#endif
|
||||
|
||||
// Be aware, this instance may be destroyed after this call.
|
||||
// XXX Why doesn't this call Selection::NotifySelectionListener() directly?
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
res = frameSelection->NotifySelectionListeners(GetType());
|
||||
if (NS_FAILED(res)) {
|
||||
|
|
@ -5790,6 +5852,14 @@ Selection::SelectAllChildren(nsIDOMNode* aParentNode)
|
|||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
Selection::SelectAllChildrenJS(nsINode& aNode, ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
SelectAllChildren(aNode, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::SelectAllChildren(nsINode& aNode, ErrorResult& aRv)
|
||||
{
|
||||
|
|
@ -5938,6 +6008,30 @@ Selection::GetPresShell() const
|
|||
return mFrameSelection->GetShell();
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
Selection::GetDocument() const
|
||||
{
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
return presShell ? presShell->GetDocument() : nullptr;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
Selection::GetWindow() const
|
||||
{
|
||||
nsIDocument* document = GetDocument();
|
||||
return document ? document->GetWindow() : nullptr;
|
||||
}
|
||||
|
||||
nsIEditor*
|
||||
Selection::GetEditor() const
|
||||
{
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (!presContext) {
|
||||
return nullptr;
|
||||
}
|
||||
return nsContentUtils::GetHTMLEditor(presContext);
|
||||
}
|
||||
|
||||
nsIFrame *
|
||||
Selection::GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect* aRect)
|
||||
{
|
||||
|
|
@ -6239,12 +6333,101 @@ Selection::RemoveSelectionListener(nsISelectionListener* aListenerToRemove,
|
|||
}
|
||||
}
|
||||
|
||||
Element*
|
||||
Selection::GetCommonEditingHostForAllRanges()
|
||||
{
|
||||
Element* editingHost = nullptr;
|
||||
for (RangeData& rangeData : mRanges) {
|
||||
nsRange* range = rangeData.mRange;
|
||||
MOZ_ASSERT(range);
|
||||
nsINode* commonAncestorNode = range->GetCommonAncestor();
|
||||
if (!commonAncestorNode || !commonAncestorNode->IsContent()) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIContent* commonAncestor = commonAncestorNode->AsContent();
|
||||
Element* foundEditingHost = commonAncestor->GetEditingHost();
|
||||
// Even when common ancestor is a non-editable element in a contenteditable
|
||||
// element, we don't need to move focus to the contenteditable element
|
||||
// because Chromium doesn't set focus to it.
|
||||
if (!foundEditingHost) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!editingHost) {
|
||||
editingHost = foundEditingHost;
|
||||
continue;
|
||||
}
|
||||
if (editingHost == foundEditingHost) {
|
||||
continue;
|
||||
}
|
||||
if (nsContentUtils::ContentIsDescendantOf(foundEditingHost, editingHost)) {
|
||||
continue;
|
||||
}
|
||||
if (nsContentUtils::ContentIsDescendantOf(editingHost, foundEditingHost)) {
|
||||
editingHost = foundEditingHost;
|
||||
continue;
|
||||
}
|
||||
// editingHost and foundEditingHost are not a descendant of the other.
|
||||
// So, there is no common editing host.
|
||||
return nullptr;
|
||||
}
|
||||
return editingHost;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Selection::NotifySelectionListeners(bool aCalledByJS)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = aCalledByJS;
|
||||
return NotifySelectionListeners();
|
||||
}
|
||||
|
||||
nsresult
|
||||
Selection::NotifySelectionListeners()
|
||||
{
|
||||
if (!mFrameSelection)
|
||||
return NS_OK;//nothing to do
|
||||
|
||||
// Our internal code should not move focus with using this class while
|
||||
// this moves focus nor from selection listeners.
|
||||
AutoRestore<bool> calledByJSRestorer(mCalledByJS);
|
||||
mCalledByJS = false;
|
||||
|
||||
// When normal selection is changed by Selection API, we need to move focus
|
||||
// if common ancestor of all ranges are in an editing host. Note that we
|
||||
// don't need to move focus *to* the other focusable node, because other
|
||||
// browsers don't do this, either.
|
||||
if (mSelectionType == SelectionType::eNormal &&
|
||||
calledByJSRestorer.SavedValue()) {
|
||||
nsPIDOMWindowOuter* window = GetWindow();
|
||||
nsIDocument* document = GetDocument();
|
||||
// If the document is in design mode or doesn't have contenteditable
|
||||
// element, we don't need to move focus.
|
||||
if (window && document && !document->HasFlag(NODE_IS_EDITABLE) &&
|
||||
GetEditor()) {
|
||||
RefPtr<Element> newEditingHost = GetCommonEditingHostForAllRanges();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
|
||||
nsIContent* focusedContent =
|
||||
fm->GetFocusedDescendant(window, false, getter_AddRefs(focusedWindow));
|
||||
nsCOMPtr<Element> focusedElement = do_QueryInterface(focusedContent);
|
||||
// When all selected ranges are in an editing host, it should take focus.
|
||||
if (newEditingHost && newEditingHost != focusedElement) {
|
||||
MOZ_ASSERT(!newEditingHost->IsInNativeAnonymousSubtree());
|
||||
nsCOMPtr<nsIDOMElement> domElementToFocus =
|
||||
do_QueryInterface(newEditingHost->AsDOMNode());
|
||||
// Note that don't steal focus from focused window if the window
|
||||
// doesn't have focus. Additionally, when an element gets focus,
|
||||
// we usually scroll to the element, but in this case we shouldn't
|
||||
// do that because Blink&Gecko don't do this.
|
||||
fm->SetFocus(domElementToFocus, nsIFocusManager::FLAG_NOSWITCHFRAME |
|
||||
nsIFocusManager::FLAG_NOSCROLL);
|
||||
}
|
||||
// Otherwise, we shouldn't move focus since Blink&Gecko don't move
|
||||
// focus; only the selection range is updated. This is a bit weird but
|
||||
// it is what it is and we should act the same for parity.
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
if (frameSelection->GetBatching()) {
|
||||
frameSelection->SetDirty();
|
||||
|
|
@ -6454,6 +6637,19 @@ Selection::Modify(const nsAString& aAlter, const nsAString& aDirection,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Selection::SetBaseAndExtentJS(nsINode& aAnchorNode,
|
||||
uint32_t aAnchorOffset,
|
||||
nsINode& aFocusNode,
|
||||
uint32_t aFocusOffset,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
|
||||
mCalledByJS = true;
|
||||
SetBaseAndExtent(aAnchorNode, aAnchorOffset,
|
||||
aFocusNode, aFocusOffset, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode& aFocusNode, uint32_t aFocusOffset,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue