cmanske%netscape.com 264e9cc62c Tweak EdImageProps.js
git-svn-id: svn://10.0.0.236/trunk@67500 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-28 07:57:29 +00:00

693 lines
21 KiB
JavaScript

/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pete Collins
* Brian King
* Ben Goodger
*/
var insertNew = true;
var insertNewIMap = true;
var wasEnableAll = false;
var oldSourceInt = 0;
var imageElement;
var imageMap = 0;
var canRemoveImageMap = false;
var imageMapDisabled = false;
// dialog initialization code
function Startup()
{
if (!InitEditorShell())
return;
doSetOKCancel(onOK, null);
// Create dialog object to store controls for easy access
dialog = new Object;
dialog.srcInput = document.getElementById( "srcInput" );
dialog.altTextInput = document.getElementById( "altTextInput" );
dialog.MoreFewerButton = document.getElementById( "MoreFewerButton" );
dialog.AdvancedEditButton = document.getElementById( "AdvancedEditButton" );
dialog.AdvancedEditButton2 = document.getElementById( "AdvancedEditButton2" );
dialog.MoreSection = document.getElementById( "MoreSection" );
dialog.customsizeRadio = document.getElementById( "customsizeRadio" );
dialog.originalsizeRadio = document.getElementById( "originalsizeRadio" );
dialog.constrainCheckbox = document.getElementById( "constrainCheckbox" );
dialog.widthInput = document.getElementById( "widthInput" );
dialog.heightInput = document.getElementById( "heightInput" );
dialog.widthUnitsMenulist = document.getElementById( "widthUnitsMenulist" );
dialog.heightUnitsMenulist = document.getElementById( "heightUnitsMenulist" );
dialog.imagelrInput = document.getElementById( "imageleftrightInput" );
dialog.imagetbInput = document.getElementById( "imagetopbottomInput" );
dialog.border = document.getElementById( "border" );
dialog.alignTypeSelect = document.getElementById( "alignTypeSelect" );
dialog.editImageMap = document.getElementById( "editImageMap" );
dialog.removeImageMap = document.getElementById( "removeImageMap" );
dialog.doConstrain = false;
dialog.isCustomSize = false;
// Get a single selected image element
var tagName = "img"
imageElement = editorShell.GetSelectedElement(tagName);
if (imageElement)
{
// We found an element and don't need to insert one
insertNew = false;
}
else
{
insertNew = true;
// We don't have an element selected,
// so create one with default attributes
imageElement = editorShell.CreateElementWithDefaults(tagName);
if( !imageElement )
{
dump("Failed to get selected element or create a new one!\n");
window.close();
}
}
// Make a copy to use for AdvancedEdit
globalElement = imageElement.cloneNode(false);
// Get image map for image
var usemap = globalElement.getAttribute("usemap");
if (usemap)
{
mapname = usemap.substring(1, usemap.length);
mapCollection = editorShell.editorDocument.getElementsByName(mapname);
if (mapCollection[0] != null)
{
imageMap = mapCollection[0];
canRemoveImageMap = true;
insertNewIMap = false;
dump(imageMap.childNodes.length+"\n");
}
else
{
insertNewIMap = true;
globalMap = null;
}
}
else
{
insertNewIMap = true;
globalMap = null;
}
// Set SeeMore bool to the OPPOSITE of the current state,
// which is automatically saved by using the 'persist="more"'
// attribute on the MoreFewerButton button
// onMoreFewerImage will toggle the state and redraw the dialog
SeeMore = (dialog.MoreFewerButton.getAttribute("more") != "1");
// Initialize widgets with image attributes in the case where the entire dialog isn't visible
if ( SeeMore ) // this is actually in the opposite state until onMoreFewerImage is called below
InitDialog();
onMoreFewerImage(); // this call will initialize all widgets if entire dialog is visible
dialog.srcInput.focus();
}
// Set dialog widgets with attribute data
// We get them from globalElement copy so this can be used
// by AdvancedEdit(), which is shared by all property dialogs
function InitDialog()
{
// Set the controls to the image's attributes
str = globalElement.getAttribute("src");
if (str)
dialog.srcInput.value = str;
str = globalElement.getAttribute("alt");
if (str)
dialog.altTextInput.value = str;
// Check for image map
if ( SeeMore )
{
// setup the height and width widgets
dialog.widthInput.value = InitPixelOrPercentMenulist(globalElement, imageElement, "width", "widthUnitsMenulist");
dialog.heightInput.value = InitPixelOrPercentMenulist(globalElement, imageElement, "height", "heightUnitsMenulist");
// TODO: We need to get the actual image dimensions.
// If different from attribute dimensions, then "custom" is checked.
// For now, always check custom, so we don't trash existing values
if ( dialog.widthInput.value.length && dialog.heightInput.value.length
&& dialog.widthInput.value != "0" && dialog.heightInput.value != "0")
{
dialog.isCustomSize = true;
dialog.customsizeRadio.checked = true;
}
else
{
dialog.isCustomSize = false;
dialog.originalsizeRadio.checked = true;
}
// set spacing editfields
dialog.imagelrInput.value = globalElement.getAttribute("hspace");
dialog.imagetbInput.value = globalElement.getAttribute("vspace");
dialog.border.value = globalElement.getAttribute("border");
// Get alignment setting
var align = globalElement.getAttribute("align");
if (align) {
align = align.toLowerCase();
}
switch ( align )
{
case "top":
dialog.alignTypeSelect.selectedIndex = 0;
break;
case "center":
dialog.alignTypeSelect.selectedIndex = 1;
break;
case "right":
dialog.alignTypeSelect.selectedIndex = 3;
break;
case "left":
dialog.alignTypeSelect.selectedIndex = 4;
break;
default: // Default or "bottom"
dialog.alignTypeSelect.selectedIndex = 2;
break;
}
}
// we want to force an update so initialize "wasEnableAll" to be the opposite of what the actual state is
wasEnableAll = !IsValidImage(dialog.srcInput.value);
doOverallEnabling();
}
function chooseFile()
{
// Get a local file, converted into URL format
fileName = GetLocalFileURL("img");
if (fileName && fileName != "") {
dialog.srcInput.value = fileName;
doOverallEnabling();
}
// Put focus into the input field
dialog.srcInput.focus();
}
function SetGlobalElementToCurrentDialogSettings()
{
// src
var str = dialog.srcInput.value.trimString();
globalElement.setAttribute("src", str);
// alt
str = dialog.altTextInput.value.trimString();
globalElement.setAttribute("alt", str);
var alignment;
//Note that the attributes "left" and "right" are opposite
// of what we use in the UI, which describes where the TEXT wraps,
// not the image location (which is what the HTML describes)
switch ( dialog.alignTypeSelect.selectedIndex )
{
case 0:
alignment = "top";
break;
case 1:
alignment = "center";
break;
case 3:
alignment = "right";
break;
case 4:
alignment = "left";
break;
default: // Default or "bottom" (2)
alignment = "";
break;
}
dump("alignment ="+alignment+"\n");
if ( alignment == "" )
globalElement.removeAttribute( "align" );
else
globalElement.setAttribute( "align", alignment );
if ( dialog.imagelrInput.value.length > 0 )
globalElement.setAttribute("hspace", dialog.imagelrInput.value);
else
globalElement.removeAttribute("hspace");
if ( dialog.imagetbInput.value.length > 0 )
globalElement.setAttribute("vspace", dialog.imagetbInput.value);
else
globalElement.removeAttribute("vspace");
if ( dialog.border.value.length > 0 )
globalElement.setAttribute("border", dialog.border.value);
else
globalElement.removeAttribute("border");
// width
str = dialog.widthInput.value;
if (dialog.widthUnitsMenulist.selectedIndex == 1)
str = str + "%";
globalElement.setAttribute("width", str);
// height
str = dialog.heightInput.value;
if (dialog.heightUnitsMenulist.selectedIndex == 1)
str = str + "%";
globalElement.setAttribute("height", str);
}
function onMoreFewerImage()
{
if (SeeMore)
{
dialog.isCustomSize = dialog.customsizeRadio.checked;
dialog.doConstrain = dialog.constrainCheckbox.checked;
SetGlobalElementToCurrentDialogSettings();
//dialog.MoreSection.setAttribute("style","display: none");
dialog.MoreSection.setAttribute("collapsed","true");
window.sizeToContent();
dialog.MoreFewerButton.setAttribute("more","0");
dialog.MoreFewerButton.setAttribute("value",GetString("MoreProperties"));
SeeMore = false;
// Show the "Advanced Edit" button on same line as "More Properties"
dialog.AdvancedEditButton.removeAttribute("hidden");
dialog.AdvancedEditButton2.setAttribute("hidden","true");
}
else
{
//dialog.MoreSection.setAttribute("style","display: inherit");
dialog.MoreSection.removeAttribute("collapsed");
// Hide the "Advanced Edit" next to "More..." Use button at bottom right of dialog
dialog.AdvancedEditButton.setAttribute("style","display: none");
window.sizeToContent();
dialog.MoreFewerButton.setAttribute("more","1");
dialog.MoreFewerButton.setAttribute("value",GetString("FewerProperties"));
SeeMore = true;
// Show the "Advanced Edit" button at bottom
dialog.AdvancedEditButton.setAttribute("hidden","true");
dialog.AdvancedEditButton2.removeAttribute("hidden");
InitDialog();
//TODO: We won't need to do this when we convert to using "collapsed"
if (dialog.isCustomSize)
{
dialog.customsizeRadio.checked = true;
dialog.originalsizeRadio.checked = false;
}
else
{
dialog.customsizeRadio.checked = false;
dialog.originalsizeRadio.checked = true;
}
if (dialog.doConstrain)
dialog.constrainCheckbox.checked = true;
}
}
function doDimensionEnabling( doEnable )
{
SetElementEnabledById( "originalsizeRadio", doEnable );
SetElementEnabledById( "customsizeRadio", doEnable);
// Enabled only if "Custom" is checked
var enable = (doEnable && dialog.customsizeRadio.checked);
if ( !dialog.customsizeRadio.checked && !dialog.originalsizeRadio.checked)
dump("BUG! neither radio button is checked!!!! \n");
SetElementEnabledById( "widthInput", enable );
SetElementEnabledById( "widthLabel", enable);
SetElementEnabledById( "widthUnitsMenulist", enable );
SetElementEnabledById( "heightInput", enable );
SetElementEnabledById( "heightLabel", enable );
SetElementEnabledById( "heightUnitsMenulist", enable );
var constrainEnable = enable
&& ( dialog.widthUnitsMenulist.selectedIndex == 0 )
&& ( dialog.heightUnitsMenulist.selectedIndex == 0 );
SetElementEnabledById( "constrainCheckbox", constrainEnable );
}
function doOverallEnabling()
{
var canEnableAll = IsValidImage(dialog.srcInput.value);
if ( wasEnableAll == canEnableAll )
return;
wasEnableAll = canEnableAll;
SetElementEnabledById("ok", canEnableAll );
SetElementEnabledById( "altTextLabel", canEnableAll );
// Do widgets for sizing
SetElementEnabledById( "dimensionsLabel", canEnableAll );
doDimensionEnabling( canEnableAll );
SetElementEnabledById("alignLabel", canEnableAll );
SetElementEnabledById("alignTypeSelect", canEnableAll );
// spacing Box
SetElementEnabledById( "spacingLabel", canEnableAll );
SetElementEnabledById( "imageleftrightInput", canEnableAll );
SetElementEnabledById( "leftrightLabel", canEnableAll );
SetElementEnabledById( "leftrighttypeLabel", canEnableAll );
SetElementEnabledById( "imagetopbottomInput", canEnableAll );
SetElementEnabledById( "topbottomLabel", canEnableAll );
SetElementEnabledById( "topbottomtypeLabel", canEnableAll );
SetElementEnabledById( "border", canEnableAll );
SetElementEnabledById( "borderLabel", canEnableAll );
SetElementEnabledById( "bordertypeLabel", canEnableAll );
// This shouldn't find button, but it does!
SetElementEnabledById( "AdvancedEditButton", canEnableAll );
SetElementEnabledById( "AdvancedEditButton2", canEnableAll );
SetElementEnabledById( "imagemapLabel", canEnableAll );
SetElementEnabledById( "editImageMap", canEnableAll );
SetElementEnabledById( "removeImageMap", canEnableAll && canRemoveImageMap);
}
// constrainProportions contribution by pete@postpagan.com
function constrainProportions( srcID, destID )
{
srcElement = document.getElementById ( srcID );
if ( !srcElement )
return;
forceInteger( srcID );
// now find out if we should be constraining or not
var constrainChecked = (dialog.constrainCheckbox.checked);
constrainChecked = constrainChecked && !dialog.constrainCheckbox.disabled;
if ( !constrainChecked )
return;
destElement = document.getElementById( destID );
if ( !destElement )
return;
// set new value in the other edit field
// src / dest ratio mantained
// newDest = (newSrc * oldDest / oldSrc)
if ( oldSourceInt == 0 )
destElement.value = srcElement.value;
else
destElement.value = Math.round( srcElement.value * destElement.value / oldSourceInt );
oldSourceInt = srcElement.value;
}
function editImageMap()
{
// Make a copy to use for image map editor
if (insertNewIMap)
{
imageMap = editorShell.CreateElementWithDefaults("map");
globalMap = imageMap.cloneNode(true);
}
else
globalMap = imageMap;
window.openDialog("chrome://editor/content/EdImageMap.xul", "_blank", "chrome,close,titlebar,modal", globalElement, globalMap);
}
function removeImageMap()
{
globalElement.removeAttribute("usemap");
if (imageMap){
canRemoveImageMap = false;
SetElementEnabledByID( "removeImageMap", false);
editorShell.DeleteElement(imageMap);
insertNewIMap = true;
globalMap = null;
}
}
// Get data from widgets, validate, and set for the global element
// accessible to AdvancedEdit() [in EdDialogCommon.js]
function ValidateData()
{
if ( !IsValidImage(dialog.srcInput.value )) {
ShowInputErrorMessage(GetString("MissingImageError"));
return false;
}
//TODO: WE NEED TO DO SOME URL VALIDATION HERE, E.G.:
// We must convert to "file:///" or "http://" format else image doesn't load!
var src = dialog.srcInput.value.trimString();
globalElement.setAttribute("src", src);
// TODO: Should we confirm with user if no alt tag? Or just set to empty string?
var alt = dialog.altTextInput.value.trimString();
globalElement.setAttribute("alt", alt);
//TODO: WE SHOULD ALWAYS SET WIDTH AND HEIGHT FOR FASTER IMAGE LAYOUT
// IF USER DOESN'T SET IT, WE NEED TO GET VALUE FROM ORIGINAL IMAGE
var width = "";
var height = "";
var isPercentWidth, isPercentHeight;
var maxLimitWidth, maxLimitHeight;
if ( SeeMore )
{
dialog.isCustomSize = dialog.customsizeRadio.checked;
isPercentWidth = (dialog.widthUnitsMenulist.selectedIndex == 1);
isPercentHeight = (dialog.heightUnitsMenulist.selectedIndex == 1);
}
else /* can't SeeMore */
{
var tailindex;
width = globalElement.getAttribute( "width" );
tailindex = width.lastIndexOf("%");
isPercentWidth = ( tailindex > 0 );
if ( isPercentWidth )
width = width.substring(0, tailindex);
height = globalElement.getAttribute( "height" );
tailindex = height.lastIndexOf("%");
isPercentHeight = ( tailindex > 0 );
if ( isPercentHeight )
height = height.substring(0, tailindex);
}
if ( SeeMore && dialog.originalsizeRadio.checked )
{
// original size: don't do anything right now
}
else if ( (SeeMore && dialog.customsizeRadio.checked)
|| dialog.isCustomSize )
{
maxLimitWidth = isPercentWidth ? 100 : maxPixels; // Defined in EdDialogCommon.js
width = ValidateNumberString(dialog.widthInput.value, 1, maxLimitWidth);
if (width == "")
{
if ( !SeeMore )
onMoreFewerImage();
dialog.widthInput.focus();
return false;
}
if (isPercentWidth)
width = width + "%";
maxLimitHeight = isPercentHeight ? 100 : maxPixels; // Defined in EdDialogCommon.js
height = ValidateNumberString(dialog.heightInput.value, 1, maxLimitHeight);
if (height == "")
{
if ( !SeeMore )
onMoreFewerImage();
dialog.heightInput.focus();
return false;
}
if (isPercentHeight)
height = height + "%";
}
if ( !dialog.isCustomSize )
{
// for now (until we can get the actual image dimensions), clear the height/width attributes if not set
globalElement.removeAttribute( "width" );
globalElement.removeAttribute( "height" );
}
else
{
if (width.length > 0)
globalElement.setAttribute("width", width);
if (height.length > 0)
globalElement.setAttribute("height", height);
}
// spacing attributes
// All of these should use ValidateNumberString() to
// ensure value is within acceptable range
var amount;
if ( SeeMore )
{
dump("SeeMore spacing attribs\n");
if ( dialog.imagelrInput.value.length > 0 )
{
amount = ValidateNumberString(dialog.imagelrInput.value, 0, maxPixels);
if (amount == "")
return false;
globalElement.setAttribute( "hspace", amount );
}
else
globalElement.removeAttribute( "hspace" );
if ( dialog.imagetbInput.value.length > 0 )
{
var vspace = ValidateNumberString(dialog.imagetbInput.value, 0, maxPixels);
if (vspace == "")
return false;
globalElement.setAttribute( "vspace", vspace );
}
else
globalElement.removeAttribute( "vspace" );
// note this is deprecated and should be converted to stylesheets
if ( dialog.border.value.length > 0 )
{
var border = ValidateNumberString(dialog.border.value, 0, maxPixels);
if (border == "")
return false;
globalElement.setAttribute( "border", border );
}
else
globalElement.removeAttribute( "border" );
// Default or setting "bottom" means don't set the attribute
// Note that the attributes "left" and "right" are opposite
// of what we use in the UI, which describes where the TEXT wraps,
// not the image location (which is what the HTML describes)
var align = "";
switch ( dialog.alignTypeSelect.selectedIndex )
{
case 0:
align = "top";
break;
case 1:
align = "center";
break;
case 3:
align = "right";
break;
case 4:
align = "left";
break;
}
if (align == "")
globalElement.removeAttribute( "align" );
else
globalElement.setAttribute( "align", align );
}
return true;
}
function onOK()
{
// handle insertion of new image
if (ValidateData())
{
// Assign to map if there is one
if ( globalMap )
{
mapName = globalMap.getAttribute("name");
dump("mapName = "+mapName+"\n");
if (mapName != "")
{
globalElement.setAttribute("usemap", ("#"+mapName));
if (globalElement.getAttribute("border") == "")
globalElement.setAttribute("border", 0);
}
// Copy or insert image map
imageMap = globalMap.cloneNode(true);
if (insertNewIMap)
{
try
{
editorShell.editorDocument.body.appendChild(imageMap);
//editorShell.InsertElementAtSelection(imageMap, false);
}
catch (e)
{
dump("Exception occured in InsertElementAtSelection\n");
}
}
}
// All values are valid - copy to actual element in doc or
// element created to insert
editorShell.CloneAttributes(imageElement, globalElement);
if (insertNew)
{
try {
// 'true' means delete the selection before inserting
editorShell.InsertElementAtSelection(imageElement, true);
} catch (e) {
dump("Exception occured in InsertElementAtSelection\n");
}
}
// un-comment to see that inserting image maps does not work!
/*test = editorShell.CreateElementWithDefaults("map");
test.setAttribute("name", "testing");
testArea = editorShell.CreateElementWithDefaults("area");
testArea.setAttribute("shape", "circle");
testArea.setAttribute("coords", "86,102,52");
testArea.setAttribute("href", "test");
test.appendChild(testArea);
editorShell.InsertElementAtSelection(test, false);*/
return true;
}
return false;
}