Added simple dialogs for insert link and restructured ui source directories

This commit is contained in:
cmanske%netscape.com 1999-04-21 18:53:55 +00:00
Родитель 3ed143ee6b
Коммит 6228e33112
16 изменённых файлов: 806 добавлений и 284 удалений

Просмотреть файл

@ -25,7 +25,7 @@ include $(DEPTH)/config/autoconf.mk
DIRS = public
ifdef MOZ_EDITOR
DIRS += base guimgr txmgr
DIRS += base guimgr txmgr ui
endif
include $(topsrcdir)/config/config.mk

Просмотреть файл

@ -23,9 +23,11 @@
#include "nsIDOMElement.h"
#include "nsIDOMAttr.h"
#include "nsIDOMNode.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMRange.h"
#include "nsIDocument.h"
#include "nsVector.h"
#include "nsIServiceManager.h"
#include "nsEditFactory.h"
#include "nsTextEditFactory.h"
@ -566,6 +568,79 @@ nsEditor::CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
return result;
}
// Objects must be DOM elements
NS_IMETHODIMP
nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
nsresult result=NS_OK;
if (!aDestNode || !aSourceNode)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> destElement = do_QueryInterface(aDestNode);
nsCOMPtr<nsIDOMElement> sourceElement = do_QueryInterface(aSourceNode);
if (!destElement || !sourceElement)
return NS_ERROR_NO_INTERFACE;
nsAutoString name;
nsAutoString value;
nsCOMPtr<nsIDOMNamedNodeMap> sourceAttributes;
sourceElement->GetAttributes(getter_AddRefs(sourceAttributes));
nsCOMPtr<nsIDOMNamedNodeMap> destAttributes;
destElement->GetAttributes(getter_AddRefs(destAttributes));
if (!sourceAttributes || !destAttributes)
return NS_ERROR_FAILURE;
PRUint32 sourceCount;
sourceAttributes->GetLength(&sourceCount);
PRUint32 i, destCount;
destAttributes->GetLength(&destCount);
nsIDOMNode* attrNode;
// Clear existing attributes
for (i = 0; i < destCount; i++)
{
if( NS_SUCCEEDED(destAttributes->Item(i, &attrNode)) && attrNode)
{
nsCOMPtr<nsIDOMAttr> destAttribute = do_QueryInterface(attrNode);
if (destAttribute)
{
nsCOMPtr<nsIDOMAttr> resultAttribute;
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
// Is the resultAttribute deleted automagically?
}
}
}
// Set just the attributes that the source element has
for (i = 0; i < sourceCount; i++)
{
if( NS_SUCCEEDED(sourceAttributes->Item(i, &attrNode)) && attrNode)
{
nsCOMPtr<nsIDOMAttr> sourceAttribute = do_QueryInterface(attrNode);
if (sourceAttribute)
{
nsString sourceAttrName;
if (NS_SUCCEEDED(sourceAttribute->GetName(sourceAttrName)))
{
nsString sourceAttrValue;
if (NS_SUCCEEDED(sourceAttribute->GetValue(sourceAttrValue)) &&
sourceAttrValue != "")
{
destElement->SetAttribute(sourceAttrName, sourceAttrValue);
} else {
// Do we ever get here?
destElement->RemoveAttribute(sourceAttrName);
#if DEBUG_cmanske
printf("Attribute in NamedNodeMap has empty value in nsEditor::CopyAttributes()\n");
#endif
}
}
}
}
}
return result;
}
NS_IMETHODIMP
nsEditor::InsertBreak()
{
@ -2132,7 +2207,6 @@ nsEditor::DebugDumpContent() const
return NS_OK;
}
//END nsEditor Private methods
/* ----- TEST METHODS ----- */

Просмотреть файл

@ -108,6 +108,10 @@ public:
NS_IMETHOD RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
//NOTE: Most callers are dealing with Nodes,
// but these objects must supports nsIDOMElement
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
NS_IMETHOD CreateNode(const nsString& aTag,
nsIDOMNode * aParent,
PRInt32 aPosition,

Просмотреть файл

@ -30,7 +30,11 @@
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIEnumerator.h"
#include "nsIContent.h"
#include "nsIContentIterator.h"
#include "nsEditorCID.h"
#include "nsLayoutCID.h"
#include "nsIDOMRange.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
@ -49,6 +53,8 @@ static NS_DEFINE_IID(kITextEditorIID, NS_ITEXTEDITOR_IID);
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
static NS_DEFINE_IID(kIHTMLEditorIID, NS_IHTMLEDITOR_IID);
static NS_DEFINE_CID(kHTMLEditorCID, NS_HTMLEDITOR_CID);
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
#ifdef NS_DEBUG
static PRBool gNoisy = PR_FALSE;
@ -342,6 +348,12 @@ NS_IMETHODIMP nsHTMLEditor::OutputHTML(nsString& aOutputString)
return nsTextEditor::OutputHTML(aOutputString);
}
NS_IMETHODIMP
nsHTMLEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
return nsTextEditor::CopyAttributes(aDestNode, aSourceNode);
}
//================================================================
// HTML Editor methods
//
@ -745,63 +757,239 @@ nsHTMLEditor::InsertImage(nsString& aURL,
nsString& aAlignment)
{
nsresult res;
(void)nsEditor::BeginTransaction();
nsCOMPtr<nsIDOMNode> newNode;
nsCOMPtr<nsIDOMDocument>doc;
res = GetDocument(getter_AddRefs(doc));
if (NS_SUCCEEDED(res))
nsAutoString tag("IMG");
res = nsEditor::DeleteSelectionAndCreateNode(tag, getter_AddRefs(newNode));
if (!NS_SUCCEEDED(res) || !newNode)
{
nsAutoString tag("IMG");
nsCOMPtr<nsIDOMElement>newElement;
res = doc->CreateElement(tag, getter_AddRefs(newElement));
if (NS_SUCCEEDED(res) && newElement)
{
newNode = do_QueryInterface(newElement);
nsCOMPtr<nsIDOMHTMLImageElement> image (do_QueryInterface(newNode));
// Set all the attributes now, before we insert into the tree:
if (image)
{
if (NS_SUCCEEDED(res = image->SetSrc(aURL)))
if (NS_SUCCEEDED(res = image->SetWidth(aWidth)))
if (NS_SUCCEEDED(res = image->SetHeight(aHeight)))
if (NS_SUCCEEDED(res = image->SetAlt(aAlt)))
if (NS_SUCCEEDED(res = image->SetBorder(aBorder)))
if (NS_SUCCEEDED(res = image->SetAlign(aAlignment)))
if (NS_SUCCEEDED(res = image->SetHspace(aHspace)))
if (NS_SUCCEEDED(res = image->SetVspace(aVspace)))
;
}
}
}
// If any of these failed, then don't insert the new node into the tree
if (!NS_SUCCEEDED(res))
{
#ifdef DEBUG_akkana
printf("Some failure creating the new image node\n");
#endif
(void)nsEditor::EndTransaction();
return res;
}
//
// Now we're ready to insert the new image node:
// Starting now, don't return without ending the transaction!
//
(void)nsEditor::BeginTransaction();
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 offsetOfNewNode;
res = nsEditor::DeleteSelectionAndPrepareToCreateNode(parentNode,
offsetOfNewNode);
if (NS_SUCCEEDED(res))
nsCOMPtr<nsIDOMHTMLImageElement> image (do_QueryInterface(newNode));
if (!image)
{
// and insert it into the right place in the tree:
res = InsertNode(newNode, parentNode, offsetOfNewNode);
#ifdef DEBUG_akkana
printf("Not an image element\n");
#endif
(void)nsEditor::EndTransaction();
return NS_NOINTERFACE;
}
// Can't return from any of these intermediates
// because then we won't hit the EndTransaction()
if (NS_SUCCEEDED(res = image->SetSrc(aURL)))
if (NS_SUCCEEDED(res = image->SetWidth(aWidth)))
if (NS_SUCCEEDED(res = image->SetHeight(aHeight)))
if (NS_SUCCEEDED(res = image->SetAlt(aAlt)))
if (NS_SUCCEEDED(res = image->SetBorder(aBorder)))
if (NS_SUCCEEDED(res = image->SetAlign(aAlignment)))
if (NS_SUCCEEDED(res = image->SetHspace(aHspace)))
if (NS_SUCCEEDED(res = image->SetVspace(aVspace)))
;
(void)nsEditor::EndTransaction(); // don't return this result!
return res;
}
// This should replace InsertLink and InsertImage once it is working
NS_IMETHODIMP
nsHTMLEditor::GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn)
{
if (!aReturn )
return NS_ERROR_NULL_POINTER;
*aReturn = nsnull;
nsAutoString TagName = aTagName;
TagName.ToLowerCase();
//Note that this doesn't need to go through the transaction system
nsresult result=NS_ERROR_NOT_INITIALIZED;
PRBool first=PR_TRUE;
nsCOMPtr<nsIDOMSelection>selection;
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (!NS_SUCCEEDED(result) || !selection)
return result;
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
nsCOMPtr<nsIDOMElement> selectedElement;
PRBool bNodeFound = PR_FALSE;
// Don't bother to examine selection if it is collapsed
if (!isCollapsed)
{
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(selection);
if (enumerator)
{
enumerator->First();
nsISupports *currentItem;
result = enumerator->CurrentItem(&currentItem);
if ((NS_SUCCEEDED(result)) && currentItem)
{
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
nsCOMPtr<nsIContentIterator> iter;
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
kIContentIteratorIID,
getter_AddRefs(iter));
if ((NS_SUCCEEDED(result)) && iter)
{
iter->Init(range);
// loop through the content iterator for each content node
nsCOMPtr<nsIContent> content;
result = iter->CurrentNode(getter_AddRefs(content));
PRBool bOtherNodeTypeFound = PR_FALSE;
while (NS_COMFALSE == iter->IsDone())
{
// Query interface to cast nsIContent to nsIDOMNode
// then get tagType to compare to aTagName
// Clone node of each desired type and append it to the aDomFrag
selectedElement = do_QueryInterface(content);
if (selectedElement)
{
// If we already found a node, then we have another element,
// so don't return an element
if (bNodeFound)
{
bNodeFound;
break;
}
nsAutoString domTagName;
selectedElement->GetNodeName(domTagName);
// The "A" tag is a pain,
// used for both link(href is set) and "Named Anchor"
if (aTagName == "HREF" || (aTagName == "ANCHOR"))
{
// We could use GetAttribute, but might as well use anchor element directly
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(selectedElement);
if (anchor)
{
nsString tmpText;
if( aTagName == "HREF")
{
if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && tmpText && tmpText != "")
bNodeFound = PR_TRUE;
} else if (aTagName == "ANCHOR")
{
if (NS_SUCCEEDED(anchor->GetName(tmpText)) && tmpText && tmpText != "")
bNodeFound = PR_TRUE;
}
}
} else if (aTagName == domTagName) { // All other tag names are handled here
bNodeFound = PR_TRUE;
}
if (!bNodeFound)
{
// Check if node we have is really part of the selection???
break;
}
}
}
if (!bNodeFound)
printf("No nodes of tag name = %s were found in selection\n", aTagName);
}
} else {
// Should never get here?
isCollapsed = PR_TRUE;
printf("isCollapsed was FALSE, but no elements found in selection\n");
}
} else {
printf("Could not create enumerator for GetSelectionProperties\n");
}
}
if (bNodeFound)
{
*aReturn = selectedElement;
}
return result;
}
NS_IMETHODIMP
nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement** aReturn)
{
nsresult result=NS_ERROR_NOT_INITIALIZED;
if (aReturn)
*aReturn = nsnull;
if (aTagName == "" || !aReturn)
return NS_ERROR_NULL_POINTER;
nsAutoString TagName = aTagName;
TagName.ToLowerCase();
nsAutoString realTagName;
PRBool isHREF = (TagName == "href");
PRBool isAnchor = (TagName == "anchor");
if (isHREF || isAnchor)
{
realTagName = "a";
} else {
realTagName = TagName;
}
//We don't use editor's CreateElement because we don't want to
// go through the transaction system
nsCOMPtr<nsIDOMElement>newElement;
result = mDoc->CreateElement(realTagName, getter_AddRefs(newElement));
if (!NS_SUCCEEDED(result) || !newElement)
return NS_ERROR_FAILURE;
// Set default values for new elements
// SHOULD THIS BE PUT IN "RULES" SYSTEM OR
// ATTRIBUTES SAVED IN PREFS?
if (isAnchor)
{
// TODO: Get the text of the selection and build a suggested Name
// Replace spaces with "_"
}
// ADD OTHER DEFAULT ATTRIBUTES HERE
if (NS_SUCCEEDED(result))
{
*aReturn = newElement; //do_QueryInterface(newElement);
}
return result;
}
NS_IMETHODIMP
nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, nsIDOMElement** aReturn)
{
nsresult result=NS_ERROR_NOT_INITIALIZED;
if (aReturn)
*aReturn = nsnull;
if (!aElement || !aReturn)
return NS_ERROR_NULL_POINTER;
result = nsEditor::BeginTransaction();
if (NS_FAILED(result))
return result;
nsCOMPtr<nsIDOMNode> parentSelectedNode;
PRInt32 offsetOfNewNode;
DeleteSelectionAndPrepareToCreateNode(parentSelectedNode, offsetOfNewNode);
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode> newNode = do_QueryInterface(aElement);
result = InsertNode(aElement, parentSelectedNode, offsetOfNewNode);
}
(void)nsEditor::EndTransaction();
return result;
}

Просмотреть файл

@ -60,6 +60,7 @@ public:
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
NS_IMETHOD InsertText(const nsString& aStringToInsert);
NS_IMETHOD InsertBreak();
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
// Transaction control
NS_IMETHOD EnableUndo(PRBool aEnable);
@ -70,7 +71,7 @@ public:
NS_IMETHOD BeginTransaction();
NS_IMETHOD EndTransaction();
// Selection and navigation -- exposed here for convenience
// Selection and navigation
NS_IMETHOD MoveSelectionUp(nsIAtom *aIncrement, PRBool aExtendSelection);
NS_IMETHOD MoveSelectionDown(nsIAtom *aIncrement, PRBool aExtendSelection);
NS_IMETHOD MoveSelectionNext(nsIAtom *aIncrement, PRBool aExtendSelection);
@ -92,7 +93,8 @@ public:
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
//=====================================
// End of methods implemented in nsEditor
//=============================================================
// HTML Editing methods
NS_IMETHOD AddBlockParent(nsString& aParentTag);
NS_IMETHOD RemoveBlockParent();
@ -104,6 +106,11 @@ public:
nsString& aBorder,
nsString& aAlt, nsString& aAlignment);
// This should replace InsertLink and InsertImage once it is working
NS_IMETHOD GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, nsIDOMElement** aReturn);
// Table Editing (implemented in EditTable.cpp)
NS_IMETHOD CreateTxnForInsertTable(const nsIDOMElement *aTableNode, InsertTableTxn ** aTxn);
NS_IMETHOD GetColIndexForCell(nsIDOMNode *aCellNode, PRInt32 &aCellIndex);

Просмотреть файл

@ -2341,3 +2341,10 @@ nsTextEditor::SetTypeInStateForProperty(TypeInState &aTypeInState,
else { return NS_ERROR_FAILURE; }
return NS_OK;
}
// This file should be rearranged to put all methods that simply call nsEditor together
NS_IMETHODIMP
nsTextEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
return nsEditor::CopyAttributes(aDestNode, aSourceNode);
}

Просмотреть файл

@ -52,6 +52,8 @@ public:
//Initialization
NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell);
//============================================================================
// Methods that are duplicates of nsEditor -- exposed here for convenience
// Editing Operations
NS_IMETHOD SetTextProperty(nsIAtom *aProperty,
const nsString *aAttribute,
@ -64,6 +66,7 @@ public:
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
NS_IMETHOD InsertText(const nsString& aStringToInsert);
NS_IMETHOD InsertBreak();
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
// Transaction control
NS_IMETHOD EnableUndo(PRBool aEnable);
@ -96,6 +99,8 @@ public:
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
// End of methods implemented in nsEditor
//=============================================================
protected:

Просмотреть файл

@ -1,21 +1,18 @@
/* XUL ELEMENTS */
window, WINDOW {
display: block;
width: 100%;
/* width: 100%; */
background: silver;
background-color: #CCCCCC; /* not working on Macintosh */
padding: 5px;
font-family: Sans-Serif;
font-size: 8pt;
font-size: 10pt;
}
/* Defeat the default behavior of borderless until rollover */
button { border: 2px outset }
/* values = margin, padding. Padding doesn't work yet */
checkbox, CHECKBOX { margin: 5px 3px }
radio, RADIO { margin: 5px 3px }
radio, RADIO, checkbox, CHECKBOX {
margin-top: 5px;
margin-right: 3px;
}
tree, TREE {
display: table;
@ -30,23 +27,25 @@ tree, TREE {
/* Force all rows to line up cell contents at the top */
tr, TR { vertical-align: top }
/* FOR DEBUG PURPOSE -- SHOW CELL BORDER */
td, TD { border-width: 0px; border-style: inset }
/* FOR DEBUG PURPOSE -- SHOW CELL BORDER
td, TD { border-width: 1px; padding: 0px; border-style: outset }
table, TABLE { border-width: 1px; padding: 0px; border-style: inset }
*/
table, TABLE { border-width: 0px }
p, br, td {
font-family: Sans-Serif;
font-size: 8pt;
margin-top: 4px;
margin-bottom: 4px
font-size: 10pt;
margin: 0px;
}
fieldset, FIELDSET {
border-width: 3px;
border-width: 2px;
border-style: groove;
padding: 3px;
margin: 5px;
padding: 2px;
margin: 0px;
text-align: left;
}
@ -54,70 +53,30 @@ legend, LEGEND {
font-family: Sans-Serif;
font-size: 10pt;
border-width: 0;
width: 100%
height: 100%
/* BUG??? align can't be set - must use <legend align="left"> in the HTML */
text-align: left;
}
/* CLASSES */
[CLASS~=GrooveBorder] { border: 2px groove; padding: 3px }
[CLASS~=RidgeBorder] { border: 2px ridge; padding: 3px }
/* CLASSES */
[CLASS~=GrooveBorder] { border: 2px groove; padding: 3px }
[CLASS~=OutsetBorder] { border: 1px outset; padding: 3px }
[CLASS~=RidgeBorder] { border: 2px ridge; padding: 3px }
[CLASS~=InsetBorder] { border: 1px inset; padding: 3px }
[CLASS~=OutsetBorder] { border: 1px outset; padding: 3px }
[CLASS~=InsetBorder] { border: 1px inset; padding: 3px }
/*
3/31/99 These don't work because of a bug HYATT knows about
.GrooveBorder { border: 2px groove; padding: 3px }
.RidgeBorder { border: 2px ridge; padding: 3px }
.OutsetBorder { border: 1px outset; padding: 3px }
.InsetBorder { border: 1px inset; padding: 3px }
.tableCenterAlign {
vertical-align: middle;
}
.genericbutton {
width: 80px;
height: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
/* IDs only one button per dialog */
#okbutton {
width: 80px;
height: 20px;
left: 385px;
top: 320px;
align: right;
font-style: normal; position: absolute; visibility: visible; z-index: auto
}
#cancelbutton {
width: 80px;
height: 20px;
left: 295px;
top: 320px;
align: right;
font-style: normal; position: absolute; visibility: visible; z-index: auto
}
#applybutton {
width: 80px;
height: 20px;
left: 205px;
top: 320px;
align: right; font-style: normal; position: absolute; visibility: visible; z-index: auto
}
#helpbutton {
width: 80px;
height: 20px;
left: 10px;
top: 320px;
align : left;
font-style: normal; position: absolute; visibility: visible; z-index: auto
}
#extrahtmlbutton {
width: 80px;
height: 20px;
align: right;
left: 385px;
font-style: normal; position: absolute; visibility: visible; z-index: auto
}
*/

Просмотреть файл

@ -23,9 +23,11 @@
#include "nsIDOMElement.h"
#include "nsIDOMAttr.h"
#include "nsIDOMNode.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMRange.h"
#include "nsIDocument.h"
#include "nsVector.h"
#include "nsIServiceManager.h"
#include "nsEditFactory.h"
#include "nsTextEditFactory.h"
@ -566,6 +568,79 @@ nsEditor::CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
return result;
}
// Objects must be DOM elements
NS_IMETHODIMP
nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
nsresult result=NS_OK;
if (!aDestNode || !aSourceNode)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> destElement = do_QueryInterface(aDestNode);
nsCOMPtr<nsIDOMElement> sourceElement = do_QueryInterface(aSourceNode);
if (!destElement || !sourceElement)
return NS_ERROR_NO_INTERFACE;
nsAutoString name;
nsAutoString value;
nsCOMPtr<nsIDOMNamedNodeMap> sourceAttributes;
sourceElement->GetAttributes(getter_AddRefs(sourceAttributes));
nsCOMPtr<nsIDOMNamedNodeMap> destAttributes;
destElement->GetAttributes(getter_AddRefs(destAttributes));
if (!sourceAttributes || !destAttributes)
return NS_ERROR_FAILURE;
PRUint32 sourceCount;
sourceAttributes->GetLength(&sourceCount);
PRUint32 i, destCount;
destAttributes->GetLength(&destCount);
nsIDOMNode* attrNode;
// Clear existing attributes
for (i = 0; i < destCount; i++)
{
if( NS_SUCCEEDED(destAttributes->Item(i, &attrNode)) && attrNode)
{
nsCOMPtr<nsIDOMAttr> destAttribute = do_QueryInterface(attrNode);
if (destAttribute)
{
nsCOMPtr<nsIDOMAttr> resultAttribute;
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
// Is the resultAttribute deleted automagically?
}
}
}
// Set just the attributes that the source element has
for (i = 0; i < sourceCount; i++)
{
if( NS_SUCCEEDED(sourceAttributes->Item(i, &attrNode)) && attrNode)
{
nsCOMPtr<nsIDOMAttr> sourceAttribute = do_QueryInterface(attrNode);
if (sourceAttribute)
{
nsString sourceAttrName;
if (NS_SUCCEEDED(sourceAttribute->GetName(sourceAttrName)))
{
nsString sourceAttrValue;
if (NS_SUCCEEDED(sourceAttribute->GetValue(sourceAttrValue)) &&
sourceAttrValue != "")
{
destElement->SetAttribute(sourceAttrName, sourceAttrValue);
} else {
// Do we ever get here?
destElement->RemoveAttribute(sourceAttrName);
#if DEBUG_cmanske
printf("Attribute in NamedNodeMap has empty value in nsEditor::CopyAttributes()\n");
#endif
}
}
}
}
}
return result;
}
NS_IMETHODIMP
nsEditor::InsertBreak()
{
@ -2132,7 +2207,6 @@ nsEditor::DebugDumpContent() const
return NS_OK;
}
//END nsEditor Private methods
/* ----- TEST METHODS ----- */

Просмотреть файл

@ -108,6 +108,10 @@ public:
NS_IMETHOD RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
//NOTE: Most callers are dealing with Nodes,
// but these objects must supports nsIDOMElement
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
NS_IMETHOD CreateNode(const nsString& aTag,
nsIDOMNode * aParent,
PRInt32 aPosition,

Просмотреть файл

@ -30,7 +30,11 @@
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIEnumerator.h"
#include "nsIContent.h"
#include "nsIContentIterator.h"
#include "nsEditorCID.h"
#include "nsLayoutCID.h"
#include "nsIDOMRange.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
@ -49,6 +53,8 @@ static NS_DEFINE_IID(kITextEditorIID, NS_ITEXTEDITOR_IID);
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
static NS_DEFINE_IID(kIHTMLEditorIID, NS_IHTMLEDITOR_IID);
static NS_DEFINE_CID(kHTMLEditorCID, NS_HTMLEDITOR_CID);
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
#ifdef NS_DEBUG
static PRBool gNoisy = PR_FALSE;
@ -342,6 +348,12 @@ NS_IMETHODIMP nsHTMLEditor::OutputHTML(nsString& aOutputString)
return nsTextEditor::OutputHTML(aOutputString);
}
NS_IMETHODIMP
nsHTMLEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
return nsTextEditor::CopyAttributes(aDestNode, aSourceNode);
}
//================================================================
// HTML Editor methods
//
@ -745,63 +757,239 @@ nsHTMLEditor::InsertImage(nsString& aURL,
nsString& aAlignment)
{
nsresult res;
(void)nsEditor::BeginTransaction();
nsCOMPtr<nsIDOMNode> newNode;
nsCOMPtr<nsIDOMDocument>doc;
res = GetDocument(getter_AddRefs(doc));
if (NS_SUCCEEDED(res))
nsAutoString tag("IMG");
res = nsEditor::DeleteSelectionAndCreateNode(tag, getter_AddRefs(newNode));
if (!NS_SUCCEEDED(res) || !newNode)
{
nsAutoString tag("IMG");
nsCOMPtr<nsIDOMElement>newElement;
res = doc->CreateElement(tag, getter_AddRefs(newElement));
if (NS_SUCCEEDED(res) && newElement)
{
newNode = do_QueryInterface(newElement);
nsCOMPtr<nsIDOMHTMLImageElement> image (do_QueryInterface(newNode));
// Set all the attributes now, before we insert into the tree:
if (image)
{
if (NS_SUCCEEDED(res = image->SetSrc(aURL)))
if (NS_SUCCEEDED(res = image->SetWidth(aWidth)))
if (NS_SUCCEEDED(res = image->SetHeight(aHeight)))
if (NS_SUCCEEDED(res = image->SetAlt(aAlt)))
if (NS_SUCCEEDED(res = image->SetBorder(aBorder)))
if (NS_SUCCEEDED(res = image->SetAlign(aAlignment)))
if (NS_SUCCEEDED(res = image->SetHspace(aHspace)))
if (NS_SUCCEEDED(res = image->SetVspace(aVspace)))
;
}
}
}
// If any of these failed, then don't insert the new node into the tree
if (!NS_SUCCEEDED(res))
{
#ifdef DEBUG_akkana
printf("Some failure creating the new image node\n");
#endif
(void)nsEditor::EndTransaction();
return res;
}
//
// Now we're ready to insert the new image node:
// Starting now, don't return without ending the transaction!
//
(void)nsEditor::BeginTransaction();
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 offsetOfNewNode;
res = nsEditor::DeleteSelectionAndPrepareToCreateNode(parentNode,
offsetOfNewNode);
if (NS_SUCCEEDED(res))
nsCOMPtr<nsIDOMHTMLImageElement> image (do_QueryInterface(newNode));
if (!image)
{
// and insert it into the right place in the tree:
res = InsertNode(newNode, parentNode, offsetOfNewNode);
#ifdef DEBUG_akkana
printf("Not an image element\n");
#endif
(void)nsEditor::EndTransaction();
return NS_NOINTERFACE;
}
// Can't return from any of these intermediates
// because then we won't hit the EndTransaction()
if (NS_SUCCEEDED(res = image->SetSrc(aURL)))
if (NS_SUCCEEDED(res = image->SetWidth(aWidth)))
if (NS_SUCCEEDED(res = image->SetHeight(aHeight)))
if (NS_SUCCEEDED(res = image->SetAlt(aAlt)))
if (NS_SUCCEEDED(res = image->SetBorder(aBorder)))
if (NS_SUCCEEDED(res = image->SetAlign(aAlignment)))
if (NS_SUCCEEDED(res = image->SetHspace(aHspace)))
if (NS_SUCCEEDED(res = image->SetVspace(aVspace)))
;
(void)nsEditor::EndTransaction(); // don't return this result!
return res;
}
// This should replace InsertLink and InsertImage once it is working
NS_IMETHODIMP
nsHTMLEditor::GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn)
{
if (!aReturn )
return NS_ERROR_NULL_POINTER;
*aReturn = nsnull;
nsAutoString TagName = aTagName;
TagName.ToLowerCase();
//Note that this doesn't need to go through the transaction system
nsresult result=NS_ERROR_NOT_INITIALIZED;
PRBool first=PR_TRUE;
nsCOMPtr<nsIDOMSelection>selection;
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (!NS_SUCCEEDED(result) || !selection)
return result;
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
nsCOMPtr<nsIDOMElement> selectedElement;
PRBool bNodeFound = PR_FALSE;
// Don't bother to examine selection if it is collapsed
if (!isCollapsed)
{
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(selection);
if (enumerator)
{
enumerator->First();
nsISupports *currentItem;
result = enumerator->CurrentItem(&currentItem);
if ((NS_SUCCEEDED(result)) && currentItem)
{
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
nsCOMPtr<nsIContentIterator> iter;
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
kIContentIteratorIID,
getter_AddRefs(iter));
if ((NS_SUCCEEDED(result)) && iter)
{
iter->Init(range);
// loop through the content iterator for each content node
nsCOMPtr<nsIContent> content;
result = iter->CurrentNode(getter_AddRefs(content));
PRBool bOtherNodeTypeFound = PR_FALSE;
while (NS_COMFALSE == iter->IsDone())
{
// Query interface to cast nsIContent to nsIDOMNode
// then get tagType to compare to aTagName
// Clone node of each desired type and append it to the aDomFrag
selectedElement = do_QueryInterface(content);
if (selectedElement)
{
// If we already found a node, then we have another element,
// so don't return an element
if (bNodeFound)
{
bNodeFound;
break;
}
nsAutoString domTagName;
selectedElement->GetNodeName(domTagName);
// The "A" tag is a pain,
// used for both link(href is set) and "Named Anchor"
if (aTagName == "HREF" || (aTagName == "ANCHOR"))
{
// We could use GetAttribute, but might as well use anchor element directly
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(selectedElement);
if (anchor)
{
nsString tmpText;
if( aTagName == "HREF")
{
if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && tmpText && tmpText != "")
bNodeFound = PR_TRUE;
} else if (aTagName == "ANCHOR")
{
if (NS_SUCCEEDED(anchor->GetName(tmpText)) && tmpText && tmpText != "")
bNodeFound = PR_TRUE;
}
}
} else if (aTagName == domTagName) { // All other tag names are handled here
bNodeFound = PR_TRUE;
}
if (!bNodeFound)
{
// Check if node we have is really part of the selection???
break;
}
}
}
if (!bNodeFound)
printf("No nodes of tag name = %s were found in selection\n", aTagName);
}
} else {
// Should never get here?
isCollapsed = PR_TRUE;
printf("isCollapsed was FALSE, but no elements found in selection\n");
}
} else {
printf("Could not create enumerator for GetSelectionProperties\n");
}
}
if (bNodeFound)
{
*aReturn = selectedElement;
}
return result;
}
NS_IMETHODIMP
nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement** aReturn)
{
nsresult result=NS_ERROR_NOT_INITIALIZED;
if (aReturn)
*aReturn = nsnull;
if (aTagName == "" || !aReturn)
return NS_ERROR_NULL_POINTER;
nsAutoString TagName = aTagName;
TagName.ToLowerCase();
nsAutoString realTagName;
PRBool isHREF = (TagName == "href");
PRBool isAnchor = (TagName == "anchor");
if (isHREF || isAnchor)
{
realTagName = "a";
} else {
realTagName = TagName;
}
//We don't use editor's CreateElement because we don't want to
// go through the transaction system
nsCOMPtr<nsIDOMElement>newElement;
result = mDoc->CreateElement(realTagName, getter_AddRefs(newElement));
if (!NS_SUCCEEDED(result) || !newElement)
return NS_ERROR_FAILURE;
// Set default values for new elements
// SHOULD THIS BE PUT IN "RULES" SYSTEM OR
// ATTRIBUTES SAVED IN PREFS?
if (isAnchor)
{
// TODO: Get the text of the selection and build a suggested Name
// Replace spaces with "_"
}
// ADD OTHER DEFAULT ATTRIBUTES HERE
if (NS_SUCCEEDED(result))
{
*aReturn = newElement; //do_QueryInterface(newElement);
}
return result;
}
NS_IMETHODIMP
nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, nsIDOMElement** aReturn)
{
nsresult result=NS_ERROR_NOT_INITIALIZED;
if (aReturn)
*aReturn = nsnull;
if (!aElement || !aReturn)
return NS_ERROR_NULL_POINTER;
result = nsEditor::BeginTransaction();
if (NS_FAILED(result))
return result;
nsCOMPtr<nsIDOMNode> parentSelectedNode;
PRInt32 offsetOfNewNode;
DeleteSelectionAndPrepareToCreateNode(parentSelectedNode, offsetOfNewNode);
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode> newNode = do_QueryInterface(aElement);
result = InsertNode(aElement, parentSelectedNode, offsetOfNewNode);
}
(void)nsEditor::EndTransaction();
return result;
}

Просмотреть файл

@ -60,6 +60,7 @@ public:
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
NS_IMETHOD InsertText(const nsString& aStringToInsert);
NS_IMETHOD InsertBreak();
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
// Transaction control
NS_IMETHOD EnableUndo(PRBool aEnable);
@ -70,7 +71,7 @@ public:
NS_IMETHOD BeginTransaction();
NS_IMETHOD EndTransaction();
// Selection and navigation -- exposed here for convenience
// Selection and navigation
NS_IMETHOD MoveSelectionUp(nsIAtom *aIncrement, PRBool aExtendSelection);
NS_IMETHOD MoveSelectionDown(nsIAtom *aIncrement, PRBool aExtendSelection);
NS_IMETHOD MoveSelectionNext(nsIAtom *aIncrement, PRBool aExtendSelection);
@ -92,7 +93,8 @@ public:
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
//=====================================
// End of methods implemented in nsEditor
//=============================================================
// HTML Editing methods
NS_IMETHOD AddBlockParent(nsString& aParentTag);
NS_IMETHOD RemoveBlockParent();
@ -104,6 +106,11 @@ public:
nsString& aBorder,
nsString& aAlt, nsString& aAlignment);
// This should replace InsertLink and InsertImage once it is working
NS_IMETHOD GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, nsIDOMElement** aReturn);
// Table Editing (implemented in EditTable.cpp)
NS_IMETHOD CreateTxnForInsertTable(const nsIDOMElement *aTableNode, InsertTableTxn ** aTxn);
NS_IMETHOD GetColIndexForCell(nsIDOMNode *aCellNode, PRInt32 &aCellIndex);

Просмотреть файл

@ -21,7 +21,7 @@ IGNORE_MANIFEST=1
!if defined(DISABLE_EDITOR)
DIRS= public
!else
DIRS= public base guimgr txmgr
DIRS= public base guimgr txmgr ui
!endif
include <$(DEPTH)\config\rules.mak>

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIEditor.h"
#include "nscore.h"
#include "nsIDOMDocumentFragment.h"
class nsIEditorCallback;
class nsISupportsArray;
@ -115,6 +116,11 @@ public:
nsString& aBorder,
nsString& aAlt, nsString& aAlignment)=0;
// This should replace InsertLink and InsertImage once it is working
NS_IMETHOD GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn)=0;
NS_IMETHOD CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement** aReturn)=0;
NS_IMETHOD InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, nsIDOMElement** aReturn)=0;
// Table editing Methods
NS_IMETHOD InsertTable()=0;
NS_IMETHOD InsertTableCell(PRInt32 aNumber, PRBool aAfter)=0;

Просмотреть файл

@ -0,0 +1,106 @@
var appCore;
var toolkitCore;
var editElement = null;
var insertNew = true;
// NOTE: Use "HREF" instead of "A" to distinguish from Named Anchor
// The returned nodes will have the "A" tagName
var tagName = "HREF";
// dialog initialization code
function Startup() {
dump("Doing Startup...\n");
toolkitCore = GetToolkitCore();
if(!toolkitCore) {
dump("toolkitCore not found!!! And we can't close the dialog!\n");
}
// NEVER create an appcore here - we must find parent editor's
appCore = XPAppCoresManager.Find("EditorAppCoreHTML");
if(!appCore || !toolkitCore) {
dump("EditorAppCore not found!!!\n");
toolkitCore.CloseWindow();
}
dump("EditorAppCore found for Link Properties dialog\n");
// Get a single selected element and edit its properites
editElement = appCore.getSelectedElement(tagName);
if (editElement) {
// We found an element and don't need to insert it
insertNew = false;
} else {
// We don't have an element selected,
// so create one with default attributes
dump("Element not selected - calling createElementWithDefaults\n");
editElement = appCore.createElementWithDefaults(tagName);
}
if(!editElement)
{
dump("Failed to get selected element or create a new one!\n");
toolkitCore.CloseWindow(window);
}
dump("GetSelectedElement...\n");
hrefInput = document.getElementById("textHREF");
// Set the input element value to current HREF
if (hrefInput)
{
dump("Setting HREF editbox value\n");
hrefInput.value = editNode.href;
}
}
function applyChanges() {
// Set the input element value to current HREF
hrefInput = document.getElementById("textHREF");
if (hrefInput)
{
dump("Copying edit field HREF value to node attribute\n");
editElement.setAttribute("href",hrefInput.value);
}
// Get text to use for a new link
if (insertNew)
{
textLink = document.getElementById("textLink");
if (textLink)
{
// Append the link text as the last child node
// of the docFrag
textNode = appCore.editorDocument.createTextNode(textLink.value);
if (textNode)
{
editElement.appendChild(textNode);
dump("Text for new link appended to HREF node\n");
newElement = appCore.insertElement(editElement, true);
if (newElement != editElement)
{
dump("Returned element from insertElement is different from orginal element.\n");
}
}
}
// Once inserted, we can modify properties, but don't insert again
insertNew = false;
}
}
function onOK() {
applyChanges();
toolkitCore.CloseWindow(window);
}
function onCancel() {
dump("Calling CloseWindow...\n");
toolkitCore.CloseWindow(window);
}
function GetToolkitCore() {
var toolkitCore = XPAppCoresManager.Find("ToolkitCore");
if (!toolkitCore) {
toolkitCore = new ToolkitCore();
if (toolkitCore)
toolkitCore.Init("ToolkitCore");
}
return toolkitCore;
}

Просмотреть файл

@ -1,120 +1,13 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
<?xml-stylesheet href="chrome://editordialogs/skin/EditorDialog.css" type="text/css"?>
<?xml-stylesheet href="chrome://editordlgs/skin/EditorDialog.css" type="text/css"?>
<!DOCTYPE window>
<xul:window width="380" height="240"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:xul ="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload = "Startup()">
<html:script>
var appCore;
var toolkitCore;
var editElement = null;
var insertNew = true;
// NOTE: Use "HREF" instead of "A" to distinguish from Named Anchor
// The returned nodes will have the "A" tagName
var tagName = "HREF";
// dialog initialization code
function Startup() {
dump("Doing Startup...\n");
toolkitCore = GetToolkitCore();
if(!toolkitCore) {
dump("toolkitCore not found!!! And we can't close the dialog!\n");
}
// NEVER create an appcore here - we must find parent editor's
appCore = XPAppCoresManager.Find("EditorAppCoreHTML");
if(!appCore || !toolkitCore) {
dump("EditorAppCore not found!!!\n");
toolkitCore.CloseWindow();
}
dump("EditorAppCore found for Link Properties dialog\n");
// Get a single selected element and edit its properites
editElement = appCore.getSelectedElement(tagName);
if (editElement) {
// We found an element and don't need to insert it
insertNew = false;
} else {
// We don't have an element selected,
// so create one with default attributes
dump("Element not selected - calling createElementWithDefaults\n");
editElement = appCore.createElementWithDefaults(tagName);
}
if(!editElement)
{
dump("Failed to get selected element or create a new one!\n");
toolkitCore.CloseWindow(window);
}
dump("GetSelectedElement...\n");
hrefInput = document.getElementById("textHREF");
// Set the input element value to current HREF
if (hrefInput)
{
dump("Setting HREF editbox value\n");
hrefInput.value = editNode.href;
}
}
function applyChanges() {
// Set the input element value to current HREF
hrefInput = document.getElementById("textHREF");
if (hrefInput)
{
dump("Copying edit field HREF value to node attribute\n");
editElement.setAttribute("href",hrefInput.value);
}
// Get text to use for a new link
if (insertNew)
{
textLink = document.getElementById("textLink");
if (textLink)
{
// Append the link text as the last child node
// of the docFrag
textNode = appCore.editorDocument.createTextNode(textLink.value);
if (textNode)
{
editElement.appendChild(textNode);
dump("Text for new link appended to HREF node\n");
newElement = appCore.insertElement(editElement);
if (newElement != editElement)
{
dump("Returned element from insertElement is different from orginal element.\n");
}
}
}
// Once inserted, we can modify properties, but don't insert again
insertNew = false;
}
}
function onOK() {
applyChanges();
toolkitCore.CloseWindow(window);
}
function onCancel() {
dump("Calling CloseWindow...\n");
toolkitCore.CloseWindow(window);
}
function GetToolkitCore() {
var toolkitCore = XPAppCoresManager.Find("ToolkitCore");
if (!toolkitCore) {
toolkitCore = new ToolkitCore();
if (toolkitCore)
toolkitCore.Init("ToolkitCore");
}
return toolkitCore;
}
<html:script language="JavaScript" src="chrome://editordlgs/content/EdLinkProps.js">
</html:script>
<html:table>