зеркало из https://github.com/mozilla/gecko-dev.git
support for ChangeAttributeTxn
This commit is contained in:
Родитель
23db7f64f8
Коммит
af2c66d39a
|
@ -22,11 +22,15 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsEditFactory.h"
|
||||
#include "nsEditorCID.h"
|
||||
|
||||
#include "nsTransactionManagerCID.h"
|
||||
#include "nsITransactionManager.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
||||
|
@ -41,6 +45,20 @@ static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
|
|||
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
|
||||
static NS_DEFINE_IID(kITransactionManagerIID, NS_ITRANSACTIONMANAGER_IID);
|
||||
static NS_DEFINE_CID(kCTransactionManagerFactoryCID, NS_TRANSACTION_MANAGER_FACTORY_CID);
|
||||
|
||||
|
||||
#ifdef XP_PC
|
||||
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#define TRANSACTION_MANAGER_DLL "TRANSACTION_MANAGER_DLL"
|
||||
#else // XP_UNIX
|
||||
#define TRANSACTION_MANAGER_DLL "libtxmgr.so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//monitor for the editor
|
||||
|
@ -98,26 +116,29 @@ NSRegisterSelf(const char *path)
|
|||
PR_TRUE, PR_TRUE); //this will register the factory with the xpcom dll.
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSUnregisterSelf(const char *path)
|
||||
{
|
||||
return nsRepository::UnregisterFactory(kIEditFactoryIID, path);//this will unregister the factory with the xpcom dll.
|
||||
}
|
||||
|
||||
|
||||
|
||||
//END EXPORTS
|
||||
|
||||
|
||||
//class implementations are in order they are declared in editor.h
|
||||
|
||||
|
||||
static PRBool needsInit=PR_TRUE;
|
||||
nsEditor::nsEditor()
|
||||
{
|
||||
//initialize member variables here
|
||||
NS_INIT_REFCNT();
|
||||
if (PR_TRUE==needsInit)
|
||||
{
|
||||
needsInit=PR_FALSE;
|
||||
nsRepository::RegisterFactory(kCTransactionManagerFactoryCID,
|
||||
TRANSACTION_MANAGER_DLL, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
mTxnMgr = nsnull;
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,6 +231,8 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
|
|||
erP->AddEventListener(mKeyListenerP, kIDOMKeyListenerIID);
|
||||
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
|
||||
|
||||
/* fire up the transaction manager */
|
||||
|
||||
/*
|
||||
now to handle selection
|
||||
*/
|
||||
|
@ -229,6 +252,29 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
|
|||
return t_result;
|
||||
}
|
||||
*/
|
||||
|
||||
nsISupports *isup = 0;
|
||||
nsresult result;
|
||||
|
||||
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
|
||||
kITransactionManagerIID, &isup);
|
||||
|
||||
if (NS_FAILED(result) || !isup) {
|
||||
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!mTxnMgr) {
|
||||
printf("ERROR: QueryInterface() returned NULL pointer.\n");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -258,6 +304,40 @@ nsEditor::GetProperties(PROPERTIES **)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::SetAttribute(nsIDOMElement *aElement, const nsString& aAttribute, const nsString& aValue)
|
||||
{
|
||||
return aElement->SetDOMAttribute(aAttribute, aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetAttributeValue(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
nsString& aResultValue,
|
||||
PRBool& aResultIsSet)
|
||||
{
|
||||
aResultIsSet=PR_FALSE;
|
||||
nsresult result=NS_OK;
|
||||
if (nsnull!=aElement)
|
||||
{
|
||||
nsIDOMAttr* attNode=nsnull;
|
||||
result = aElement->GetAttributeNode(aAttribute, &attNode);
|
||||
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
|
||||
{
|
||||
attNode->GetSpecified(&aResultIsSet);
|
||||
attNode->GetValue(aResultValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute)
|
||||
{
|
||||
return aElement->RemoveAttribute(aAttribute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::Commit(PRBool aCtrlKey)
|
||||
|
@ -337,6 +417,59 @@ nsEditor::GetCurrentNode(nsIDOMNode ** aNode)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
/* If no node set, get root node */
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
|
||||
if (nsnull==aStartNode)
|
||||
{
|
||||
mDomInterfaceP->GetDocumentElement(getter_AddRefs(element));
|
||||
result = element->QueryInterface(kIDOMNodeIID,getter_AddRefs(node));
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
if (!node)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
node=aStartNode;
|
||||
|
||||
*aResult = nsnull;
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = node->GetFirstChild(getter_AddRefs(childNode));
|
||||
while (childNode)
|
||||
{
|
||||
result = childNode->QueryInterface(kIDOMNodeIID,getter_AddRefs(element));
|
||||
nsString tag;
|
||||
if (NS_SUCCEEDED(result) && (element))
|
||||
{
|
||||
element->GetTagName(tag);
|
||||
if (PR_TRUE==aTag.Equals(tag))
|
||||
{
|
||||
return (childNode->QueryInterface(kIDOMNodeIID,(void **) aResult)); // does the addref
|
||||
}
|
||||
else
|
||||
{
|
||||
nsresult result = GetFirstNodeOfType(childNode, aTag, aResult);
|
||||
if (nsnull!=*aResult)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> xNode;
|
||||
childNode->GetNextSibling(getter_AddRefs(xNode));
|
||||
childNode=xNode;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
|
@ -387,6 +520,46 @@ nsEditor::GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::ExecuteTransaction(nsITransaction *aTxn)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=aTxn)
|
||||
{
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Do(aTxn);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = aTxn->Do();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::Undo()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Undo();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::Redo()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Redo();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//END nsEditor Private methods
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "editorInterfaces.h"
|
||||
#include "nsITransactionManager.h"
|
||||
//#include "nsISelection.h"
|
||||
|
||||
|
||||
|
@ -42,6 +43,9 @@ private:
|
|||
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
|
||||
// nsCOMPtr<nsISelection> mSelectionP;
|
||||
//nsCOMPtr<nsITransactionManager> mTxnMgrP;
|
||||
nsITransactionManager * mTxnMgr;
|
||||
|
||||
public:
|
||||
/** The default constructor. This should suffice. the setting of the interfaces is done
|
||||
* after the construction of the editor class.
|
||||
|
@ -66,10 +70,23 @@ public:
|
|||
|
||||
virtual nsresult GetProperties(PROPERTIES **);
|
||||
|
||||
virtual nsresult SetAttribute(nsIDOMElement * aElement,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue);
|
||||
|
||||
virtual nsresult GetAttributeValue(nsIDOMElement * aElement,
|
||||
const nsString& aAttribute,
|
||||
nsString& aResultValue,
|
||||
PRBool& aResultIsSet);
|
||||
|
||||
virtual nsresult RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
|
||||
|
||||
virtual nsresult InsertString(nsString *aString);
|
||||
|
||||
virtual nsresult Commit(PRBool aCtrlKey);
|
||||
|
||||
|
||||
|
||||
/*END nsIEditor interfaces*/
|
||||
|
||||
/*BEGIN nsEditor interfaces*/
|
||||
|
@ -112,6 +129,42 @@ public:
|
|||
*/
|
||||
nsresult GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode);
|
||||
|
||||
/** GetFirstNodeOfType ADDREFFS and will get the next available node from the passed
|
||||
* in aStartNode parameter of type aTag.
|
||||
* It can also return NS_ERROR_FAILURE if no such nodes are available
|
||||
* @param nsIDOMNode *aStartNode is the node to start looking from
|
||||
* @param nsIAtom *aTag is the type of node we are searching for
|
||||
* @param nsIDOMNode **aResult is the node we found, or nsnull if there is none
|
||||
*/
|
||||
nsresult GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult);
|
||||
|
||||
/** ExecuteTransaction fires a transaction. It is provided here so
|
||||
* clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is used.
|
||||
* Otherwise, the transaction is just executed directly.
|
||||
*
|
||||
* @param aTxn the transaction to execute
|
||||
*/
|
||||
nsresult ExecuteTransaction(nsITransaction *aTxn);
|
||||
|
||||
/** Undo reverses the effects of the last ExecuteTransaction operation
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to undo and the result of
|
||||
* that undo is returned.
|
||||
* Otherwise, the Undo request is ignored.
|
||||
*
|
||||
*/
|
||||
nsresult Undo();
|
||||
|
||||
/** Redo reverses the effects of the last Undo operation
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to redo and the result of
|
||||
* that redo is returned.
|
||||
* Otherwise, the Redo request is ignored.
|
||||
*
|
||||
*/
|
||||
nsresult Redo();
|
||||
|
||||
/*END private methods of nsEditor*/
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
#include "editorInterfaces.h"
|
||||
#include "nsString.h"
|
||||
#include "editor.h"
|
||||
#include "ChangeAttributeTxn.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
|
||||
|
||||
/*
|
||||
* nsEditorKeyListener implementation
|
||||
|
@ -113,25 +117,30 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
|
||||
) {
|
||||
switch(keyCode) {
|
||||
case nsIDOMEvent::VK_BACK:
|
||||
break;
|
||||
case nsIDOMEvent::VK_RETURN:
|
||||
// Need to implement creation of either <P> or <BR> nodes.
|
||||
mEditor->Commit(ctrlKey);
|
||||
break;
|
||||
default:
|
||||
// XXX Replace with x-platform NS-virtkeycode transform.
|
||||
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
|
||||
nsString* key = new nsString();
|
||||
*key += character;
|
||||
if (!isShift) {
|
||||
key->ToLowerCase();
|
||||
PRBool keyProcessed;
|
||||
ProcessShortCutKeys(aKeyEvent, keyProcessed);
|
||||
if (PR_FALSE==keyProcessed)
|
||||
{
|
||||
switch(keyCode) {
|
||||
case nsIDOMEvent::VK_BACK:
|
||||
break;
|
||||
case nsIDOMEvent::VK_RETURN:
|
||||
// Need to implement creation of either <P> or <BR> nodes.
|
||||
mEditor->Commit(ctrlKey);
|
||||
break;
|
||||
default:
|
||||
// XXX Replace with x-platform NS-virtkeycode transform.
|
||||
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
|
||||
nsString* key = new nsString();
|
||||
*key += character;
|
||||
if (!isShift) {
|
||||
key->ToLowerCase();
|
||||
}
|
||||
mEditor->InsertString(key);
|
||||
delete key;
|
||||
}
|
||||
mEditor->InsertString(key);
|
||||
delete key;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +163,90 @@ nsEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
|
||||
{
|
||||
aProcessed=PR_FALSE;
|
||||
PRUint32 keyCode;
|
||||
PRBool isShift;
|
||||
PRBool ctrlKey;
|
||||
|
||||
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
|
||||
)
|
||||
{
|
||||
// XXX: please please please get these mappings from an external source!
|
||||
switch (keyCode)
|
||||
{
|
||||
// hard-coded undo
|
||||
case nsIDOMEvent::VK_Z:
|
||||
if (PR_TRUE==ctrlKey)
|
||||
{
|
||||
if (nsnull!=mEditor)
|
||||
mEditor->Undo();
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
// hard-coded redo
|
||||
case nsIDOMEvent::VK_Y:
|
||||
if (PR_TRUE==ctrlKey)
|
||||
{
|
||||
if (nsnull!=mEditor)
|
||||
mEditor->Redo();
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIDOMEvent::VK_TAB:
|
||||
{
|
||||
//XXX: should be from a factory
|
||||
//XXX: should manage the refcount of txn
|
||||
nsString attribute("width");
|
||||
nsString value("400");
|
||||
|
||||
nsString tableTag("TABLE");
|
||||
nsCOMPtr<nsIDOMNode> currentNode;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
|
||||
{
|
||||
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
|
||||
{
|
||||
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
|
||||
mEditor->ExecuteTransaction(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIDOMEvent::VK_SPACE:
|
||||
{
|
||||
//XXX: should be from a factory
|
||||
//XXX: should manage the refcount of txn
|
||||
nsString attribute("height");
|
||||
nsString value("200");
|
||||
|
||||
nsString tableTag("TABLE");
|
||||
nsCOMPtr<nsIDOMNode> currentNode;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
|
||||
{
|
||||
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
|
||||
{
|
||||
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
|
||||
mEditor->ExecuteTransaction(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
/*END interfaces from nsIDOMKeyListener*/
|
||||
private:
|
||||
virtual nsresult GetCharFromKeyCode(PRUint32 aKeyCode, PRBool aIsShift, char *aChar);
|
||||
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsEditFactory.h"
|
||||
#include "nsEditorCID.h"
|
||||
|
||||
#include "nsTransactionManagerCID.h"
|
||||
#include "nsITransactionManager.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
||||
|
@ -41,6 +45,20 @@ static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
|
|||
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
|
||||
static NS_DEFINE_IID(kITransactionManagerIID, NS_ITRANSACTIONMANAGER_IID);
|
||||
static NS_DEFINE_CID(kCTransactionManagerFactoryCID, NS_TRANSACTION_MANAGER_FACTORY_CID);
|
||||
|
||||
|
||||
#ifdef XP_PC
|
||||
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#define TRANSACTION_MANAGER_DLL "TRANSACTION_MANAGER_DLL"
|
||||
#else // XP_UNIX
|
||||
#define TRANSACTION_MANAGER_DLL "libtxmgr.so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//monitor for the editor
|
||||
|
@ -98,26 +116,29 @@ NSRegisterSelf(const char *path)
|
|||
PR_TRUE, PR_TRUE); //this will register the factory with the xpcom dll.
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSUnregisterSelf(const char *path)
|
||||
{
|
||||
return nsRepository::UnregisterFactory(kIEditFactoryIID, path);//this will unregister the factory with the xpcom dll.
|
||||
}
|
||||
|
||||
|
||||
|
||||
//END EXPORTS
|
||||
|
||||
|
||||
//class implementations are in order they are declared in editor.h
|
||||
|
||||
|
||||
static PRBool needsInit=PR_TRUE;
|
||||
nsEditor::nsEditor()
|
||||
{
|
||||
//initialize member variables here
|
||||
NS_INIT_REFCNT();
|
||||
if (PR_TRUE==needsInit)
|
||||
{
|
||||
needsInit=PR_FALSE;
|
||||
nsRepository::RegisterFactory(kCTransactionManagerFactoryCID,
|
||||
TRANSACTION_MANAGER_DLL, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
mTxnMgr = nsnull;
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,6 +231,8 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
|
|||
erP->AddEventListener(mKeyListenerP, kIDOMKeyListenerIID);
|
||||
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
|
||||
|
||||
/* fire up the transaction manager */
|
||||
|
||||
/*
|
||||
now to handle selection
|
||||
*/
|
||||
|
@ -229,6 +252,29 @@ nsEditor::Init(nsIDOMDocument *aDomInterface)
|
|||
return t_result;
|
||||
}
|
||||
*/
|
||||
|
||||
nsISupports *isup = 0;
|
||||
nsresult result;
|
||||
|
||||
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
|
||||
kITransactionManagerIID, &isup);
|
||||
|
||||
if (NS_FAILED(result) || !isup) {
|
||||
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!mTxnMgr) {
|
||||
printf("ERROR: QueryInterface() returned NULL pointer.\n");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -258,6 +304,40 @@ nsEditor::GetProperties(PROPERTIES **)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::SetAttribute(nsIDOMElement *aElement, const nsString& aAttribute, const nsString& aValue)
|
||||
{
|
||||
return aElement->SetDOMAttribute(aAttribute, aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetAttributeValue(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
nsString& aResultValue,
|
||||
PRBool& aResultIsSet)
|
||||
{
|
||||
aResultIsSet=PR_FALSE;
|
||||
nsresult result=NS_OK;
|
||||
if (nsnull!=aElement)
|
||||
{
|
||||
nsIDOMAttr* attNode=nsnull;
|
||||
result = aElement->GetAttributeNode(aAttribute, &attNode);
|
||||
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
|
||||
{
|
||||
attNode->GetSpecified(&aResultIsSet);
|
||||
attNode->GetValue(aResultValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute)
|
||||
{
|
||||
return aElement->RemoveAttribute(aAttribute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::Commit(PRBool aCtrlKey)
|
||||
|
@ -337,6 +417,59 @@ nsEditor::GetCurrentNode(nsIDOMNode ** aNode)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
/* If no node set, get root node */
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
|
||||
if (nsnull==aStartNode)
|
||||
{
|
||||
mDomInterfaceP->GetDocumentElement(getter_AddRefs(element));
|
||||
result = element->QueryInterface(kIDOMNodeIID,getter_AddRefs(node));
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
if (!node)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
node=aStartNode;
|
||||
|
||||
*aResult = nsnull;
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = node->GetFirstChild(getter_AddRefs(childNode));
|
||||
while (childNode)
|
||||
{
|
||||
result = childNode->QueryInterface(kIDOMNodeIID,getter_AddRefs(element));
|
||||
nsString tag;
|
||||
if (NS_SUCCEEDED(result) && (element))
|
||||
{
|
||||
element->GetTagName(tag);
|
||||
if (PR_TRUE==aTag.Equals(tag))
|
||||
{
|
||||
return (childNode->QueryInterface(kIDOMNodeIID,(void **) aResult)); // does the addref
|
||||
}
|
||||
else
|
||||
{
|
||||
nsresult result = GetFirstNodeOfType(childNode, aTag, aResult);
|
||||
if (nsnull!=*aResult)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> xNode;
|
||||
childNode->GetNextSibling(getter_AddRefs(xNode));
|
||||
childNode=xNode;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
|
@ -387,6 +520,46 @@ nsEditor::GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::ExecuteTransaction(nsITransaction *aTxn)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=aTxn)
|
||||
{
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Do(aTxn);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = aTxn->Do();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::Undo()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Undo();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::Redo()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (nsnull!=mTxnMgr)
|
||||
{
|
||||
result = mTxnMgr->Redo();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//END nsEditor Private methods
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "editorInterfaces.h"
|
||||
#include "nsITransactionManager.h"
|
||||
//#include "nsISelection.h"
|
||||
|
||||
|
||||
|
@ -42,6 +43,9 @@ private:
|
|||
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
|
||||
// nsCOMPtr<nsISelection> mSelectionP;
|
||||
//nsCOMPtr<nsITransactionManager> mTxnMgrP;
|
||||
nsITransactionManager * mTxnMgr;
|
||||
|
||||
public:
|
||||
/** The default constructor. This should suffice. the setting of the interfaces is done
|
||||
* after the construction of the editor class.
|
||||
|
@ -66,10 +70,23 @@ public:
|
|||
|
||||
virtual nsresult GetProperties(PROPERTIES **);
|
||||
|
||||
virtual nsresult SetAttribute(nsIDOMElement * aElement,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue);
|
||||
|
||||
virtual nsresult GetAttributeValue(nsIDOMElement * aElement,
|
||||
const nsString& aAttribute,
|
||||
nsString& aResultValue,
|
||||
PRBool& aResultIsSet);
|
||||
|
||||
virtual nsresult RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
|
||||
|
||||
virtual nsresult InsertString(nsString *aString);
|
||||
|
||||
virtual nsresult Commit(PRBool aCtrlKey);
|
||||
|
||||
|
||||
|
||||
/*END nsIEditor interfaces*/
|
||||
|
||||
/*BEGIN nsEditor interfaces*/
|
||||
|
@ -112,6 +129,42 @@ public:
|
|||
*/
|
||||
nsresult GetFirstTextNode(nsIDOMNode *aNode, nsIDOMNode **aRetNode);
|
||||
|
||||
/** GetFirstNodeOfType ADDREFFS and will get the next available node from the passed
|
||||
* in aStartNode parameter of type aTag.
|
||||
* It can also return NS_ERROR_FAILURE if no such nodes are available
|
||||
* @param nsIDOMNode *aStartNode is the node to start looking from
|
||||
* @param nsIAtom *aTag is the type of node we are searching for
|
||||
* @param nsIDOMNode **aResult is the node we found, or nsnull if there is none
|
||||
*/
|
||||
nsresult GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult);
|
||||
|
||||
/** ExecuteTransaction fires a transaction. It is provided here so
|
||||
* clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is used.
|
||||
* Otherwise, the transaction is just executed directly.
|
||||
*
|
||||
* @param aTxn the transaction to execute
|
||||
*/
|
||||
nsresult ExecuteTransaction(nsITransaction *aTxn);
|
||||
|
||||
/** Undo reverses the effects of the last ExecuteTransaction operation
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to undo and the result of
|
||||
* that undo is returned.
|
||||
* Otherwise, the Undo request is ignored.
|
||||
*
|
||||
*/
|
||||
nsresult Undo();
|
||||
|
||||
/** Redo reverses the effects of the last Undo operation
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to redo and the result of
|
||||
* that redo is returned.
|
||||
* Otherwise, the Redo request is ignored.
|
||||
*
|
||||
*/
|
||||
nsresult Redo();
|
||||
|
||||
/*END private methods of nsEditor*/
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
#include "editorInterfaces.h"
|
||||
#include "nsString.h"
|
||||
#include "editor.h"
|
||||
#include "ChangeAttributeTxn.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
|
||||
|
||||
/*
|
||||
* nsEditorKeyListener implementation
|
||||
|
@ -113,25 +117,30 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
|
||||
) {
|
||||
switch(keyCode) {
|
||||
case nsIDOMEvent::VK_BACK:
|
||||
break;
|
||||
case nsIDOMEvent::VK_RETURN:
|
||||
// Need to implement creation of either <P> or <BR> nodes.
|
||||
mEditor->Commit(ctrlKey);
|
||||
break;
|
||||
default:
|
||||
// XXX Replace with x-platform NS-virtkeycode transform.
|
||||
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
|
||||
nsString* key = new nsString();
|
||||
*key += character;
|
||||
if (!isShift) {
|
||||
key->ToLowerCase();
|
||||
PRBool keyProcessed;
|
||||
ProcessShortCutKeys(aKeyEvent, keyProcessed);
|
||||
if (PR_FALSE==keyProcessed)
|
||||
{
|
||||
switch(keyCode) {
|
||||
case nsIDOMEvent::VK_BACK:
|
||||
break;
|
||||
case nsIDOMEvent::VK_RETURN:
|
||||
// Need to implement creation of either <P> or <BR> nodes.
|
||||
mEditor->Commit(ctrlKey);
|
||||
break;
|
||||
default:
|
||||
// XXX Replace with x-platform NS-virtkeycode transform.
|
||||
if (NS_OK == GetCharFromKeyCode(keyCode, isShift, & character)) {
|
||||
nsString* key = new nsString();
|
||||
*key += character;
|
||||
if (!isShift) {
|
||||
key->ToLowerCase();
|
||||
}
|
||||
mEditor->InsertString(key);
|
||||
delete key;
|
||||
}
|
||||
mEditor->InsertString(key);
|
||||
delete key;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +163,90 @@ nsEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
|
||||
{
|
||||
aProcessed=PR_FALSE;
|
||||
PRUint32 keyCode;
|
||||
PRBool isShift;
|
||||
PRBool ctrlKey;
|
||||
|
||||
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetShiftKey(&isShift)) &&
|
||||
NS_SUCCEEDED(aKeyEvent->GetCtrlKey(&ctrlKey))
|
||||
)
|
||||
{
|
||||
// XXX: please please please get these mappings from an external source!
|
||||
switch (keyCode)
|
||||
{
|
||||
// hard-coded undo
|
||||
case nsIDOMEvent::VK_Z:
|
||||
if (PR_TRUE==ctrlKey)
|
||||
{
|
||||
if (nsnull!=mEditor)
|
||||
mEditor->Undo();
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
// hard-coded redo
|
||||
case nsIDOMEvent::VK_Y:
|
||||
if (PR_TRUE==ctrlKey)
|
||||
{
|
||||
if (nsnull!=mEditor)
|
||||
mEditor->Redo();
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIDOMEvent::VK_TAB:
|
||||
{
|
||||
//XXX: should be from a factory
|
||||
//XXX: should manage the refcount of txn
|
||||
nsString attribute("width");
|
||||
nsString value("400");
|
||||
|
||||
nsString tableTag("TABLE");
|
||||
nsCOMPtr<nsIDOMNode> currentNode;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
|
||||
{
|
||||
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
|
||||
{
|
||||
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
|
||||
mEditor->ExecuteTransaction(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIDOMEvent::VK_SPACE:
|
||||
{
|
||||
//XXX: should be from a factory
|
||||
//XXX: should manage the refcount of txn
|
||||
nsString attribute("height");
|
||||
nsString value("200");
|
||||
|
||||
nsString tableTag("TABLE");
|
||||
nsCOMPtr<nsIDOMNode> currentNode;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, tableTag, getter_AddRefs(currentNode))))
|
||||
{
|
||||
if (NS_SUCCEEDED(currentNode->QueryInterface(kIDOMElementIID, getter_AddRefs(element))))
|
||||
{
|
||||
ChangeAttributeTxn *txn = new ChangeAttributeTxn(mEditor, element, attribute, value);
|
||||
mEditor->ExecuteTransaction(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
aProcessed=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
/*END interfaces from nsIDOMKeyListener*/
|
||||
private:
|
||||
virtual nsresult GetCharFromKeyCode(PRUint32 aKeyCode, PRBool aIsShift, char *aChar);
|
||||
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче