nsresult nsTextControlFrame::OffsetToDOMPoint(PRInt32 aOffset, nsIDOMNode** aResult, PRInt32* aPosition) { NS_ENSURE_ARG_POINTER(aResult && aPosition); *aResult = nsnull; *aPosition = 0; nsCOMPtr<nsIDOMElement> rootElement; nsresult rv = GetRootNodeAndInitializeEditor(getter_AddRefs(rootElement)); NS_ENSURE_SUCCESS(rv, rv); 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); 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); if (length == 0 || aOffset < 0) { NS_IF_ADDREF(*aResult = rootNode); *aPosition = 0; } else if (textNode) { PRUint32 textLength = 0; textNode->GetLength(&textLength); if (length == 2 && PRUint32(aOffset) == textLength) { // If we're at the end of the text node and we have a trailing BR node, // set the selection on the BR node. NS_IF_ADDREF(*aResult = rootNode); *aPosition = 1; } else { // Otherwise, set the selection on the textnode itself. NS_IF_ADDREF(*aResult = firstNode); *aPosition = NS_MIN(aOffset, PRInt32(textLength)); } } else { NS_IF_ADDREF(*aResult = rootNode); *aPosition = 0; } return NS_OK; }
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::SelectAllOrCollapseToEndOfText(PRBool aSelect) { nsCOMPtr<nsIDOMElement> rootElement; nsresult rv = GetRootNodeAndInitializeEditor(getter_AddRefs(rootElement)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIContent> rootContent = do_QueryInterface(rootElement); nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement)); NS_ENSURE_TRUE(rootNode && rootContent, NS_ERROR_FAILURE); PRInt32 numChildren = rootContent->GetChildCount(); if (numChildren > 0) { // We never want to place the selection after the last // br under the root node! nsIContent *child = rootContent->GetChildAt(numChildren - 1); if (child) { if (child->Tag() == nsGkAtoms::br) --numChildren; } if (!aSelect && numChildren) { child = rootContent->GetChildAt(numChildren - 1); if (child && child->IsNodeOfType(nsINode::eTEXT)) { rootNode = do_QueryInterface(child); const nsTextFragment* fragment = child->GetText(); numChildren = fragment ? fragment->GetLength() : 0; } } } rv = SetSelectionInternal(rootNode, aSelect ? 0 : numChildren, rootNode, numChildren); NS_ENSURE_SUCCESS(rv, rv); return ScrollSelectionIntoView(); }