seperating out html edit rules from text edit rules

git-svn-id: svn://10.0.0.236/trunk@25439 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jfrancis%netscape.com 1999-03-29 08:02:05 +00:00
parent bfe4edbf65
commit 46bf828d41
10 changed files with 281 additions and 339 deletions

View File

@ -18,11 +18,13 @@
#include "nsTextEditor.h"
#include "nsHTMLEditor.h"
#include "nsHTMLEditRules.h"
#include "nsEditorEventListeners.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMKeyListener.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMSelection.h"
#include "nsEditorCID.h"
#include "nsIComponentManager.h"
@ -96,6 +98,14 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
return result;
}
void nsHTMLEditor::InitRules()
{
// instantiate the rules for this text editor
// XXX: we should be told which set of rules to instantiate
mRules = new nsHTMLEditRules();
mRules->Init(this);
}
NS_IMETHODIMP nsHTMLEditor::SetTextProperty(nsIAtom *aProperty)
{
return nsTextEditor::SetTextProperty(aProperty);
@ -123,7 +133,80 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
NS_IMETHODIMP nsHTMLEditor::InsertBreak()
{
return nsTextEditor::InsertBreak();
nsresult result;
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
nsCOMPtr<nsIDOMSelection> selection;
PRBool cancel= PR_FALSE;
result = nsEditor::BeginTransaction();
if (NS_FAILED(result)) { return result; }
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillInsertBreak(selection, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
// create the new BR node
nsCOMPtr<nsIDOMNode> newNode;
nsAutoString tag("BR");
result = nsEditor::DeleteSelectionAndCreateNode(tag, getter_AddRefs(newNode));
if (NS_SUCCEEDED(result) && newNode)
{
// set the selection to the new node
nsCOMPtr<nsIDOMNode>parent;
result = newNode->GetParentNode(getter_AddRefs(parent));
if (NS_SUCCEEDED(result) && parent)
{
PRInt32 offsetInParent=-1; // we use the -1 as a marker to see if we need to compute this or not
nsCOMPtr<nsIDOMNode>nextNode;
newNode->GetNextSibling(getter_AddRefs(nextNode));
if (nextNode)
{
nsCOMPtr<nsIDOMCharacterData>nextTextNode;
nextTextNode = do_QueryInterface(nextNode);
if (!nextTextNode) {
nextNode = do_QueryInterface(newNode);
}
else {
offsetInParent=0;
}
}
else {
nextNode = do_QueryInterface(newNode);
}
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result))
{
if (-1==offsetInParent)
{
nextNode->GetParentNode(getter_AddRefs(parent));
result = nsIEditorSupport::GetChildOffset(nextNode, parent, offsetInParent);
if (NS_SUCCEEDED(result)) {
selection->Collapse(parent, offsetInParent+1); // +1 to insert just after the break
}
}
else
{
selection->Collapse(nextNode, offsetInParent);
}
}
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidInsertBreak(selection, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");
// XXXX: Horrible hack! We are doing this because
// of an error in Gecko which is not rendering the
// document after a change via the DOM - gpk 2/13/99
// BEGIN HACK!!!
HACKForceRedraw();
// END HACK
return result;
}
// Methods shared with the base editor.

View File

@ -110,8 +110,14 @@ public:
NS_IMETHOD JoinTableCells(PRBool aCellToRight);
// Data members
protected:
// rules initialization
virtual void InitRules();
// EVENT LISTENERS AND COMMAND ROUTING NEEDS WORK
// For now, the listners are tied to the nsTextEditor class
//

View File

@ -17,7 +17,7 @@
*/
#include "nsTextEditRules.h"
#include "nsTextEditor.h"
#include "nsEditor.h"
#include "PlaceholderTxn.h"
#include "InsertTextTxn.h"
#include "nsCOMPtr.h"
@ -35,7 +35,11 @@ const static char* kMOZEditorBogusNodeValue="TRUE";
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
/*-------------------------------------------------------------------*
* Helper Functions
*-------------------------------------------------------------------*/
PRBool nsTextEditRules::NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
{
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(aNode);
@ -51,7 +55,7 @@ static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
return PR_FALSE;
}
PRBool IsEditable(nsIDOMNode *aNode)
PRBool nsTextEditRules::IsEditable(nsIDOMNode *aNode)
{
if (!aNode) return PR_FALSE;
nsCOMPtr<nsIDOMElement>element;
@ -91,6 +95,11 @@ PRBool IsEditable(nsIDOMNode *aNode)
}
/*-------------------------------------------------------------------*
* Constructor/Destructor
*-------------------------------------------------------------------*/
nsTextEditRules::nsTextEditRules()
{
mEditor = nsnull;
@ -101,8 +110,15 @@ nsTextEditRules::~nsTextEditRules()
// do NOT delete mEditor here. We do not hold a ref count to mEditor. mEditor owns our lifespan.
}
/*-------------------------------------------------------------------*
* Public methods
*-------------------------------------------------------------------*/
NS_IMETHODIMP
nsTextEditRules::Init(nsTextEditor *aEditor)
nsTextEditRules::Init(nsEditor *aEditor)
{
// null aNextRule is ok
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
@ -110,6 +126,17 @@ nsTextEditRules::Init(nsTextEditor *aEditor)
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
@ -168,126 +195,6 @@ nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
return DidInsert(aSelection, aResult);
}
NS_IMETHODIMP
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
return WillInsert(aSelection, aCancel);
}
// XXX: this code is all experimental, and has no effect on the content model yet
// the point here is to collapse adjacent BR's into P's
NS_IMETHODIMP
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
PRBool isCollapsed;
aSelection->IsCollapsed(&isCollapsed);
NS_ASSERTION(PR_TRUE==isCollapsed, "selection not collapsed after insert break.");
// if the insert break resulted in consecutive BR tags,
// collapse the two BR tags into a single P
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(aSelection,&result);
if (enumerator)
{
enumerator->First();
nsISupports *currentItem;
result = enumerator->CurrentItem(&currentItem);
if ((NS_SUCCEEDED(result)) && currentItem)
{
result = NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
if (range)
{
nsIAtom *brTag = NS_NewAtom("BR");
nsCOMPtr<nsIDOMNode> startNode;
result = range->GetStartParent(getter_AddRefs(startNode));
if ((NS_SUCCEEDED(result)) && startNode)
{
PRInt32 offset;
range->GetStartOffset(&offset);
nsCOMPtr<nsIDOMNodeList>startNodeChildren;
result = startNode->GetChildNodes(getter_AddRefs(startNodeChildren));
if ((NS_SUCCEEDED(result)) && startNodeChildren)
{
nsCOMPtr<nsIDOMNode> selectedNode;
result = startNodeChildren->Item(offset, getter_AddRefs(selectedNode));
if ((NS_SUCCEEDED(result)) && selectedNode)
{
nsCOMPtr<nsIDOMNode> prevNode;
result = selectedNode->GetPreviousSibling(getter_AddRefs(prevNode));
if ((NS_SUCCEEDED(result)) && prevNode)
{
if (PR_TRUE==NodeIsType(prevNode, brTag))
{ // the previous node is a BR, check it's siblings
nsCOMPtr<nsIDOMNode> leftNode;
result = prevNode->GetPreviousSibling(getter_AddRefs(leftNode));
if ((NS_SUCCEEDED(result)) && leftNode)
{
if (PR_TRUE==NodeIsType(leftNode, brTag))
{ // left sibling is also a BR, collapse
printf("1\n");
}
else
{
if (PR_TRUE==NodeIsType(selectedNode, brTag))
{ // right sibling is also a BR, collapse
printf("2\n");
}
}
}
}
}
// now check the next node from selectedNode
nsCOMPtr<nsIDOMNode> nextNode;
result = selectedNode->GetNextSibling(getter_AddRefs(nextNode));
if ((NS_SUCCEEDED(result)) && nextNode)
{
if (PR_TRUE==NodeIsType(nextNode, brTag))
{ // the previous node is a BR, check it's siblings
nsCOMPtr<nsIDOMNode> rightNode;
result = nextNode->GetNextSibling(getter_AddRefs(rightNode));
if ((NS_SUCCEEDED(result)) && rightNode)
{
if (PR_TRUE==NodeIsType(rightNode, brTag))
{ // right sibling is also a BR, collapse
printf("3\n");
}
else
{
if (PR_TRUE==NodeIsType(selectedNode, brTag))
{ // left sibling is also a BR, collapse
printf("4\n");
}
}
}
}
}
}
}
}
NS_RELEASE(brTag);
}
}
}
}
return result;
}
NS_IMETHODIMP
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
{
if (!aTag) { return NS_ERROR_NULL_POINTER; }
*aTag = NS_NewAtom("BR");
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
{

View File

@ -23,7 +23,7 @@
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
class nsTextEditor;
class nsEditor;
class PlaceholderTxn;
/** Object that encapsulates HTML text-specific editing rules.
@ -44,11 +44,10 @@ public:
nsTextEditRules();
virtual ~nsTextEditRules();
NS_IMETHOD Init(nsTextEditor *aEditor);
NS_IMETHOD Init(nsEditor *aEditor);
NS_IMETHOD WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD GetInsertBreakTag(nsIAtom **aTag);
NS_IMETHOD WillInsertText(nsIDOMSelection *aSelection,
const nsString& aInputString,
@ -71,7 +70,11 @@ public:
protected:
nsTextEditor *mEditor; // note that we do not refcount the editor
// helper functions
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag);
static PRBool IsEditable(nsIDOMNode *aNode);
nsEditor *mEditor; // note that we do not refcount the editor
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
};

View File

@ -175,6 +175,9 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
if (NS_OK != result)
return result;
// Init the rules system
InitRules();
result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
if (NS_OK != result) {
return result;
@ -217,15 +220,10 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
}
//cmanske: Shouldn't we check result from this?
erP->AddEventListenerByIID(mKeyListenerP, kIDOMKeyListenerIID);
//erP->AddEventListenerByIID(mDragListenerP, kIDOMDragListenerIID);
//erP->AddEventListenerByIID(mMouseListenerP, kIDOMMouseListenerIID);
//erP->AddEventListener(mDragListenerP, kIDOMDragListenerIID);
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
erP->AddEventListenerByIID(mTextListenerP,kIDOMTextListenerIID);
// instantiate the rules for this text editor
// XXX: we should be told which set of rules to instantiate
mRules = new nsTextEditRules();
mRules->Init(this);
erP->AddEventListenerByIID(mTextListenerP,kIDOMTextListenerIID);
result = NS_OK;
@ -234,6 +232,16 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
return result;
}
void nsTextEditor::InitRules()
{
// instantiate the rules for this text editor
// XXX: we should be told which set of rules to instantiate
mRules = new nsTextEditRules();
mRules->Init(this);
}
// this is a total hack for now. We don't yet have a way of getting the style properties
// of the current selection, so we can't do anything useful here except show off a little.
NS_IMETHODIMP nsTextEditor::SetTextProperty(nsIAtom *aProperty)
@ -485,80 +493,11 @@ NS_IMETHODIMP nsTextEditor::InsertText(const nsString& aStringToInsert)
NS_IMETHODIMP nsTextEditor::InsertBreak()
{
nsresult result;
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
// For plainttext just pass newlines through
nsAutoString key;
key += '\n';
nsCOMPtr<nsIDOMSelection> selection;
PRBool cancel= PR_FALSE;
result = nsEditor::BeginTransaction();
if (NS_FAILED(result)) { return result; }
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillInsertBreak(selection, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
// create the new BR node
nsCOMPtr<nsIDOMNode> newNode;
nsAutoString tag("BR");
result = nsEditor::DeleteSelectionAndCreateNode(tag, getter_AddRefs(newNode));
if (NS_SUCCEEDED(result) && newNode)
{
// set the selection to the new node
nsCOMPtr<nsIDOMNode>parent;
result = newNode->GetParentNode(getter_AddRefs(parent));
if (NS_SUCCEEDED(result) && parent)
{
PRInt32 offsetInParent=-1; // we use the -1 as a marker to see if we need to compute this or not
nsCOMPtr<nsIDOMNode>nextNode;
newNode->GetNextSibling(getter_AddRefs(nextNode));
if (nextNode)
{
nsCOMPtr<nsIDOMCharacterData>nextTextNode;
nextTextNode = do_QueryInterface(nextNode);
if (!nextTextNode) {
nextNode = do_QueryInterface(newNode);
}
else {
offsetInParent=0;
}
}
else {
nextNode = do_QueryInterface(newNode);
}
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result))
{
if (-1==offsetInParent)
{
nextNode->GetParentNode(getter_AddRefs(parent));
result = nsIEditorSupport::GetChildOffset(nextNode, parent, offsetInParent);
if (NS_SUCCEEDED(result)) {
selection->Collapse(parent, offsetInParent+1); // +1 to insert just after the break
}
}
else
{
selection->Collapse(nextNode, offsetInParent);
}
}
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidInsertBreak(selection, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");
// XXXX: Horrible hack! We are doing this because
// of an error in Gecko which is not rendering the
// document after a change via the DOM - gpk 2/13/99
// BEGIN HACK!!!
HACKForceRedraw();
// END HACK
return result;
return InsertText(key);
}

View File

@ -89,6 +89,11 @@ public:
NS_IMETHOD OutputHTML(nsString& aOutputString);
protected:
// rules initialization
virtual void InitRules();
// Utility Methods
virtual void IsTextStyleSet(nsIStyleContext *aSC,

View File

@ -18,11 +18,13 @@
#include "nsTextEditor.h"
#include "nsHTMLEditor.h"
#include "nsHTMLEditRules.h"
#include "nsEditorEventListeners.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMKeyListener.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMSelection.h"
#include "nsEditorCID.h"
#include "nsIComponentManager.h"
@ -96,6 +98,14 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
return result;
}
void nsHTMLEditor::InitRules()
{
// instantiate the rules for this text editor
// XXX: we should be told which set of rules to instantiate
mRules = new nsHTMLEditRules();
mRules->Init(this);
}
NS_IMETHODIMP nsHTMLEditor::SetTextProperty(nsIAtom *aProperty)
{
return nsTextEditor::SetTextProperty(aProperty);
@ -123,7 +133,80 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
NS_IMETHODIMP nsHTMLEditor::InsertBreak()
{
return nsTextEditor::InsertBreak();
nsresult result;
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
nsCOMPtr<nsIDOMSelection> selection;
PRBool cancel= PR_FALSE;
result = nsEditor::BeginTransaction();
if (NS_FAILED(result)) { return result; }
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillInsertBreak(selection, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
// create the new BR node
nsCOMPtr<nsIDOMNode> newNode;
nsAutoString tag("BR");
result = nsEditor::DeleteSelectionAndCreateNode(tag, getter_AddRefs(newNode));
if (NS_SUCCEEDED(result) && newNode)
{
// set the selection to the new node
nsCOMPtr<nsIDOMNode>parent;
result = newNode->GetParentNode(getter_AddRefs(parent));
if (NS_SUCCEEDED(result) && parent)
{
PRInt32 offsetInParent=-1; // we use the -1 as a marker to see if we need to compute this or not
nsCOMPtr<nsIDOMNode>nextNode;
newNode->GetNextSibling(getter_AddRefs(nextNode));
if (nextNode)
{
nsCOMPtr<nsIDOMCharacterData>nextTextNode;
nextTextNode = do_QueryInterface(nextNode);
if (!nextTextNode) {
nextNode = do_QueryInterface(newNode);
}
else {
offsetInParent=0;
}
}
else {
nextNode = do_QueryInterface(newNode);
}
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result))
{
if (-1==offsetInParent)
{
nextNode->GetParentNode(getter_AddRefs(parent));
result = nsIEditorSupport::GetChildOffset(nextNode, parent, offsetInParent);
if (NS_SUCCEEDED(result)) {
selection->Collapse(parent, offsetInParent+1); // +1 to insert just after the break
}
}
else
{
selection->Collapse(nextNode, offsetInParent);
}
}
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidInsertBreak(selection, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");
// XXXX: Horrible hack! We are doing this because
// of an error in Gecko which is not rendering the
// document after a change via the DOM - gpk 2/13/99
// BEGIN HACK!!!
HACKForceRedraw();
// END HACK
return result;
}
// Methods shared with the base editor.

View File

@ -110,8 +110,14 @@ public:
NS_IMETHOD JoinTableCells(PRBool aCellToRight);
// Data members
protected:
// rules initialization
virtual void InitRules();
// EVENT LISTENERS AND COMMAND ROUTING NEEDS WORK
// For now, the listners are tied to the nsTextEditor class
//

View File

@ -17,7 +17,7 @@
*/
#include "nsTextEditRules.h"
#include "nsTextEditor.h"
#include "nsEditor.h"
#include "PlaceholderTxn.h"
#include "InsertTextTxn.h"
#include "nsCOMPtr.h"
@ -35,7 +35,11 @@ const static char* kMOZEditorBogusNodeValue="TRUE";
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
/*-------------------------------------------------------------------*
* Helper Functions
*-------------------------------------------------------------------*/
PRBool nsTextEditRules::NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
{
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(aNode);
@ -51,7 +55,7 @@ static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
return PR_FALSE;
}
PRBool IsEditable(nsIDOMNode *aNode)
PRBool nsTextEditRules::IsEditable(nsIDOMNode *aNode)
{
if (!aNode) return PR_FALSE;
nsCOMPtr<nsIDOMElement>element;
@ -91,6 +95,11 @@ PRBool IsEditable(nsIDOMNode *aNode)
}
/*-------------------------------------------------------------------*
* Constructor/Destructor
*-------------------------------------------------------------------*/
nsTextEditRules::nsTextEditRules()
{
mEditor = nsnull;
@ -101,8 +110,15 @@ nsTextEditRules::~nsTextEditRules()
// do NOT delete mEditor here. We do not hold a ref count to mEditor. mEditor owns our lifespan.
}
/*-------------------------------------------------------------------*
* Public methods
*-------------------------------------------------------------------*/
NS_IMETHODIMP
nsTextEditRules::Init(nsTextEditor *aEditor)
nsTextEditRules::Init(nsEditor *aEditor)
{
// null aNextRule is ok
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
@ -110,6 +126,17 @@ nsTextEditRules::Init(nsTextEditor *aEditor)
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
@ -168,126 +195,6 @@ nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
return DidInsert(aSelection, aResult);
}
NS_IMETHODIMP
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
return WillInsert(aSelection, aCancel);
}
// XXX: this code is all experimental, and has no effect on the content model yet
// the point here is to collapse adjacent BR's into P's
NS_IMETHODIMP
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
PRBool isCollapsed;
aSelection->IsCollapsed(&isCollapsed);
NS_ASSERTION(PR_TRUE==isCollapsed, "selection not collapsed after insert break.");
// if the insert break resulted in consecutive BR tags,
// collapse the two BR tags into a single P
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(aSelection,&result);
if (enumerator)
{
enumerator->First();
nsISupports *currentItem;
result = enumerator->CurrentItem(&currentItem);
if ((NS_SUCCEEDED(result)) && currentItem)
{
result = NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
if (range)
{
nsIAtom *brTag = NS_NewAtom("BR");
nsCOMPtr<nsIDOMNode> startNode;
result = range->GetStartParent(getter_AddRefs(startNode));
if ((NS_SUCCEEDED(result)) && startNode)
{
PRInt32 offset;
range->GetStartOffset(&offset);
nsCOMPtr<nsIDOMNodeList>startNodeChildren;
result = startNode->GetChildNodes(getter_AddRefs(startNodeChildren));
if ((NS_SUCCEEDED(result)) && startNodeChildren)
{
nsCOMPtr<nsIDOMNode> selectedNode;
result = startNodeChildren->Item(offset, getter_AddRefs(selectedNode));
if ((NS_SUCCEEDED(result)) && selectedNode)
{
nsCOMPtr<nsIDOMNode> prevNode;
result = selectedNode->GetPreviousSibling(getter_AddRefs(prevNode));
if ((NS_SUCCEEDED(result)) && prevNode)
{
if (PR_TRUE==NodeIsType(prevNode, brTag))
{ // the previous node is a BR, check it's siblings
nsCOMPtr<nsIDOMNode> leftNode;
result = prevNode->GetPreviousSibling(getter_AddRefs(leftNode));
if ((NS_SUCCEEDED(result)) && leftNode)
{
if (PR_TRUE==NodeIsType(leftNode, brTag))
{ // left sibling is also a BR, collapse
printf("1\n");
}
else
{
if (PR_TRUE==NodeIsType(selectedNode, brTag))
{ // right sibling is also a BR, collapse
printf("2\n");
}
}
}
}
}
// now check the next node from selectedNode
nsCOMPtr<nsIDOMNode> nextNode;
result = selectedNode->GetNextSibling(getter_AddRefs(nextNode));
if ((NS_SUCCEEDED(result)) && nextNode)
{
if (PR_TRUE==NodeIsType(nextNode, brTag))
{ // the previous node is a BR, check it's siblings
nsCOMPtr<nsIDOMNode> rightNode;
result = nextNode->GetNextSibling(getter_AddRefs(rightNode));
if ((NS_SUCCEEDED(result)) && rightNode)
{
if (PR_TRUE==NodeIsType(rightNode, brTag))
{ // right sibling is also a BR, collapse
printf("3\n");
}
else
{
if (PR_TRUE==NodeIsType(selectedNode, brTag))
{ // left sibling is also a BR, collapse
printf("4\n");
}
}
}
}
}
}
}
}
NS_RELEASE(brTag);
}
}
}
}
return result;
}
NS_IMETHODIMP
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
{
if (!aTag) { return NS_ERROR_NULL_POINTER; }
*aTag = NS_NewAtom("BR");
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
{

View File

@ -23,7 +23,7 @@
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
class nsTextEditor;
class nsEditor;
class PlaceholderTxn;
/** Object that encapsulates HTML text-specific editing rules.
@ -44,11 +44,10 @@ public:
nsTextEditRules();
virtual ~nsTextEditRules();
NS_IMETHOD Init(nsTextEditor *aEditor);
NS_IMETHOD Init(nsEditor *aEditor);
NS_IMETHOD WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD GetInsertBreakTag(nsIAtom **aTag);
NS_IMETHOD WillInsertText(nsIDOMSelection *aSelection,
const nsString& aInputString,
@ -71,7 +70,11 @@ public:
protected:
nsTextEditor *mEditor; // note that we do not refcount the editor
// helper functions
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag);
static PRBool IsEditable(nsIDOMNode *aNode);
nsEditor *mEditor; // note that we do not refcount the editor
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
};