Added CloneAttributes to IDL and nsIHTMLEditor. Reworked property dialogs to accomodate AdvancedEdit dialog. Preliminary version of AdvancedEdit dialog done

This commit is contained in:
cmanske%netscape.com 1999-09-02 01:47:18 +00:00
Родитель 4571deeb69
Коммит 714789baa3
20 изменённых файлов: 297 добавлений и 128 удалений

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

@ -1275,7 +1275,7 @@ nsEditor::GetBodyElement(nsIDOMElement **aBodyElement)
// Objects must be DOM elements
NS_IMETHODIMP
nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
nsresult result=NS_OK;
@ -1336,7 +1336,7 @@ nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
// Do we ever get here?
destElement->RemoveAttribute(sourceAttrName);
#if DEBUG_cmanske
printf("Attribute in NamedNodeMap has empty value in nsEditor::CopyAttributes()\n");
printf("Attribute in NamedNodeMap has empty value in nsEditor::CloneAttributes()\n");
#endif
}
}

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

@ -213,7 +213,7 @@ protected:
//NOTE: Most callers are dealing with Nodes,
// but these objects must supports nsIDOMElement
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
NS_IMETHOD CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
/*
NS_IMETHOD SetProperties(nsVoidArray *aPropList);
NS_IMETHOD GetProperties(nsVoidArray *aPropList);

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

@ -1304,6 +1304,30 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType
return res;
}
NS_IMETHODIMP
nsEditorShell::CloneAttributes(nsIDOMNode *destNode, nsIDOMNode *sourceNode)
{
if (!destNode || !sourceNode) { return NS_ERROR_NULL_POINTER; }
nsresult rv = NS_NOINTERFACE;
switch (mEditorType)
{
case ePlainTextEditorType:
case eHTMLTextEditorType:
{
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
if (editor)
rv = editor->CloneAttributes(destNode, sourceNode);
}
break;
default:
rv = NS_ERROR_NOT_IMPLEMENTED;
}
return rv;
}
NS_IMETHODIMP
nsEditorShell::NodeIsBlock(nsIDOMNode *node, PRBool *_retval)
{

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

@ -1304,6 +1304,30 @@ nsEditorShell::GetLocalFileURL(nsIDOMWindow *parent, const PRUnichar *filterType
return res;
}
NS_IMETHODIMP
nsEditorShell::CloneAttributes(nsIDOMNode *destNode, nsIDOMNode *sourceNode)
{
if (!destNode || !sourceNode) { return NS_ERROR_NULL_POINTER; }
nsresult rv = NS_NOINTERFACE;
switch (mEditorType)
{
case ePlainTextEditorType:
case eHTMLTextEditorType:
{
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
if (editor)
rv = editor->CloneAttributes(destNode, sourceNode);
}
break;
default:
rv = NS_ERROR_NOT_IMPLEMENTED;
}
return rv;
}
NS_IMETHODIMP
nsEditorShell::NodeIsBlock(nsIDOMNode *node, PRBool *_retval)
{

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

@ -297,6 +297,18 @@ interface nsIEditorShell : nsISupports
*/
boolean NodeIsBlock(in nsIDOMNode node);
/**
* This is similar to nsIDOMNode::cloneNode(),
* it assures the attribute nodes of the destination are identical with the source node
* by copying all existing attributes from the source and deleting those not in the source.
* This is used when the destination node (element) already exists
*
* The supplied nodes MUST BE ELEMENTS (most callers are working with nodes)
* destNode the destination element to operate on
* sourceNode the source element to copy attributes from
*/
void CloneAttributes(in nsIDOMNode destNode, in nsIDOMNode sourceNode);
void BeginBatchChanges();
void EndBatchChanges();
void RunUnitTests();

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

@ -1275,7 +1275,7 @@ nsEditor::GetBodyElement(nsIDOMElement **aBodyElement)
// Objects must be DOM elements
NS_IMETHODIMP
nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
nsresult result=NS_OK;
@ -1336,7 +1336,7 @@ nsEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
// Do we ever get here?
destElement->RemoveAttribute(sourceAttrName);
#if DEBUG_cmanske
printf("Attribute in NamedNodeMap has empty value in nsEditor::CopyAttributes()\n");
printf("Attribute in NamedNodeMap has empty value in nsEditor::CloneAttributes()\n");
#endif
}
}

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

@ -213,7 +213,7 @@ protected:
//NOTE: Most callers are dealing with Nodes,
// but these objects must supports nsIDOMElement
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
NS_IMETHOD CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
/*
NS_IMETHOD SetProperties(nsVoidArray *aPropList);
NS_IMETHOD GetProperties(nsVoidArray *aPropList);

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

@ -279,6 +279,18 @@ public:
NS_IMETHOD RemoveAttribute(nsIDOMElement * aElement,
const nsString& aAttribute)=0;
/**
* CloneAttributes() is similar to nsIDOMNode::cloneNode(),
* it assures the attribute nodes of the destination are identical with the source node
* by copying all existing attributes from the source and deleting those not in the source.
* This is used when the destination node (element) already exists
*
* The supplied nodes MUST BE ELEMENTS (most callers are working with nodes)
* @param aDestNode the destination element to operate on
* @param aSourceNode the source element to copy attributes from
*/
NS_IMETHOD CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)=0;
/**
* CreateNode instantiates a new element of type aTag and inserts it into aParent at aPosition.
* @param aTag The type of object to create

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

@ -2,6 +2,7 @@ More=More
Fewer=Fewer
OpenHTMLFile=Open HTML File
SelectImageFile=Select Image File
SaveDocument=Save Document
SaveDocumentAs=Save Document As
LinkImage=Link Image:
EditMode=Edit Mode
@ -16,4 +17,6 @@ SaveFilePrompt=Save changes to current file?
SaveFileFailed=Saving file failed!
DocumentTitle=Document Title
NeedDocTitle=Document does not have a title.
SaveDocument=Save Document
AttributesFor=Current attributes for:
foo=bar

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

@ -22,32 +22,77 @@
//Cancel() is in EdDialogCommon.js
// Note: This dialog
var tagname;
var element;
// dialog initialization code
function Startup()
{
// This is the return value for the parent,
// who only needs to know if OK was clicked
window.opener.AdvancedEditOK = false;
if (!InitEditorShell())
return;
doSetOKCancel(onOK, null);
// Create dialog object to store controls for easy access
dialog = new Object;
// GET EACH CONTROL -- E.G.:
dialog.editBox = document.getElementById("editBox");
element = window.arguments[1]);
// Element to edit is passed in
element = window.arguments[1];
if (!element || element == "undefined") {
dump("Advanced Edit: Element to edit not supplied\n");
window.close();
}
dump("*** Element passed into Advanced Edit: "+element+" ***\n");
// SET FOCUS TO FIRST CONTROL
//dialog.editBox.focus();
// Append tagname of element we are editing after the message text
// above the attribute editing treewidget
var msgParent = document.getElementById("AttributeMsgParent");
// Remove temporary place holder text:
// TODO: REMOVE THIS WHEN WE CAN RESIZE DIALOG AFTER CREATION
msgParent.removeChild(msgParent.firstChild);
var msg = editorShell.GetString("AttributesFor");
dump("Tagname Msg = "+msg+"\n");
msg +=(" "+element.nodeName);
dump("Tagname Msg = "+msg+"\n");
textNode = editorShell.editorDocument.createTextNode(msg);
if (textNode) {
msgParent.appendChild(textNode);
}
// Create dialog object to store controls for easy access
dialog = new Object;
dialog.AddAttributeNameInput = document.getElementById("AddAttributeNameInput");
//TODO: We should disable this button if the AddAttributeNameInput editbox is empty
dialog.AddAttribute = document.getElementById("AddAttribute");
//TODO: Get the list of attribute nodes,
// read each one, and use to build a text + editbox
// in a treewidget row for each attribute
var nodeMap = element.attributes;
var nodeMapCount = nodeMap.length;
// SET FOCUS TO FIRST CONTROL
}
function onAddAttribute()
{
var name = dialog.AddAttributeNameInput.value;
// TODO: Add a new text + editbox to the treewidget editing list
}
function onOK()
{
// Set attribute example:
// imageElement.setAttribute("src",dialog.srcInput.value);
//TODO: Get all children of the treewidget to get all
// name, value strings for all attributes.
// Set those attributes on "element" we are editing.
window.opener.AdvancedEditOK = true;
return true; // do close the window
}

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

@ -30,7 +30,7 @@
<!-- <?xul-overlay href="chrome://editor/content/EdDialogOverlay.xul"?> -->
<!DOCTYPE window SYSTEM "chrome://editor/locale/EdAdvancedEdit.dtd">
<xul:window class="dialog" title="&windowTitle.label;"
<xul:window class="dialog" title="&WindowTitle.label;"
xmlns:xul ="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns="http://www.w3.org/TR/REC-html40"
onload = "Startup()"
@ -44,6 +44,24 @@
<script language="JavaScript" src="chrome://global/content/dialogOverlay.js" />
<xul:broadcaster id="args" value=""/>
<xul:box align="vertical" style="width: 100%; height: 100%">
<xul:box align="horizontal">
<!-- temporary text, do not localize -->
<div id="AttributeMsgParent"> "REMOVE ME"</div>
<!-- Message with the tagname appended will be inserted here -->
</xul:box>
<xul:spring class="spacer"/>
<div id="AttributeTree" style="min-width: 200px; min-height: 200px; border: 1px inset white"/>
<xul:spring class="spacer"/>
<label for="AddAttributeNameInput"> &AddAttributeMsg.label;</label>
<xul:box align="horizontal" flex="100%">
<input type="text" id="AddAttributeNameInput"/>
<xul:spring class="spacer"/>
<div><xul:titledbutton class="hspaced" id="AddAttribute" onclick="AddAttribute()" value="&AddAttributeButton.label;"/></div>
</xul:box>
<html:div><html:hr width="100%"/></html:div>
</xul:box>
<!-- from global dialogOverlay -->
<xul:box id="okCancelButtons"/>
</xul:window>

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

@ -29,6 +29,8 @@ var SelectionOnly = 1;
var FormatedWithDoctype = 2;
var FormatedWithoutDoctype = 6;
var maxPixels = 10000;
// The element being edited - so AdvancedEdit can have access to it
var globalElement;
function InitEditorShell()
{
@ -408,20 +410,6 @@ function GetSelectionAsText()
}
// This is here so to stop the annoying JS error that keeps poping up
// from the advanced edit button which points to a non existant onAdvanced() function
// Well now it exists -pete
function onAdvancedEdit(){
dump("\n\ncomming soon . . .\nthe \"onAdvancedEdit\" function\n\n");
}
// ** getSelection ()
// ** This function checks for existence of table around the focus node
// ** Brian King - XML Workshop

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

@ -44,7 +44,7 @@ function Startup()
//dialog.editBox.focus();
}
function initDialog() {
function InitDialog() {
// Get a single selected element of the desired type
element = editorShell.GetSelectedElement(tagName);

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

@ -23,7 +23,6 @@
var toolkitCore;
var tagName = "hr";
var hLineElement;
var tempLineElement;
var percentChar = "";
var width;
var height;
@ -47,13 +46,6 @@ function Startup()
window.close();
return;
}
// Create a temporary element to use with Save Settings as default
tempLineElement = editorShell.editorDocument.createElement("HR");
if (!hLineElement) {
dump("Temporary HLine element was not created!\n");
window.close();
return;
}
// Create dialog object to store controls for easy access
dialog = new Object;
@ -64,18 +56,27 @@ function Startup()
dialog.rightAlign = document.getElementById("rightAlign");
dialog.shading = document.getElementById("3dShading");
// Make a copy to use for AdvancedEdit and onSaveDefault
globalElement = hLineElement.cloneNode(false);
// Initialize control values based on existing attributes
InitDialog()
// SET FOCUS TO FIRST CONTROL
dialog.heightInput.focus();
}
function InitDialog()
{
// Just to be confusing, "size" is used instead of height
// We will use "height" here and in UI
dialog.heightInput.value = hLineElement.getAttribute("size");
dialog.heightInput.value = globalElement.getAttribute("size");
// Get the width attribute of the element, stripping out "%"
// This sets contents of button text and "percentChar" variable
dialog.widthInput.value = InitPixelOrPercentPopupButton(hLineElement, "width", "pixelOrPercentButton");
dialog.widthInput.value = InitPixelOrPercentPopupButton(globalElement, "width", "pixelOrPercentButton");
align = hLineElement.getAttribute("align");
align = globalElement.getAttribute("align");
if (align == "center") {
dialog.centerAlign.checked = true;
} else if (align == "right") {
@ -83,18 +84,15 @@ function Startup()
} else {
dialog.leftAlign.checked = true;
}
noshade = hLineElement.getAttribute("noshade");
noshade = globalElement.getAttribute("noshade");
dialog.shading.checked = (noshade == "");
// SET FOCUS TO FIRST CONTROL
dialog.heightInput.focus();
}
function onSaveDefault()
{
// "false" means set attributes on the tempLineElement,
// "false" means set attributes on the globalElement,
// not the real element being edited
if (ValidateData(false)) {
if (ValidateData()) {
var prefs = Components.classes['component://netscape/preferences'];
if (prefs) {
prefs = prefs.getService();
@ -139,7 +137,24 @@ function onSaveDefault()
}
}
function ValidateData(setAttributes)
function onAdvancedEdit()
{
if (ValidateData()) {
// Set true if OK is clicked in the Advanced Edit dialog
window.AdvancedEditOK = false;
window.openDialog("chrome://editor/content/EdAdvancedEdit.xul", "AdvancedEdit", "chrome,close,titlebar,modal", "", globalElement);
if (window.AdvancedEditOK) {
dump("OK was pressed in AdvancedEdit Dialog\n");
// Copy edited attributes to the dialog widgets:
// Note that we still don't want
InitDialog();
} else {
dump("OK was NOT pressed in AdvancedEdit Dialog\n");
}
}
}
function ValidateData()
{
// Height is always pixels
height = ValidateNumberString(dialog.heightInput.value, 1, maxPixels);
@ -150,11 +165,7 @@ function ValidateData(setAttributes)
return false;
}
dump("Setting height="+height+"\n");
if (setAttributes) {
hLineElement.setAttribute("size", height);
} else {
tempLineElement.setAttribute("size", height);
}
globalElement.setAttribute("size", height);
var maxLimit;
dump("Validate width. PercentChar="+percentChar+"\n");
@ -173,11 +184,7 @@ function ValidateData(setAttributes)
}
width = width + percentChar;
dump("Height="+height+" Width="+width+"\n");
if (setAttributes) {
hLineElement.setAttribute("width", width);
} else {
tempLineElement.setAttribute("width", width);
}
globalElement.setAttribute("width", width);
align = "left";
if (dialog.centerAlign.checked) {
@ -185,26 +192,14 @@ function ValidateData(setAttributes)
} else if (dialog.rightAlign.checked) {
align = "right";
}
if (setAttributes) {
hLineElement.setAttribute("align", align);
} else {
tempLineElement.setAttribute("align", align);
}
globalElement.setAttribute("align", align);
if (dialog.shading.checked) {
shading = true;
if (setAttributes) {
hLineElement.removeAttribute("noshade");
} else {
tempLineElement.removeAttribute("noshade");
}
globalElement.removeAttribute("noshade");
} else {
shading = false;
if (setAttributes) {
hLineElement.setAttribute("noshade", "");
} else {
tempLineElement.setAttribute("noshade", "");
}
globalElement.setAttribute("noshade", "");
}
return true;
}
@ -214,5 +209,9 @@ function onOK()
// Since we only edit existing HLines,
// ValidateData will set the new attributes
// so there's nothing else to do
var res = ValidateData();
// Copy attributes from the globalElement to the document element
if (res)
editorShell.CloneAttributes(hLineElement, globalElement);
return (ValidateData(true));
}

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

@ -75,14 +75,7 @@ function Startup()
dump("Not all dialog controls were found!!!\n");
}
initDialog();
dialog.srcInput.focus();
}
function initDialog() {
// Get a single selected anchor element
// Get a single selected image element
imageElement = editorShell.GetSelectedElement(tagName);
@ -108,6 +101,14 @@ function initDialog() {
}
}
// Initialize all widgets with image attributes
InitDialog();
dialog.srcInput.focus();
}
function InitDialog() {
// Set the controls to the image's attributes
str = imageElement.getAttribute("src");
@ -492,6 +493,11 @@ function constrainProportions( srcID, destID )
oldSourceInt = srcElement.value;
}
function onAdvancedEdit()
{
dump("\n\n Need to write onAdvancedEdit for Image dialog\n\n");
}
function onOK()
{
if ( !imageType ) {

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

@ -66,6 +66,11 @@ function Startup()
dialog.rowsInput.focus();
}
function onAdvancedEdit()
{
dump("\n\n Need to write onAdvancedEdit for Insert Table dialog\n\n");
}
function onOK()
{
rows = ValidateNumberString(dialog.rowsInput.value, 1, maxRows);

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

@ -55,31 +55,6 @@ function Startup()
dump("Not all dialog controls were found!!!\n");
}
// Set data for the dialog controls
initDialog();
// Set initial focus
if (insertNew) {
dump("Setting focus to linkTextInput\n");
// We will be using the HREF inputbox, so text message
linkTextInput.focus();
} else {
dump("Setting focus to linkTextInput\n");
hrefInput.focus();
// We will not insert a new link at caret, so remove link text input field
parentNode = linkTextInput.parentNode;
if (parentNode) {
dump("Removing link text input field.\n");
parentNode.removeChild(linkTextInput);
linkTextInput = null;
}
}
}
function initDialog()
{
// Get a single selected anchor element
anchorElement = editorShell.GetSelectedElement(tagName);
@ -101,8 +76,9 @@ function initDialog()
editorShell.SelectElement(anchorElement);
selection = editorShell.editorSelection;
hrefInput.value = anchorElement.getAttribute("href");
dump("Current HREF: "+hrefInput.value+"\n");
// Moved to InitDialog()
// hrefInput.value = anchorElement.getAttribute("href");
// dump("Current HREF: "+hrefInput.value+"\n");
} else {
// See if we have a selected image instead of text
imageElement = editorShell.GetSelectedElement("img");
@ -165,6 +141,33 @@ function initDialog()
insertLinkAroundSelection = true;
dump("insertLinkAroundSelection is TRUE\n");
}
// Set data for the dialog controls
InitDialog();
// Set initial focus
if (insertNew) {
dump("Setting focus to linkTextInput\n");
// We will be using the HREF inputbox, so text message
linkTextInput.focus();
} else {
dump("Setting focus to linkTextInput\n");
hrefInput.focus();
// We will not insert a new link at caret, so remove link text input field
parentNode = linkTextInput.parentNode;
if (parentNode) {
dump("Removing link text input field.\n");
parentNode.removeChild(linkTextInput);
linkTextInput = null;
}
}
}
function InitDialog()
{
hrefInput.value = anchorElement.getAttribute("href");
dump("Current HREF: "+hrefInput.value+"\n");
}
function ChooseFile()
@ -184,6 +187,11 @@ function RemoveLink()
hrefInput.value = "";
}
function onAdvancedEdit()
{
dump("\n\n Need to write onAdvancedEdit for Link dialog\n\n");
}
function onOK()
{
dump("***** Clicked OK in link props dialog\n");

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

@ -24,6 +24,7 @@ var insertNew = true;
var tagName = "anchor";
var anchorElement = null;
var nameInput;
var name;
// dialog initialization code
function Startup()
@ -44,7 +45,7 @@ function Startup()
// We found an element and don't need to insert one
insertNew = false;
dump("Found existing anchor\n");
nameInput.value = anchorElement.getAttribute("name");
name = anchorElement.getAttribute("name");
} else {
insertNew = true;
// We don't have an element selected,
@ -61,8 +62,6 @@ function Startup()
//Be sure the name is unique to the document
if (AnchorNameExists(name))
name += "_"
nameInput.value = name;
}
if(!anchorElement)
@ -70,10 +69,19 @@ function Startup()
dump("Failed to get selected element or create a new one!\n");
window.close();
}
// Make a copy to use for AdvancedEdit
globalElement = anchorElement.cloneNode;
InitDialog();
nameInput.focus();
}
function InitDialog()
{
nameInput.value = name;
}
function AnchorNameExists(name)
{
anchorList = editorShell.editorDocument.anchors; // getElementsByTagName("A");
@ -88,6 +96,13 @@ function AnchorNameExists(name)
return false;
}
function onAdvancedEdit()
{
dump("\n\n Need to write onAdvancedEdit for Named Anchor dialog\n\n");
}
}
function onOK()
{
name = nameInput.value;

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

@ -37,7 +37,15 @@ function Startup()
// GET EACH CONTROL -- E.G.:
//dialog.editBox = document.getElementById("editBox");
initDialog();
/*
// Get the selected or enclosing table element
if(!element)
{
dump("Failed to get selected element or create a new one!\n");
window.close();
}
*/
InitDialog();
var table = editorShell.GetElementOrParentByTagName("table", null);
if (!table)
@ -48,14 +56,14 @@ function Startup()
}
function initDialog() {
/*
if(!element)
function InitDialog()
{
dump("Failed to get selected element or create a new one!\n");
window.close();
dump{"Table Editing:InitDialog()\n");
}
*/
function onAdvancedEdit()
{
dump("\n\n Need to write onAdvancedEdit for Table and Cell dialog\n\n");
}
function onOK()

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

@ -20,4 +20,6 @@
- Contributor(s):
-->
<!ENTITY windowTitle.label "Advanced Property Editor">
<!ENTITY WindowTitle.label "Advanced Property Editor">
<!ENTITY AddAttributeMsg.label "Name for attribute to add:">
<!ENTITY AddAttributeButton.label "Add">