fix for 164054: Place selection at first visible content on editor doc load

This commit is contained in:
jfrancis%netscape.com 2002-10-08 22:53:55 +00:00
parent ca44975b7f
commit ac9f0f07f5
3 changed files with 102 additions and 56 deletions

View File

@ -814,55 +814,46 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument()
{
if (!mDocWeak || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
// get the selection
nsCOMPtr<nsISelection> selection;
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsISelectionController> selCon = do_QueryReferent(mSelConWeak);
if (!selCon) return NS_ERROR_NOT_INITIALIZED;
nsresult result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection)
nsresult result = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
return result;
if (!selection)
return NS_ERROR_NOT_INITIALIZED;
// get the root element
nsCOMPtr<nsIDOMElement> rootElement;
result = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(result)) return result;
if (!rootElement) return NS_ERROR_NULL_POINTER;
// find first editable thingy
nsCOMPtr<nsIDOMNode> firstNode;
result = GetFirstEditableNode(rootElement, address_of(firstNode));
if (firstNode)
{
nsCOMPtr<nsIDOMNodeList> nodeList;
nsCOMPtr<nsIDOMDocument> doc = do_QueryReferent(mDocWeak);
if (!doc) return NS_ERROR_NOT_INITIALIZED;
result = doc->GetElementsByTagName(NS_LITERAL_STRING("body"), getter_AddRefs(nodeList));
if ((NS_SUCCEEDED(result)) && nodeList)
// if firstNode is text, set selection to beginning of the text node
if (IsTextNode(firstNode))
{
PRUint32 count;
nodeList->GetLength(&count);
if (1!=count) { return NS_ERROR_UNEXPECTED; }
nsCOMPtr<nsIDOMNode> bodyNode;
result = nodeList->Item(0, getter_AddRefs(bodyNode));
if ((NS_SUCCEEDED(result)) && bodyNode)
{
// Get the first child of the body node:
nsCOMPtr<nsIDOMNode> firstNode;
result = GetFirstEditableNode(bodyNode, address_of(firstNode));
if (firstNode)
{
// if firstNode is text, set selection to beginning of the text node
if (IsTextNode(firstNode))
{
result = selection->Collapse(firstNode, 0);
}
else
{ // otherwise, it's a leaf node and we set the selection just in front of it
nsCOMPtr<nsIDOMNode> parentNode;
result = firstNode->GetParentNode(getter_AddRefs(parentNode));
if (NS_FAILED(result)) { return result; }
if (!parentNode) { return NS_ERROR_NULL_POINTER; }
PRInt32 offsetInParent;
result = nsEditor::GetChildOffset(firstNode, parentNode, offsetInParent);
if (NS_FAILED(result)) return result;
result = selection->Collapse(parentNode, offsetInParent);
}
}
else
{
// just the body node, set selection to inside the body
result = selection->Collapse(bodyNode, 0);
}
}
result = selection->Collapse(firstNode, 0);
}
else
{ // otherwise, it's a leaf node and we set the selection just in front of it
nsCOMPtr<nsIDOMNode> parentNode;
result = firstNode->GetParentNode(getter_AddRefs(parentNode));
if (NS_FAILED(result)) { return result; }
if (!parentNode) { return NS_ERROR_NULL_POINTER; }
PRInt32 offsetInParent;
result = nsEditor::GetChildOffset(firstNode, parentNode, offsetInParent);
if (NS_FAILED(result)) return result;
result = selection->Collapse(parentNode, offsetInParent);
}
}
else
{
// just the body node, set selection to inside the body
result = selection->Collapse(rootElement, 0);
}
return result;
}

View File

@ -281,6 +281,10 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
// block to scope nsAutoEditInitRulesTrigger
nsAutoEditInitRulesTrigger rulesTrigger(NS_STATIC_CAST(nsPlaintextEditor*,this), rulesRes);
// Set up a DTD
mDTD = do_CreateInstance(kCTransitionalDTDCID);
if (!mDTD) result = NS_ERROR_FAILURE;
// Init the plaintext editor
result = nsPlaintextEditor::Init(aDoc, aPresShell, aRoot, aSelCon, aFlags);
if (NS_FAILED(result)) { return result; }
@ -324,10 +328,6 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
selPriv->AddSelectionListener(listener);
}
}
// Set up a DTD
mDTD = do_CreateInstance(kCTransitionalDTDCID);
if (!mDTD) result = NS_ERROR_FAILURE;
}
if (NS_FAILED(rulesRes)) return rulesRes;
@ -470,6 +470,61 @@ NS_IMETHODIMP nsHTMLEditor::InitRules()
return res;
}
NS_IMETHODIMP nsHTMLEditor::BeginningOfDocument()
{
if (!mDocWeak || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
// get the selection
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res))
return res;
if (!selection)
return NS_ERROR_NOT_INITIALIZED;
// get the root element
nsCOMPtr<nsIDOMElement> rootElement;
res = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res)) return res;
if (!rootElement) return NS_ERROR_NULL_POINTER;
// find first editable thingy
PRBool done = PR_FALSE;
nsCOMPtr<nsIDOMNode> curNode(rootElement), selNode;
PRInt32 curOffset = 0, selOffset;
while (!done)
{
nsWSRunObject wsObj(this, curNode, curOffset);
nsCOMPtr<nsIDOMNode> visNode;
PRInt32 visOffset=0;
PRInt16 visType=0;
wsObj.NextVisibleNode(curNode, curOffset, address_of(visNode), &visOffset, &visType);
if ((visType==nsWSRunObject::eNormalWS) ||
(visType==nsWSRunObject::eText) ||
(visType==nsWSRunObject::eBreak) ||
(visType==nsWSRunObject::eSpecial))
{
selNode = visNode;
selOffset = visOffset;
done = PR_TRUE;
}
else if (visType==nsWSRunObject::eOtherBlock)
{
curNode = visNode;
curOffset = 0;
// keep looping
}
else
{
// else we found nothing useful
selNode = curNode;
selOffset = curOffset;
done = PR_TRUE;
}
}
return selection->Collapse(selNode, selOffset);
}
/**
* Returns true if the id represents an element of block type.
* Can be used to determine if a new paragraph should be started.
@ -1557,12 +1612,7 @@ nsHTMLEditor::GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver)
NS_IMETHODIMP
nsHTMLEditor::CollapseSelectionToStart()
{
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement);
return CollapseSelectionToDeepestNonTableFirstChild(nsnull, bodyNode);
return BeginningOfDocument();
}
nsresult
@ -1806,7 +1856,11 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
if (!child) return NS_ERROR_NULL_POINTER;
// Copy all attributes from the div child to current body element
return CloneAttributes(bodyElement, child);
res = CloneAttributes(bodyElement, child);
if (NS_FAILED(res)) return res;
// place selection at first editable content
return BeginningOfDocument();
}
NS_IMETHODIMP

View File

@ -120,6 +120,7 @@ public:
NS_IMETHODIMP HandleKeyPress(nsIDOMKeyEvent* aKeyEvent);
NS_IMETHODIMP CollapseSelectionToStart();
NS_IMETHOD GetIsDocumentEditable(PRBool *aIsDocumentEditable);
NS_IMETHODIMP BeginningOfDocument();
/* ------------ nsIHTMLEditor methods -------------- */
NS_IMETHOD CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock,