nsresult TextEditRules::CreateBogusNodeIfNeeded(Selection* aSelection) { NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(mTextEditor, NS_ERROR_NULL_POINTER); if (mBogusNode) { // Let's not create more than one, ok? return NS_OK; } // tell rules system to not do any post-processing AutoRules beginRulesSniffing(mTextEditor, EditAction::ignore, nsIEditor::eNone); nsCOMPtr<dom::Element> body = mTextEditor->GetRoot(); if (!body) { // We don't even have a body yet, don't insert any bogus nodes at // this point. return NS_OK; } // Now we've got the body element. Iterate over the body element's children, // looking for editable content. If no editable content is found, insert the // bogus node. for (nsCOMPtr<nsIContent> bodyChild = body->GetFirstChild(); bodyChild; bodyChild = bodyChild->GetNextSibling()) { if (mTextEditor->IsMozEditorBogusNode(bodyChild) || !mTextEditor->IsEditable(body) || // XXX hoist out of the loop? mTextEditor->IsEditable(bodyChild) || mTextEditor->IsBlockNode(bodyChild)) { return NS_OK; } } // Skip adding the bogus node if body is read-only. if (!mTextEditor->IsModifiableNode(body)) { return NS_OK; } // Create a br. nsCOMPtr<Element> newContent = mTextEditor->CreateHTMLContent(nsGkAtoms::br); NS_ENSURE_STATE(newContent); // set mBogusNode to be the newly created <br> mBogusNode = do_QueryInterface(newContent); NS_ENSURE_TRUE(mBogusNode, NS_ERROR_NULL_POINTER); // Give it a special attribute. newContent->SetAttr(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom, kMOZEditorBogusNodeValue, false); // Put the node in the document. nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(body); nsresult rv = mTextEditor->InsertNode(mBogusNode, bodyNode, 0); NS_ENSURE_SUCCESS(rv, rv); // Set selection. aSelection->CollapseNative(body, 0); return NS_OK; }
nsresult nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection) { if (!aSelection) { return NS_ERROR_NULL_POINTER; } if (!mEditor) { return NS_ERROR_NULL_POINTER; } if (mBogusNode) return NS_OK; // let's not create more than one, ok? // tell rules system to not do any post-processing nsAutoRules beginRulesSniffing(mEditor, nsEditor::kOpIgnore, nsIEditor::eNone); nsIDOMNode* body = mEditor->GetRoot(); if (!body) { // we don't even have a body yet, don't insert any bogus nodes at // this point. return NS_OK; } // now we've got the body tag. // iterate the body tag, looking for editable content // if no editable content is found, insert the bogus node PRBool needsBogusContent=PR_TRUE; nsCOMPtr<nsIDOMNode> bodyChild; nsresult res = body->GetFirstChild(getter_AddRefs(bodyChild)); while ((NS_SUCCEEDED(res)) && bodyChild) { if (mEditor->IsMozEditorBogusNode(bodyChild) || !mEditor->IsEditable(body) || mEditor->IsEditable(bodyChild)) { needsBogusContent = PR_FALSE; break; } nsCOMPtr<nsIDOMNode>temp; bodyChild->GetNextSibling(getter_AddRefs(temp)); bodyChild = do_QueryInterface(temp); } // Skip adding the bogus node if body is read-only if (needsBogusContent && mEditor->IsModifiableNode(body)) { // create a br nsCOMPtr<nsIContent> newContent; res = mEditor->CreateHTMLContent(NS_LITERAL_STRING("br"), getter_AddRefs(newContent)); NS_ENSURE_SUCCESS(res, res); nsCOMPtr<nsIDOMElement>brElement = do_QueryInterface(newContent); // set mBogusNode to be the newly created <br> mBogusNode = brElement; NS_ENSURE_TRUE(mBogusNode, NS_ERROR_NULL_POINTER); // give it a special attribute newContent->SetAttr(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom, kMOZEditorBogusNodeValue, PR_FALSE); // put the node in the document res = mEditor->InsertNode(mBogusNode, body, 0); NS_ENSURE_SUCCESS(res, res); // set selection aSelection->Collapse(body, 0); } return res; }