зеркало из https://github.com/mozilla/gecko-dev.git
Bug 757771 part 4 - Create new nsContentUtils::GetSelectionInTextControl method; r=ehsan
This commit is contained in:
Родитель
3bea0fda01
Коммит
19175c3318
|
@ -117,6 +117,7 @@ struct nsIntMargin;
|
|||
class nsPIDOMWindow;
|
||||
class nsIDocumentLoaderFactory;
|
||||
class nsIDOMHTMLInputElement;
|
||||
class nsTypedSelection;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -2027,6 +2028,22 @@ public:
|
|||
*/
|
||||
static nsresult IsOnPrefWhitelist(nsPIDOMWindow* aWindow,
|
||||
const char* aPrefURL, bool *aAllowed);
|
||||
|
||||
/**
|
||||
* Takes a selection, and a text control element (<input> or <textarea>), and
|
||||
* returns the offsets in the text content corresponding to the selection.
|
||||
* The selection's anchor and focus must both be in the root node passed or a
|
||||
* descendant.
|
||||
*
|
||||
* @param aSelection Selection to check
|
||||
* @param aRoot Root <input> or <textarea> element
|
||||
* @param aOutStartOffset Output start offset
|
||||
* @param aOutEndOffset Output end offset
|
||||
*/
|
||||
static void GetSelectionInTextControl(nsTypedSelection* aSelection,
|
||||
Element* aRoot,
|
||||
PRInt32& aOutStartOffset,
|
||||
PRInt32& aOutEndOffset);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
|
|
@ -143,6 +143,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsParserConstants.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsTypedSelection.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
@ -6863,3 +6864,57 @@ nsContentUtils::IsOnPrefWhitelist(nsPIDOMWindow* aWindow,
|
|||
*aAllowed = allowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsContentUtils::GetSelectionInTextControl(nsTypedSelection* aSelection,
|
||||
Element* aRoot,
|
||||
PRInt32& aOutStartOffset,
|
||||
PRInt32& aOutEndOffset)
|
||||
{
|
||||
MOZ_ASSERT(aSelection && aRoot);
|
||||
|
||||
if (!aSelection->GetRangeCount()) {
|
||||
// Nothing selected
|
||||
aOutStartOffset = aOutEndOffset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> anchorNode = aSelection->GetAnchorNode();
|
||||
PRInt32 anchorOffset = aSelection->GetAnchorOffset();
|
||||
nsCOMPtr<nsINode> focusNode = aSelection->GetFocusNode();
|
||||
PRInt32 focusOffset = aSelection->GetFocusOffset();
|
||||
|
||||
// We have at most two children, consisting of an optional text node followed
|
||||
// by an optional <br>.
|
||||
NS_ASSERTION(aRoot->GetChildCount() <= 2, "Unexpected children");
|
||||
nsCOMPtr<nsIContent> firstChild = aRoot->GetFirstChild();
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContent> lastChild = aRoot->GetLastChild();
|
||||
NS_ASSERTION(anchorNode == aRoot || anchorNode == firstChild ||
|
||||
anchorNode == lastChild, "Unexpected anchorNode");
|
||||
NS_ASSERTION(focusNode == aRoot || focusNode == firstChild ||
|
||||
focusNode == lastChild, "Unexpected focusNode");
|
||||
#endif
|
||||
if (!firstChild || !firstChild->IsNodeOfType(nsINode::eTEXT)) {
|
||||
// No text node, so everything is 0
|
||||
anchorOffset = focusOffset = 0;
|
||||
} else {
|
||||
// First child is text. If the anchor/focus is already in the text node,
|
||||
// or the start of the root node, no change needed. If it's in the root
|
||||
// node but not the start, or in the trailing <br>, we need to set the
|
||||
// offset to the end.
|
||||
if ((anchorNode == aRoot && anchorOffset != 0) ||
|
||||
(anchorNode != aRoot && anchorNode != firstChild)) {
|
||||
anchorOffset = firstChild->Length();
|
||||
}
|
||||
if ((focusNode == aRoot && focusOffset != 0) ||
|
||||
(focusNode != aRoot && focusNode != firstChild)) {
|
||||
focusOffset = firstChild->Length();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure aOutStartOffset <= aOutEndOffset.
|
||||
aOutStartOffset = NS_MIN(anchorOffset, focusOffset);
|
||||
aOutEndOffset = NS_MAX(anchorOffset, focusOffset);
|
||||
}
|
||||
|
|
|
@ -326,13 +326,6 @@ public:
|
|||
bool aNoEmptyNodes);
|
||||
virtual already_AddRefed<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode* aNode);
|
||||
|
||||
/** returns the absolute position of the end points of aSelection
|
||||
* in the document as a text stream.
|
||||
*/
|
||||
nsresult GetTextSelectionOffsets(nsISelection *aSelection,
|
||||
PRInt32 &aStartOffset,
|
||||
PRInt32 &aEndOffset);
|
||||
|
||||
// Use this to assure that selection is set after attribute nodes when
|
||||
// trying to collapse selection at begining of a block node
|
||||
// e.g., when setting at beginning of a table cell
|
||||
|
|
|
@ -533,94 +533,6 @@ nsPlaintextEditor::InsertBR(nsCOMPtr<nsIDOMNode>* outBRNode)
|
|||
return selection->Collapse(selNode, selOffset+1);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlaintextEditor::GetTextSelectionOffsets(nsISelection *aSelection,
|
||||
PRUint32 &aOutStartOffset,
|
||||
PRUint32 &aOutEndOffset)
|
||||
{
|
||||
NS_ASSERTION(aSelection, "null selection");
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
PRInt32 startNodeOffset, endNodeOffset;
|
||||
aSelection->GetAnchorNode(getter_AddRefs(startNode));
|
||||
aSelection->GetAnchorOffset(&startNodeOffset);
|
||||
aSelection->GetFocusNode(getter_AddRefs(endNode));
|
||||
aSelection->GetFocusOffset(&endNodeOffset);
|
||||
|
||||
dom::Element *rootElement = GetRoot();
|
||||
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
|
||||
NS_ENSURE_TRUE(rootNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
PRInt32 startOffset = -1;
|
||||
PRInt32 endOffset = -1;
|
||||
|
||||
nsCOMPtr<nsIContentIterator> iter =
|
||||
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 nodeCount = 0; // only needed for the assertions below
|
||||
#endif
|
||||
PRUint32 totalLength = 0;
|
||||
iter->Init(rootElement);
|
||||
for (; !iter->IsDone() && (startOffset == -1 || endOffset == -1); iter->Next()) {
|
||||
nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(iter->GetCurrentNode());
|
||||
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(currentNode);
|
||||
if (textNode) {
|
||||
// Note that sometimes we have an empty #text-node as start/endNode,
|
||||
// which we regard as not editable because the frame width == 0,
|
||||
// see nsEditor::IsEditable().
|
||||
bool editable = IsEditable(currentNode);
|
||||
if (currentNode == startNode) {
|
||||
startOffset = totalLength + (editable ? startNodeOffset : 0);
|
||||
}
|
||||
if (currentNode == endNode) {
|
||||
endOffset = totalLength + (editable ? endNodeOffset : 0);
|
||||
}
|
||||
if (editable) {
|
||||
PRUint32 length;
|
||||
textNode->GetLength(&length);
|
||||
totalLength += length;
|
||||
}
|
||||
}
|
||||
#ifdef NS_DEBUG
|
||||
// The post content iterator might return the parent node (which is the
|
||||
// editor's root node) as the last item. Don't count the root node itself
|
||||
// as one of its children!
|
||||
if (!SameCOMIdentity(currentNode, rootNode)) {
|
||||
++nodeCount;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (endOffset == -1) {
|
||||
NS_ASSERTION(endNode == rootNode, "failed to find the end node");
|
||||
NS_ASSERTION(IsPasswordEditor() ||
|
||||
(endNodeOffset == nodeCount-1 || endNodeOffset == 0),
|
||||
"invalid end node offset");
|
||||
endOffset = endNodeOffset == 0 ? 0 : totalLength;
|
||||
}
|
||||
if (startOffset == -1) {
|
||||
NS_ASSERTION(startNode == rootNode, "failed to find the start node");
|
||||
NS_ASSERTION(startNodeOffset == nodeCount-1 || startNodeOffset == 0,
|
||||
"invalid start node offset");
|
||||
startOffset = startNodeOffset == 0 ? 0 : totalLength;
|
||||
}
|
||||
|
||||
// Make sure aOutStartOffset <= aOutEndOffset.
|
||||
if (startOffset <= endOffset) {
|
||||
aOutStartOffset = startOffset;
|
||||
aOutEndOffset = endOffset;
|
||||
}
|
||||
else {
|
||||
aOutStartOffset = endOffset;
|
||||
aOutEndOffset = startOffset;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlaintextEditor::ExtendSelectionForDelete(nsISelection *aSelection,
|
||||
nsIEditor::EDirection *aAction)
|
||||
|
|
|
@ -121,14 +121,6 @@ public:
|
|||
/* ------------ Utility Routines, not part of public API -------------- */
|
||||
NS_IMETHOD TypedText(const nsAString& aString, ETypingAction aAction);
|
||||
|
||||
/** Returns the absolute position of the end points of aSelection
|
||||
* in the document as a text stream.
|
||||
* Invariant: aStartOffset <= aEndOffset.
|
||||
*/
|
||||
nsresult GetTextSelectionOffsets(nsISelection *aSelection,
|
||||
PRUint32 &aStartOffset,
|
||||
PRUint32 &aEndOffset);
|
||||
|
||||
nsresult InsertTextAt(const nsAString &aStringToInsert,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "DeleteTextTxn.h"
|
||||
#include "nsNodeIterator.h"
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
// for IBMBIDI
|
||||
#include "nsFrameSelection.h"
|
||||
|
@ -578,15 +579,13 @@ nsTextEditRules::WillInsertText(nsEditor::OperationID aAction,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 start = 0;
|
||||
PRUint32 end = 0;
|
||||
PRInt32 start = 0;
|
||||
PRInt32 end = 0;
|
||||
|
||||
// handle password field docs
|
||||
if (IsPasswordEditor())
|
||||
{
|
||||
res = mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
||||
NS_ASSERTION((NS_SUCCEEDED(res)), "getTextSelectionOffsets failed!");
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (IsPasswordEditor()) {
|
||||
nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(),
|
||||
start, end);
|
||||
}
|
||||
|
||||
// if the selection isn't collapsed, delete it.
|
||||
|
@ -780,9 +779,9 @@ nsTextEditRules::WillDeleteSelection(nsTypedSelection* aSelection,
|
|||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// manage the password buffer
|
||||
PRUint32 start, end;
|
||||
mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
PRInt32 start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(),
|
||||
start, end);
|
||||
|
||||
if (LookAndFeel::GetEchoPassword()) {
|
||||
HideLastPWInput();
|
||||
|
@ -1171,9 +1170,9 @@ nsTextEditRules::TruncateInsertionIfNeeded(nsTypedSelection* aSelection,
|
|||
res = mEditor->GetTextLength(&docLength);
|
||||
if (NS_FAILED(res)) { return res; }
|
||||
|
||||
PRUint32 start, end;
|
||||
res = mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
||||
if (NS_FAILED(res)) { return res; }
|
||||
PRInt32 start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(),
|
||||
start, end);
|
||||
|
||||
PRInt32 oldCompStrLength = mEditor->GetIMEBufferLength();
|
||||
|
||||
|
@ -1208,7 +1207,7 @@ nsTextEditRules::ResetIMETextPWBuf()
|
|||
}
|
||||
|
||||
void
|
||||
nsTextEditRules::RemoveIMETextFromPWBuf(PRUint32 &aStart, nsAString *aIMEString)
|
||||
nsTextEditRules::RemoveIMETextFromPWBuf(PRInt32 &aStart, nsAString *aIMEString)
|
||||
{
|
||||
MOZ_ASSERT(aIMEString);
|
||||
|
||||
|
@ -1241,12 +1240,11 @@ nsresult nsTextEditRules::HideLastPWInput() {
|
|||
nsAutoString hiddenText;
|
||||
FillBufWithPWChars(&hiddenText, mLastLength);
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
PRUint32 start, end;
|
||||
nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = mEditor->GetTextSelectionOffsets(selection, start, end);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsRefPtr<nsTypedSelection> selection = mEditor->GetTypedSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
PRInt32 start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(selection, mEditor->GetRoot(),
|
||||
start, end);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> selNode = GetTextNode(selection, mEditor);
|
||||
NS_ENSURE_TRUE(selNode, NS_OK);
|
||||
|
|
|
@ -163,7 +163,7 @@ protected:
|
|||
bool *aTruncated);
|
||||
|
||||
/** Remove IME composition text from password buffer */
|
||||
void RemoveIMETextFromPWBuf(PRUint32 &aStart, nsAString *aIMEString);
|
||||
void RemoveIMETextFromPWBuf(PRInt32 &aStart, nsAString *aIMEString);
|
||||
|
||||
nsresult CreateMozBR(nsIDOMNode* inParent, PRInt32 inOffset,
|
||||
nsIDOMNode** outBRNode = nsnull);
|
||||
|
|
|
@ -34,6 +34,7 @@ _TEST_FILES = \
|
|||
test_bug681229.html \
|
||||
test_bug692520.html \
|
||||
test_bug740784.html \
|
||||
test_bug757771.html \
|
||||
test_dom_input_event_on_texteditor.html \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=757771
|
||||
-->
|
||||
<title>Test for Bug 757771</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=757771">Mozilla Bug 757771</a>
|
||||
<input value=foo maxlength=4>
|
||||
<input type=password value=password>
|
||||
<script>
|
||||
/** Test for Bug 757771 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var textInput = document.querySelector("input");
|
||||
textInput.focus();
|
||||
textInput.select();
|
||||
sendString("abcde");
|
||||
|
||||
var passwordInput = document.querySelector("input + input");
|
||||
passwordInput.focus();
|
||||
passwordInput.select();
|
||||
sendString("hunter2");
|
||||
|
||||
ok(true, "No real tests, just crashes/asserts");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
|
@ -817,6 +817,15 @@ nsTextControlFrame::ScrollSelectionIntoView()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mozilla::dom::Element*
|
||||
nsTextControlFrame::GetRootNodeAndInitializeEditor()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> root;
|
||||
GetRootNodeAndInitializeEditor(getter_AddRefs(root));
|
||||
nsCOMPtr<mozilla::dom::Element> rootElem = do_QueryInterface(root);
|
||||
return rootElem;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement)
|
||||
{
|
||||
|
@ -964,58 +973,6 @@ nsTextControlFrame::SetSelectionEnd(PRInt32 aSelectionEnd)
|
|||
return SetSelectionEndPoints(selStart, selEnd);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::DOMPointToOffset(nsIDOMNode* aNode,
|
||||
PRInt32 aNodeOffset,
|
||||
PRInt32* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNode && aResult);
|
||||
|
||||
*aResult = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rootElement;
|
||||
nsresult rv = GetRootNodeAndInitializeEditor(getter_AddRefs(rootElement));
|
||||
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
|
||||
|
||||
NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
|
||||
rv = rootNode->GetChildNodes(getter_AddRefs(nodeList));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 length = 0;
|
||||
rv = nodeList->GetLength(&length);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!length || aNodeOffset < 0)
|
||||
return NS_OK;
|
||||
|
||||
NS_ASSERTION(length <= 2, "We should have one text node and one mozBR at most");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> firstNode;
|
||||
rv = nodeList->Item(0, getter_AddRefs(firstNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(firstNode);
|
||||
|
||||
nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(aNode);
|
||||
if (nodeAsText || (aNode == rootNode && aNodeOffset == 0)) {
|
||||
// Selection is somewhere inside the text node; the offset is aNodeOffset
|
||||
*aResult = aNodeOffset;
|
||||
} else {
|
||||
// Selection is on the mozBR node, so offset should be set to the length
|
||||
// of the text node.
|
||||
if (textNode) {
|
||||
rv = textNode->GetLength(&length);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*aResult = PRInt32(length);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::OffsetToDOMPoint(PRInt32 aOffset,
|
||||
nsIDOMNode** aResult,
|
||||
|
@ -1102,26 +1059,24 @@ nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart,
|
|||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 numRanges = 0;
|
||||
selection->GetRangeCount(&numRanges);
|
||||
|
||||
if (numRanges < 1)
|
||||
return NS_OK;
|
||||
|
||||
// We only operate on the first range in the selection!
|
||||
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
|
||||
NS_ENSURE_TRUE(selPriv, NS_ERROR_FAILURE);
|
||||
nsRefPtr<nsFrameSelection> frameSel;
|
||||
rv = selPriv->GetFrameSelection(getter_AddRefs(frameSel));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(frameSel, NS_ERROR_FAILURE);
|
||||
nsRefPtr<nsTypedSelection> typedSel =
|
||||
frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
NS_ENSURE_TRUE(typedSel, NS_ERROR_FAILURE);
|
||||
|
||||
if (aDirection) {
|
||||
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
|
||||
if (selPriv) {
|
||||
nsDirection direction = selPriv->GetSelectionDirection();
|
||||
if (direction == eDirNext) {
|
||||
*aDirection = eForward;
|
||||
} else if (direction == eDirPrevious) {
|
||||
*aDirection = eBackward;
|
||||
} else {
|
||||
NS_NOTREACHED("Invalid nsDirection enum value");
|
||||
}
|
||||
nsDirection direction = typedSel->GetSelectionDirection();
|
||||
if (direction == eDirNext) {
|
||||
*aDirection = eForward;
|
||||
} else if (direction == eDirPrevious) {
|
||||
*aDirection = eBackward;
|
||||
} else {
|
||||
NS_NOTREACHED("Invalid nsDirection enum value");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1129,40 +1084,10 @@ nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMRange> firstRange;
|
||||
rv = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(firstRange, NS_ERROR_FAILURE);
|
||||
nsContentUtils::GetSelectionInTextControl(typedSel,
|
||||
GetRootNodeAndInitializeEditor(), *aSelectionStart, *aSelectionEnd);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
PRInt32 startOffset = 0, endOffset = 0;
|
||||
|
||||
// Get the start point of the range.
|
||||
|
||||
rv = firstRange->GetStartContainer(getter_AddRefs(startNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
|
||||
|
||||
rv = firstRange->GetStartOffset(&startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the end point of the range.
|
||||
|
||||
rv = firstRange->GetEndContainer(getter_AddRefs(endNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
|
||||
|
||||
rv = firstRange->GetEndOffset(&endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Convert the start point to a selection offset.
|
||||
|
||||
rv = DOMPointToOffset(startNode, startOffset, aSelectionStart);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Convert the end point to a selection offset.
|
||||
|
||||
return DOMPointToOffset(endNode, endOffset, aSelectionEnd);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////END INTERFACE IMPLEMENTATIONS
|
||||
|
|
|
@ -26,6 +26,11 @@ class nsIAccessible;
|
|||
#endif
|
||||
class EditorInitializerEntryTracker;
|
||||
class nsTextEditorState;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
}
|
||||
}
|
||||
|
||||
class nsTextControlFrame : public nsStackFrame,
|
||||
public nsIAnonymousContentCreator,
|
||||
|
@ -286,7 +291,6 @@ protected:
|
|||
nsTextControlFrame* mFrame;
|
||||
};
|
||||
|
||||
nsresult DOMPointToOffset(nsIDOMNode* aNode, PRInt32 aNodeOffset, PRInt32 *aResult);
|
||||
nsresult OffsetToDOMPoint(PRInt32 aOffset, nsIDOMNode** aResult, PRInt32* aPosition);
|
||||
|
||||
/**
|
||||
|
@ -347,6 +351,7 @@ private:
|
|||
/**
|
||||
* Return the root DOM element, and implicitly initialize the editor if needed.
|
||||
*/
|
||||
mozilla::dom::Element* GetRootNodeAndInitializeEditor();
|
||||
nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement);
|
||||
|
||||
void FinishedInitializer() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче