mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Added simple dialogs for insert link and restructured ui source directories
This commit is contained in:
parent
3ed143ee6b
commit
6228e33112
@ -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(¤tItem);
|
||||
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(¤tItem);
|
||||
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;
|
||||
|
106
editor/ui/dialogs/content/EdLinkProps.js
Normal file
106
editor/ui/dialogs/content/EdLinkProps.js
Normal file
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user