fix for 164054: Place selection at first visible content on editor doc load
This commit is contained in:
Родитель
c864ac4f5e
Коммит
6f9fc789b7
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче