зеркало из https://github.com/mozilla/pjs.git
Add checkbox to remove link border and simplify anchor/heading selection when choosing link (b=96477, fix by neil@parkwaycc.co.uk, r=cmanske, sr=kin); improved 'Constrain' checkbox logic in image dialogs (b=58133, r=neil@parkwaycc.co.uk, sr=kin)
This commit is contained in:
Родитель
27f932a43d
Коммит
6ff254ec3a
|
@ -220,6 +220,7 @@ function SetTextboxFocus(textbox)
|
|||
{
|
||||
// Select entire contents
|
||||
if (textbox.value.length > 0)
|
||||
// This doesn't work for editable menulists yet
|
||||
textbox.select();
|
||||
else
|
||||
textbox.focus();
|
||||
|
@ -888,11 +889,13 @@ function onCancel()
|
|||
return true;
|
||||
}
|
||||
|
||||
function SetRelativeCheckbox()
|
||||
function SetRelativeCheckbox(checkbox)
|
||||
{
|
||||
var checkbox = document.getElementById("MakeRelativeCheckbox");
|
||||
if (!checkbox) {
|
||||
checkbox = document.getElementById("MakeRelativeCheckbox");
|
||||
if (!checkbox)
|
||||
return;
|
||||
}
|
||||
|
||||
// Mail never allows relative URLs, so hide the checkbox
|
||||
if (editorShell.editorType == "htmlmail")
|
||||
|
@ -947,16 +950,12 @@ function SetRelativeCheckbox()
|
|||
}
|
||||
}
|
||||
|
||||
SetElementEnabledById("MakeRelativeCheckbox", enable);
|
||||
SetElementEnabled(checkbox, enable);
|
||||
}
|
||||
|
||||
// oncommand handler for the Relativize checkbox in EditorOverlay.xul
|
||||
function MakeInputValueRelativeOrAbsolute()
|
||||
function MakeInputValueRelativeOrAbsolute(checkbox)
|
||||
{
|
||||
var checkbox = document.getElementById("MakeRelativeCheckbox");
|
||||
if (!checkbox)
|
||||
return;
|
||||
|
||||
var input = document.getElementById(checkbox.getAttribute("for"));
|
||||
if (!input)
|
||||
return;
|
||||
|
@ -979,7 +978,7 @@ function MakeInputValueRelativeOrAbsolute()
|
|||
input.value = MakeAbsoluteUrl(input.value);
|
||||
|
||||
// Reset checkbox to reflect url state
|
||||
SetRelativeCheckbox(checkbox, input.value);
|
||||
SetRelativeCheckbox(checkbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1203,3 +1202,74 @@ function RemoveElementKeepingChildren(element)
|
|||
editorShell.EndBatchChanges();
|
||||
}
|
||||
|
||||
function FillLinkMenulist(linkMenulist, headingsArray)
|
||||
{
|
||||
var NamedAnchorNodeList = editorShell.editorDocument.anchors;
|
||||
var NamedAnchorCount = NamedAnchorNodeList.length;
|
||||
if (NamedAnchorCount > 0)
|
||||
{
|
||||
for (var i = 0; i < NamedAnchorCount; i++)
|
||||
linkMenulist.appendItem("#" + NamedAnchorNodeList.item(i).name);
|
||||
}
|
||||
for (var j = 1; j <= 6; j++)
|
||||
{
|
||||
var headingList = editorShell.editorDocument.getElementsByTagName("h" + j);
|
||||
for (var k = 0; k < headingList.length; k++)
|
||||
{
|
||||
var heading = headingList.item(k);
|
||||
|
||||
// Skip headings that already have a named anchor as their first child
|
||||
// (this may miss nearby anchors, but at least we don't insert another
|
||||
// under the same heading)
|
||||
var child = heading.firstChild;
|
||||
if (child && child.nodeName == "A" && child.name && (child.name.length>0))
|
||||
continue;
|
||||
|
||||
var range = editorShell.editorDocument.createRange();
|
||||
range.setStart(heading,0);
|
||||
var lastChildIndex = heading.childNodes.length;
|
||||
range.setEnd(heading,lastChildIndex);
|
||||
var text = range.toString();
|
||||
if (text)
|
||||
{
|
||||
// Use just first 40 characters, don't add "...",
|
||||
// and replace whitespace with "_" and strip non-word characters
|
||||
text = "#" + ConvertToCDATAString(TruncateStringAtWordEnd(text, 40, false));
|
||||
// Append "_" to any name already in the list
|
||||
while (linkMenulist.getElementsByAttribute("label", text).length)
|
||||
text += "_";
|
||||
linkMenulist.appendItem(text);
|
||||
|
||||
// Save nodes in an array so we can create anchor node under it later
|
||||
headingsArray[NamedAnchorCount++] = heading;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!linkMenulist.firstChild.hasChildNodes())
|
||||
{
|
||||
var item = linkMenulist.appendItem(GetString("NoNamedAnchorsOrHeadings"));
|
||||
item.setAttribute("disabled", "true");
|
||||
}
|
||||
}
|
||||
|
||||
// Shared by Image and Link dialogs for the "Choose" button for links
|
||||
function chooseLinkFile()
|
||||
{
|
||||
// Get a local file, converted into URL format
|
||||
var fileName = GetLocalFileURL("html, img");
|
||||
if (fileName)
|
||||
{
|
||||
// Always try to relativize local file URLs
|
||||
if (gHaveDocumentUrl)
|
||||
fileName = MakeRelativeUrl(fileName);
|
||||
|
||||
gDialog.hrefInput.value = fileName;
|
||||
|
||||
// Do stuff specific to a particular dialog
|
||||
// (This is defined separately in Image and Link dialogs)
|
||||
ChangeLinkLocation();
|
||||
}
|
||||
// Put focus into the input field
|
||||
SetTextboxFocus(gDialog.hrefInput);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,11 +58,38 @@
|
|||
oncommand = "chooseFile()"
|
||||
label = "&chooseButton.label;"/>
|
||||
|
||||
<button
|
||||
id = "ChooseLink"
|
||||
oncommand = "chooseLink();"
|
||||
label = "&chooseButton.label;"/>
|
||||
|
||||
<checkbox
|
||||
id = "MakeRelativeCheckbox"
|
||||
label = "&makeUrlRelative.label;"
|
||||
oncommand = "MakeInputValueRelativeOrAbsolute()"
|
||||
tooltiptext = "&makeUrlRelative.tooltip;"
|
||||
style = "margin-top: 0px"/>
|
||||
oncommand = "MakeInputValueRelativeOrAbsolute(this);"
|
||||
tooltiptext = "&makeUrlRelative.tooltip;"/>
|
||||
|
||||
<checkbox
|
||||
id = "MakeRelativeLink"
|
||||
label = "&makeUrlRelative.label;"
|
||||
oncommand = "MakeInputValueRelativeOrAbsolute(this);"
|
||||
tooltiptext = "&makeUrlRelative.tooltip;"/>
|
||||
|
||||
<vbox id="LinkLocationBox">
|
||||
<description width="1">&LinkURLEditField.label;</description>
|
||||
<menulist editable="true" id="hrefInput" oninput="ChangeLinkLocation();">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
<hbox align="center">
|
||||
<!-- from EdDialogOverlay.xul 'for' identifies the textfield to get URL from -->
|
||||
<checkbox id="MakeRelativeLink"
|
||||
for="hrefInput"
|
||||
label="&makeUrlRelative.label;"
|
||||
oncommand="MakeInputValueRelativeOrAbsolute(this);"
|
||||
tooltiptext="&makeUrlRelative.tooltip;"/>
|
||||
<spacer flex="1"/>
|
||||
<button label="&chooseButton.label;" oncommand="chooseLinkFile();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
</overlay>
|
||||
|
|
|
@ -46,9 +46,9 @@ var gImageMap = 0;
|
|||
var gCanRemoveImageMap = false;
|
||||
var gRemoveImageMap = false;
|
||||
var gImageMapDisabled = false;
|
||||
var actualWidth = "";
|
||||
var gActualWidth = "";
|
||||
var gActualHeight = "";
|
||||
var gOriginalSrc = "";
|
||||
var actualHeight = "";
|
||||
var gHaveDocumentUrl = false;
|
||||
var gTimerID;
|
||||
var gValidateTab;
|
||||
|
@ -127,17 +127,11 @@ function InitImage()
|
|||
gInsertNewImage ? null : imageElement,
|
||||
"height", "heightUnitsMenulist", gPixel);
|
||||
|
||||
var rg = gDialog.actualSizeRadio.radioGroup;
|
||||
// Set actual radio button if both set values are the same as actual
|
||||
if (actualWidth && actualHeight) {
|
||||
if ((width == actualWidth && height == actualHeight) || !(width || height))
|
||||
rg.selectedItem = gDialog.actualSizeRadio;
|
||||
}
|
||||
if (!gDialog.actualSizeRadio.selected)
|
||||
rg.selectedItem = gDialog.customSizeRadio;
|
||||
SetSizeWidgets(width, height);
|
||||
|
||||
gDialog.widthInput.value = gConstrainWidth = width ? width : (actualWidth ? actualWidth : "");
|
||||
gDialog.heightInput.value = gConstrainHeight = height ? height : (actualHeight ? actualHeight : "");
|
||||
gDialog.widthInput.value = gConstrainWidth = width ? width : (gActualWidth ? gActualWidth : "");
|
||||
gDialog.heightInput.value = gConstrainHeight = height ? height : (gActualHeight ? gActualHeight : "");
|
||||
|
||||
// set spacing editfields
|
||||
gDialog.imagelrInput.value = globalElement.getAttribute("hspace");
|
||||
|
@ -192,6 +186,26 @@ function InitImage()
|
|||
doDimensionEnabling();
|
||||
}
|
||||
|
||||
function SetSizeWidgets(width, height)
|
||||
{
|
||||
if (!(width || height) || (gActualWidth && gActualHeight && width == gActualWidth && height == gActualHeight))
|
||||
gDialog.actualSizeRadio.radioGroup.selectedItem = gDialog.actualSizeRadio;
|
||||
|
||||
if (!gDialog.actualSizeRadio.selected)
|
||||
{
|
||||
gDialog.actualSizeRadio.radioGroup.selectedItem = gDialog.customSizeRadio;
|
||||
|
||||
// Decide if user's sizes are in the same ratio as actual sizes
|
||||
if (gActualWidth && gActualHeight)
|
||||
{
|
||||
if (gActualWidth > gActualHeight)
|
||||
gDialog.constrainCheckbox.checked = (Math.round(gActualHeight * width / gActualWidth) == height);
|
||||
else
|
||||
gDialog.constrainCheckbox.checked = (Math.round(gActualWidth * height / gActualHeight) == width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable alt text input when "Don't use alt" radio is checked
|
||||
function SetAltTextDisabled(disable)
|
||||
{
|
||||
|
@ -249,34 +263,34 @@ function PreviewImageLoaded()
|
|||
if (gDialog.PreviewImage)
|
||||
{
|
||||
// Image loading has completed -- we can get actual width
|
||||
actualWidth = gDialog.PreviewImage.naturalWidth;
|
||||
actualHeight = gDialog.PreviewImage.naturalHeight;
|
||||
gActualWidth = gDialog.PreviewImage.naturalWidth;
|
||||
gActualHeight = gDialog.PreviewImage.naturalHeight;
|
||||
|
||||
if (actualWidth && actualHeight)
|
||||
if (gActualWidth && gActualHeight)
|
||||
{
|
||||
// Use actual size or scale to fit preview if either dimension is too large
|
||||
var width = actualWidth;
|
||||
var height = actualHeight;
|
||||
if (actualWidth > gPreviewImageWidth)
|
||||
var width = gActualWidth;
|
||||
var height = gActualHeight;
|
||||
if (gActualWidth > gPreviewImageWidth)
|
||||
{
|
||||
width = gPreviewImageWidth;
|
||||
height = actualHeight * (gPreviewImageWidth / actualWidth);
|
||||
height = gActualHeight * (gPreviewImageWidth / gActualWidth);
|
||||
}
|
||||
if (height > gPreviewImageHeight)
|
||||
{
|
||||
height = gPreviewImageHeight;
|
||||
width = actualWidth * (gPreviewImageHeight / actualHeight);
|
||||
width = gActualWidth * (gPreviewImageHeight / gActualHeight);
|
||||
}
|
||||
gDialog.PreviewImage.width = width;
|
||||
gDialog.PreviewImage.height = height;
|
||||
|
||||
gDialog.PreviewWidth.setAttribute("value", actualWidth);
|
||||
gDialog.PreviewHeight.setAttribute("value", actualHeight);
|
||||
gDialog.PreviewWidth.setAttribute("value", gActualWidth);
|
||||
gDialog.PreviewHeight.setAttribute("value", gActualHeight);
|
||||
|
||||
gDialog.PreviewSize.setAttribute("collapsed", "false");
|
||||
gDialog.ImageHolder.setAttribute("collapsed", "false");
|
||||
|
||||
// Use values as start for constrain proportions
|
||||
SetSizeWidgets(gDialog.widthInput.value, gDialog.heightInput.value);
|
||||
}
|
||||
|
||||
if (gDialog.actualSizeRadio.selected)
|
||||
|
@ -335,9 +349,9 @@ function LoadPreviewImage()
|
|||
|
||||
function SetActualSize()
|
||||
{
|
||||
gDialog.widthInput.value = actualWidth ? actualWidth : "";
|
||||
gDialog.widthInput.value = gActualWidth ? gActualWidth : "";
|
||||
gDialog.widthUnitsMenulist.selectedIndex = 0;
|
||||
gDialog.heightInput.value = actualHeight ? actualHeight : "";
|
||||
gDialog.heightInput.value = gActualHeight ? gActualHeight : "";
|
||||
gDialog.heightUnitsMenulist.selectedIndex = 0;
|
||||
doDimensionEnabling();
|
||||
}
|
||||
|
@ -415,7 +429,7 @@ function constrainProportions( srcID, destID )
|
|||
// always force an integer (whether we are constraining or not)
|
||||
forceInteger(srcID);
|
||||
|
||||
if (!actualWidth || !actualHeight ||
|
||||
if (!gActualWidth || !gActualHeight ||
|
||||
!(gDialog.constrainCheckbox.checked && !gDialog.constrainCheckbox.disabled))
|
||||
return;
|
||||
|
||||
|
@ -429,9 +443,9 @@ function constrainProportions( srcID, destID )
|
|||
// and then turn constrain on and change a number
|
||||
// I prefer the old strategy (below) but I can see some merit to this solution
|
||||
if (srcID == "widthInput")
|
||||
destElement.value = Math.round( srcElement.value * actualHeight / actualWidth );
|
||||
destElement.value = Math.round( srcElement.value * gActualHeight / gActualWidth );
|
||||
else
|
||||
destElement.value = Math.round( srcElement.value * actualWidth / actualHeight );
|
||||
destElement.value = Math.round( srcElement.value * gActualWidth / gActualHeight );
|
||||
|
||||
/*
|
||||
// With this strategy, the width and height ratio
|
||||
|
@ -521,9 +535,9 @@ function ValidateImage()
|
|||
// We always set the width and height attributes, even if same as actual.
|
||||
// This speeds up layout of pages since sizes are known before image is loaded
|
||||
if (!width)
|
||||
width = actualWidth;
|
||||
width = gActualWidth;
|
||||
if (!height)
|
||||
height = actualHeight;
|
||||
height = gActualHeight;
|
||||
|
||||
// Remove existing width and height only if source changed
|
||||
// and we couldn't obtain actual dimensions
|
||||
|
@ -574,87 +588,3 @@ function ValidateImage()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onAccept()
|
||||
{
|
||||
// Use this now (default = false) so Advanced Edit button dialog doesn't trigger error message
|
||||
gDoAltTextError = true;
|
||||
|
||||
if (ValidateData())
|
||||
{
|
||||
if ("arguments" in window && window.arguments[0])
|
||||
{
|
||||
SaveWindowLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
editorShell.BeginBatchChanges();
|
||||
|
||||
if (gRemoveImageMap)
|
||||
{
|
||||
globalElement.removeAttribute("usemap");
|
||||
if (gImageMap)
|
||||
{
|
||||
editorShell.DeleteElement(gImageMap);
|
||||
gInsertNewIMap = true;
|
||||
gImageMap = null;
|
||||
}
|
||||
}
|
||||
else if (gImageMap)
|
||||
{
|
||||
// Assign to map if there is one
|
||||
var mapName = gImageMap.getAttribute("name");
|
||||
if (mapName != "")
|
||||
{
|
||||
globalElement.setAttribute("usemap", ("#"+mapName));
|
||||
if (globalElement.getAttribute("border") == "")
|
||||
globalElement.setAttribute("border", 0);
|
||||
}
|
||||
|
||||
if (gInsertNewIMap)
|
||||
{
|
||||
try
|
||||
{
|
||||
editorShell.editorDocument.body.appendChild(gImageMap);
|
||||
//editorShell.InsertElementAtSelection(gImageMap, 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 (gInsertNewImage)
|
||||
{
|
||||
try {
|
||||
// 'true' means delete the selection before inserting
|
||||
editorShell.InsertElementAtSelection(imageElement, true);
|
||||
} catch (e) {
|
||||
dump(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);*/
|
||||
|
||||
editorShell.EndBatchChanges();
|
||||
|
||||
SaveWindowLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
gDoAltTextError = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
<tab id="imageLocationTab" label="&imageLocationTab.label;"/>
|
||||
<tab id="imageDimensionsTab" label="&imageDimensionsTab.label;"/>
|
||||
<tab id="imageAppearanceTab" label="&imageAppearanceTab.label;"/>
|
||||
<!-- This tab is currently not used -->
|
||||
<tab id="imageLinkTab" label="&imageLinkTab.label;"/>
|
||||
|
||||
<vbox id="imageLocation">
|
||||
|
@ -43,10 +42,7 @@
|
|||
value = "&locationEditField.label;"
|
||||
tooltiptext="&locationEditField.tooltip;"
|
||||
/>
|
||||
<textbox flex="1"
|
||||
id = "srcInput"
|
||||
oninput = "ChangeImageSrc()"
|
||||
style = "min-width : 20em"/>
|
||||
<textbox id="srcInput" oninput="ChangeImageSrc();"/>
|
||||
<hbox>
|
||||
<checkbox
|
||||
id = "MakeRelativeCheckbox"
|
||||
|
|
|
@ -23,41 +23,41 @@
|
|||
* Ben Goodger
|
||||
*/
|
||||
|
||||
var gPreviewImageHeight = 50;
|
||||
var StartupCalled = false;
|
||||
var gAnchorElement = null;
|
||||
var gOriginalHref = "";
|
||||
var gHNodeArray = [];
|
||||
|
||||
// dialog initialization code
|
||||
|
||||
function Startup()
|
||||
{
|
||||
//XXX Very weird! When calling this with an existing image,
|
||||
// we get called twice. That causes dialog layout
|
||||
// to explode to fullscreen!
|
||||
if (StartupCalled)
|
||||
{
|
||||
dump("*** CALLING IMAGE DIALOG Startup() AGAIN! ***\n");
|
||||
return;
|
||||
}
|
||||
StartupCalled = true;
|
||||
|
||||
if (!InitEditorShell())
|
||||
return;
|
||||
|
||||
ImageStartup();
|
||||
gDialog.hrefInput = document.getElementById("hrefInput");
|
||||
gDialog.makeRelativeLink = document.getElementById("MakeRelativeLink");
|
||||
gDialog.showLinkBorder = document.getElementById("showLinkBorder");
|
||||
|
||||
// Get a single selected image element
|
||||
var tagName = "img";
|
||||
if ("arguments" in window && window.arguments[0])
|
||||
{
|
||||
imageElement = window.arguments[0];
|
||||
// We've been called from form field propertes, so we can't insert a link
|
||||
var imageLinkTab = document.getElementById('imageLinkTab');
|
||||
imageLinkTab.parentNode.removeChild(imageLinkTab);
|
||||
}
|
||||
else
|
||||
{
|
||||
// First check for <input type="image">
|
||||
imageElement = editorShell.GetSelectedElement("input");
|
||||
if (!imageElement || imageElement.getAttribute("type") != "image")
|
||||
if (!imageElement || imageElement.getAttribute("type") != "image") {
|
||||
// Get a single selected image element
|
||||
imageElement = editorShell.GetSelectedElement(tagName);
|
||||
if (imageElement)
|
||||
gAnchorElement = editorShell.GetElementOrParentByTagName("href", imageElement);
|
||||
}
|
||||
}
|
||||
|
||||
if (imageElement)
|
||||
|
@ -66,8 +66,8 @@ function Startup()
|
|||
if (imageElement.hasAttribute("src"))
|
||||
{
|
||||
gInsertNewImage = false;
|
||||
actualWidth = imageElement.naturalWidth;
|
||||
actualHeight = imageElement.naturalHeight;
|
||||
gActualWidth = imageElement.naturalWidth;
|
||||
gActualHeight = imageElement.naturalHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -84,6 +84,7 @@ function Startup()
|
|||
window.close();
|
||||
return;
|
||||
}
|
||||
gAnchorElement = editorShell.GetSelectedElement(tagName);
|
||||
}
|
||||
|
||||
// Make a copy to use for AdvancedEdit
|
||||
|
@ -93,6 +94,12 @@ function Startup()
|
|||
gHaveDocumentUrl = GetDocumentBaseUrl();
|
||||
|
||||
InitDialog();
|
||||
if (gAnchorElement)
|
||||
gOriginalHref = gAnchorElement.getAttribute("href");
|
||||
gDialog.hrefInput.value = gOriginalHref;
|
||||
|
||||
FillLinkMenulist(gDialog.hrefInput, gHNodeArray);
|
||||
ChangeLinkLocation();
|
||||
|
||||
// Save initial source URL
|
||||
gOriginalSrc = gDialog.srcInput.value;
|
||||
|
@ -113,6 +120,26 @@ function Startup()
|
|||
function InitDialog()
|
||||
{
|
||||
InitImage();
|
||||
gDialog.showLinkBorder.checked = gDialog.border.value != "0";
|
||||
}
|
||||
|
||||
function ChangeLinkLocation()
|
||||
{
|
||||
SetRelativeCheckbox(gDialog.makeRelativeLink);
|
||||
gDialog.showLinkBorder.disabled = !TrimString(gDialog.hrefInput.value);
|
||||
}
|
||||
|
||||
function ToggleShowLinkBorder()
|
||||
{
|
||||
if (gDialog.showLinkBorder.checked)
|
||||
{
|
||||
if (TrimString(gDialog.border.value) == "0")
|
||||
gDialog.border.value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
gDialog.border.value = "0";
|
||||
}
|
||||
}
|
||||
|
||||
// Get data from widgets, validate, and set for the global element
|
||||
|
@ -127,3 +154,113 @@ function doHelpButton()
|
|||
openHelp("chrome://help/content/help.xul?image_properties");
|
||||
return true;
|
||||
}
|
||||
|
||||
function onAccept()
|
||||
{
|
||||
// Use this now (default = false) so Advanced Edit button dialog doesn't trigger error message
|
||||
gDoAltTextError = true;
|
||||
|
||||
if (ValidateData())
|
||||
{
|
||||
if ("arguments" in window && window.arguments[0])
|
||||
{
|
||||
SaveWindowLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
editorShell.BeginBatchChanges();
|
||||
|
||||
if (gRemoveImageMap)
|
||||
{
|
||||
globalElement.removeAttribute("usemap");
|
||||
if (gImageMap)
|
||||
{
|
||||
editorShell.DeleteElement(gImageMap);
|
||||
gInsertNewIMap = true;
|
||||
gImageMap = null;
|
||||
}
|
||||
}
|
||||
else if (gImageMap)
|
||||
{
|
||||
// Assign to map if there is one
|
||||
var mapName = gImageMap.getAttribute("name");
|
||||
if (mapName != "")
|
||||
{
|
||||
globalElement.setAttribute("usemap", ("#"+mapName));
|
||||
if (globalElement.getAttribute("border") == "")
|
||||
globalElement.setAttribute("border", 0);
|
||||
}
|
||||
|
||||
if (gInsertNewIMap)
|
||||
{
|
||||
try
|
||||
{
|
||||
editorShell.editorDocument.body.appendChild(gImageMap);
|
||||
//editorShell.InsertElementAtSelection(gImageMap, false);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
dump("Exception occured in InsertElementAtSelection\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create or remove the link as appropriate
|
||||
var href = gDialog.hrefInput.value;
|
||||
if (href != gOriginalHref) {
|
||||
if (href)
|
||||
editorShell.SetTextProperty("a", "href", href);
|
||||
else
|
||||
editorShell.RemoveTextProperty("href", "");
|
||||
}
|
||||
|
||||
// All values are valid - copy to actual element in doc or
|
||||
// element created to insert
|
||||
editorShell.CloneAttributes(imageElement, globalElement);
|
||||
if (gInsertNewImage)
|
||||
{
|
||||
try {
|
||||
// 'true' means delete the selection before inserting
|
||||
editorShell.InsertElementAtSelection(imageElement, true);
|
||||
// Also move the insertion point out of the link
|
||||
if (href)
|
||||
setTimeout(editorShell.RemoveTextProperty, 0, "href", "");
|
||||
} catch (e) {
|
||||
dump(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the link was to a heading
|
||||
// Do this last because it moves the caret (BAD!)
|
||||
var index = gDialog.hrefInput.selectedIndex;
|
||||
if (index in gHNodeArray && gHNodeArray[index])
|
||||
{
|
||||
var anchorNode = editorShell.editorDocument.createElement("a");
|
||||
if (anchorNode)
|
||||
{
|
||||
anchorNode.name = href.substr(1);
|
||||
// Remember to use editorShell method so it is undoable!
|
||||
editorShell.InsertElement(anchorNode, gHNodeArray[index], 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);*/
|
||||
|
||||
editorShell.EndBatchChanges();
|
||||
|
||||
SaveWindowLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
gDoAltTextError = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -58,13 +58,19 @@
|
|||
<tab id="imageLocationTab"/>
|
||||
<tab id="imageDimensionsTab"/>
|
||||
<tab id="imageAppearanceTab"/>
|
||||
<tab id="imageLinkTab"/>
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<!-- panels overlayed from EdImageOverlay.xul -->
|
||||
<vbox id="imageLocation"/>
|
||||
<vbox id="imageDimensions"/>
|
||||
<hbox id="imageAppearance"/>
|
||||
|
||||
<vbox>
|
||||
<spacer class="spacer"/>
|
||||
<vbox id="LinkLocationBox"/>
|
||||
<spacer class="spacer"/>
|
||||
<checkbox id="showLinkBorder" label="&showImageLinkBorder.label;" oncommand="ToggleShowLinkBorder();"/>
|
||||
</vbox>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
|
||||
|
|
|
@ -137,9 +137,8 @@ function onAccept()
|
|||
// Show alt text error only once
|
||||
// (we don't initialize doAltTextError=true
|
||||
// so Advanced edit button dialog doesn't trigger that error message)
|
||||
doAltTextError = firstTimeOkUsed;
|
||||
firstTimeOkUsed = false;
|
||||
|
||||
// Use this now (default = false) so Advanced Edit button dialog doesn't trigger error message
|
||||
gDoAltTextError = true;
|
||||
|
||||
if (ValidateData())
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ var insertLinkAtCaret;
|
|||
var needLinkText = false;
|
||||
var href;
|
||||
var newLinkText;
|
||||
var HNodeArray;
|
||||
var gHNodeArray = [];
|
||||
var gHaveNamedAnchors = false;
|
||||
var gHaveHeadings = false;
|
||||
var gCanChangeHeadingSelected = true;
|
||||
|
@ -50,10 +50,7 @@ function Startup()
|
|||
gDialog.linkTextMessage = document.getElementById("linkTextMessage");
|
||||
gDialog.linkTextInput = document.getElementById("linkTextInput");
|
||||
gDialog.hrefInput = document.getElementById("hrefInput");
|
||||
gDialog.NamedAnchorList = document.getElementById("NamedAnchorList");
|
||||
gDialog.HeadingsList = document.getElementById("HeadingsList");
|
||||
gDialog.MoreSection = document.getElementById("MoreSection");
|
||||
gDialog.MoreFewerButton = document.getElementById("MoreFewerButton");
|
||||
gDialog.makeRelativeLink = document.getElementById("MakeRelativeLink");
|
||||
gDialog.AdvancedEditSection = document.getElementById("AdvancedEdit");
|
||||
|
||||
var selection = editorShell.editorSelection;
|
||||
|
@ -124,7 +121,7 @@ function Startup()
|
|||
anchorElement = editorShell.CreateElementWithDefaults(tagName);
|
||||
insertNew = true;
|
||||
// Hide message about removing existing link
|
||||
document.getElementById("RemoveLinkMsg").setAttribute("hidden","true");
|
||||
//document.getElementById("RemoveLinkMsg").setAttribute("hidden","true");
|
||||
}
|
||||
if(!anchorElement)
|
||||
{
|
||||
|
@ -193,7 +190,7 @@ function Startup()
|
|||
globalElement = anchorElement.cloneNode(false);
|
||||
|
||||
// Get the list of existing named anchors and headings
|
||||
FillListboxes();
|
||||
FillLinkMenulist(gDialog.hrefInput, gHNodeArray);
|
||||
|
||||
// We only need to test for this once per dialog load
|
||||
gHaveDocumentUrl = GetDocumentBaseUrl();
|
||||
|
@ -219,8 +216,6 @@ function Startup()
|
|||
gDialog.linkTextInput = null;
|
||||
}
|
||||
|
||||
InitMoreFewer();
|
||||
|
||||
// This sets enable state on OK button
|
||||
doEnabling();
|
||||
|
||||
|
@ -237,92 +232,7 @@ function InitDialog()
|
|||
gDialog.hrefInput.value = globalElement.getAttribute("href");
|
||||
|
||||
// Set "Relativize" checkbox according to current URL state
|
||||
SetRelativeCheckbox();
|
||||
}
|
||||
|
||||
function chooseFile()
|
||||
{
|
||||
// Get a local file, converted into URL format
|
||||
var fileName = GetLocalFileURL("html, img");
|
||||
if (fileName)
|
||||
{
|
||||
// Always try to relativize local file URLs
|
||||
if (gHaveDocumentUrl)
|
||||
fileName = MakeRelativeUrl(fileName);
|
||||
|
||||
gDialog.hrefInput.value = fileName;
|
||||
|
||||
SetRelativeCheckbox();
|
||||
doEnabling();
|
||||
}
|
||||
// Put focus into the input field
|
||||
SetTextboxFocus(gDialog.hrefInput);
|
||||
}
|
||||
|
||||
function FillListboxes()
|
||||
{
|
||||
var NamedAnchorNodeList = editorShell.editorDocument.anchors;
|
||||
var NamedAnchorCount = NamedAnchorNodeList.length;
|
||||
var item;
|
||||
if (NamedAnchorCount > 0)
|
||||
{
|
||||
for (var i = 0; i < NamedAnchorCount; i++)
|
||||
AppendStringToTreelist(gDialog.NamedAnchorList, NamedAnchorNodeList.item(i).name);
|
||||
|
||||
gHaveNamedAnchors = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message to tell user there are none
|
||||
item = AppendStringToTreelistById(gDialog.NamedAnchorList, "NoNamedAnchors");
|
||||
if (item) item.setAttribute("disabled", "true");
|
||||
}
|
||||
var firstHeading = true;
|
||||
for (var j = 1; j <= 6; j++)
|
||||
{
|
||||
var headingList = editorShell.editorDocument.getElementsByTagName("h"+String(j));
|
||||
for (var k = 0; k < headingList.length; k++)
|
||||
{
|
||||
var heading = headingList.item(k);
|
||||
|
||||
// Skip headings that already have a named anchor as their first child
|
||||
// (this may miss nearby anchors, but at least we don't insert another
|
||||
// under the same heading)
|
||||
var child = heading.firstChild;
|
||||
if (child && child.nodeName == "A" && child.name && (child.name.length>0))
|
||||
continue;
|
||||
|
||||
var range = editorShell.editorDocument.createRange();
|
||||
range.setStart(heading,0);
|
||||
var lastChildIndex = heading.childNodes.length;
|
||||
range.setEnd(heading,lastChildIndex);
|
||||
var text = range.toString();
|
||||
if (text)
|
||||
{
|
||||
// Use just first 40 characters, don't add "...",
|
||||
// and replace whitespace with "_" and strip non-word characters
|
||||
text = ConvertToCDATAString(TruncateStringAtWordEnd(text, 40, false));
|
||||
// Append "_" to any name already in the list
|
||||
if (GetExistingHeadingIndex(text) > -1)
|
||||
text += "_";
|
||||
AppendStringToTreelist(gDialog.HeadingsList, text);
|
||||
|
||||
// Save nodes in an array so we can create anchor node under it later
|
||||
if (!HNodeArray)
|
||||
HNodeArray = new Array(heading)
|
||||
else
|
||||
HNodeArray[HNodeArray.length] = heading;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (HNodeArray)
|
||||
{
|
||||
gHaveHeadings = true;
|
||||
} else {
|
||||
// Message to tell user there are none
|
||||
item = AppendStringToTreelistById(gDialog.HeadingsList, "NoHeadings");
|
||||
if (item) item.setAttribute("disabled", "true");
|
||||
}
|
||||
SetRelativeCheckbox(gDialog.makeRelativeLink);
|
||||
}
|
||||
|
||||
function doEnabling()
|
||||
|
@ -337,93 +247,14 @@ function doEnabling()
|
|||
SetElementEnabledById( "AdvancedEditButton1", enable);
|
||||
}
|
||||
|
||||
var gClearListSelections = true;
|
||||
|
||||
function ChangeLocation()
|
||||
function ChangeLinkLocation()
|
||||
{
|
||||
if (gClearListSelections)
|
||||
{
|
||||
// Unselect the treelists
|
||||
UnselectNamedAnchor();
|
||||
UnselectHeadings();
|
||||
}
|
||||
|
||||
SetRelativeCheckbox();
|
||||
|
||||
// Set OK button enable state
|
||||
doEnabling();
|
||||
}
|
||||
|
||||
function GetExistingHeadingIndex(text)
|
||||
{
|
||||
var len = gDialog.HeadingsList.getAttribute("length");
|
||||
for (var i=0; i < len; i++)
|
||||
{
|
||||
if (GetTreelistValueAt(gDialog.HeadingsList, i) == text)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function SelectNamedAnchor()
|
||||
{
|
||||
if (gCanChangeAnchorSelected)
|
||||
{
|
||||
if (gHaveNamedAnchors)
|
||||
{
|
||||
// Prevent ChangeLocation() from unselecting the list
|
||||
gClearListSelections = false;
|
||||
gDialog.hrefInput.value = "#"+GetSelectedTreelistValue(gDialog.NamedAnchorList);
|
||||
gClearListSelections = true;
|
||||
|
||||
SetRelativeCheckbox();
|
||||
|
||||
// ChangeLocation isn't always called, so be sure Ok is enabled
|
||||
doEnabling();
|
||||
}
|
||||
else
|
||||
UnselectNamedAnchor();
|
||||
|
||||
UnselectHeadings();
|
||||
}
|
||||
}
|
||||
|
||||
function SelectHeading()
|
||||
{
|
||||
if (gCanChangeHeadingSelected)
|
||||
{
|
||||
if (gHaveHeadings)
|
||||
{
|
||||
gClearListSelections = false;
|
||||
gDialog.hrefInput.value = "#"+GetSelectedTreelistValue(gDialog.HeadingsList);
|
||||
gClearListSelections = true;
|
||||
|
||||
SetRelativeCheckbox();
|
||||
doEnabling();
|
||||
}
|
||||
else
|
||||
UnselectHeadings();
|
||||
|
||||
UnselectNamedAnchor();
|
||||
}
|
||||
}
|
||||
|
||||
function UnselectNamedAnchor()
|
||||
{
|
||||
// Prevent recursive calling of SelectNamedAnchor()
|
||||
gCanChangeAnchorSelected = false;
|
||||
gDialog.NamedAnchorList.selectedIndex = -1;
|
||||
gCanChangeAnchorSelected = true;
|
||||
}
|
||||
|
||||
function UnselectHeadings()
|
||||
{
|
||||
// Prevent recursive calling of SelectHeading()
|
||||
gCanChangeHeadingSelected = false;
|
||||
gDialog.HeadingsList.selectedIndex = -1;
|
||||
gCanChangeHeadingSelected = true;
|
||||
}
|
||||
|
||||
// Get and validate data from widgets.
|
||||
// Set attributes on globalElement so they can be accessed by AdvancedEdit()
|
||||
function ValidateData()
|
||||
|
@ -509,20 +340,16 @@ function onAccept()
|
|||
// Check if the link was to a heading
|
||||
if (href[0] == "#")
|
||||
{
|
||||
var name = href.substr(1);
|
||||
var index = GetExistingHeadingIndex(name);
|
||||
if (index >= 0) {
|
||||
// We need to create a named anchor
|
||||
// and insert it as the first child of the heading element
|
||||
var headNode = HNodeArray[index];
|
||||
var index = gDialog.hrefInput.selectedIndex;
|
||||
if (index in gHNodeArray && gHNodeArray[index])
|
||||
{
|
||||
var anchorNode = editorShell.editorDocument.createElement("a");
|
||||
if (anchorNode) {
|
||||
anchorNode.name = name;
|
||||
if (anchorNode)
|
||||
{
|
||||
anchorNode.name = href.substr(1);
|
||||
// Remember to use editorShell method so it is undoable!
|
||||
editorShell.InsertElement(anchorNode, headNode, 0, false);
|
||||
editorShell.InsertElement(anchorNode, gHNodeArray[index], 0, false);
|
||||
}
|
||||
} else {
|
||||
dump("HREF is a heading but is not in the list!\n");
|
||||
}
|
||||
}
|
||||
editorShell.EndBatchChanges();
|
||||
|
|
|
@ -49,38 +49,14 @@
|
|||
|
||||
<vbox style="min-width: 20em">
|
||||
<groupbox><caption id="linkTextCaption"/>
|
||||
<vbox>
|
||||
<label id="linkTextMessage"/>
|
||||
<textbox id="linkTextInput" flex="1"/>
|
||||
<textbox id="linkTextInput"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox><caption label="&LinkURLBox.label;"/>
|
||||
<label value="&LinkURLEditField.label;"/>
|
||||
<textbox id="hrefInput" flex="1" style="min-width: 18em" oninput="ChangeLocation()"/>
|
||||
<hbox align="center">
|
||||
<!-- from EdDialogOverlay.xul 'for' identifies the textfield to get URL from -->
|
||||
<checkbox id="MakeRelativeCheckbox" for="hrefInput"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="ChooseFile"/>
|
||||
</hbox>
|
||||
<description class="wrap" flex="1" id="RemoveLinkMsg" style="margin-bottom: 7px">&RemoveLinkMsg.label;</description>
|
||||
<spacer class="smallspacer"/>
|
||||
<hbox align="start">
|
||||
<button id="MoreFewerButton" oncommand="onMoreFewer()" persist="more"/>
|
||||
</hbox>
|
||||
<spacer class="spacer"/>
|
||||
<vbox id="MoreSection">
|
||||
<spacer class="spacer"/>
|
||||
<label value="&NamedAnchorMsg.label;"/>
|
||||
<tree rows="4" class="list" id="NamedAnchorList" onselect="SelectNamedAnchor()">
|
||||
<treecolgroup><treecol flex="1"/></treecolgroup>
|
||||
</tree>
|
||||
<spacer class="spacer"/>
|
||||
<label value="&HeadingMsg.label;"/>
|
||||
<tree rows="4" class="list" id="HeadingsList" onselect="SelectHeading()">
|
||||
<treecolgroup><treecol flex="1"/></treecolgroup>
|
||||
</tree>
|
||||
<label value="&HeadingMsg2.label;"/>
|
||||
</vbox>
|
||||
<vbox id="LinkLocationBox"/>
|
||||
</groupbox>
|
||||
</vbox>
|
||||
<!-- from EdDialogOverlay -->
|
||||
|
|
|
@ -25,3 +25,6 @@
|
|||
<!ENTITY chooseButton.label "Choose File...">
|
||||
<!ENTITY makeUrlRelative.label "URL is relative to page location">
|
||||
<!ENTITY makeUrlRelative.tooltip "Change between relative and absolute URL. You must first save the page to change this.">
|
||||
|
||||
<!-- Shared by Link and Image dialogs -->
|
||||
<!ENTITY LinkURLEditField.label "Enter a web page location, a local file, or select a Named Anchor or Heading from the popup list:">
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
<!ENTITY topBottomEditField.label "Top and Bottom:">
|
||||
<!ENTITY borderEditField.label "Solid Border:">
|
||||
|
||||
<!-- These controls are in the Link Box -->
|
||||
<!ENTITY showImageLinkBorder.label "Show border around linked image">
|
||||
|
||||
<!-- These controls may be added some day; currently not used -->
|
||||
<!ENTITY makePageBackgroundCheckbox.label "Make Page Background">
|
||||
<!ENTITY makePageBackgroundCheckbox.tooltip "Use image as background for your page">
|
||||
|
@ -82,5 +85,4 @@
|
|||
<!ENTITY imageLocationTab.label "Location">
|
||||
<!ENTITY imageDimensionsTab.label "Dimensions">
|
||||
<!ENTITY imageAppearanceTab.label "Appearance">
|
||||
<!-- This tab is currently not used -->
|
||||
<!ENTITY imageLinkTab.label "Link">
|
||||
|
|
|
@ -22,9 +22,3 @@
|
|||
|
||||
<!ENTITY windowTitle.label "Link Properties">
|
||||
<!ENTITY LinkURLBox.label "Link Location">
|
||||
<!ENTITY LinkURLEditField.label "Enter a web page location or local file:">
|
||||
<!ENTITY RemoveLinkButton.label "Remove Link">
|
||||
<!ENTITY NamedAnchorMsg.label "or select a Named Anchor:">
|
||||
<!ENTITY HeadingMsg.label "or select a Heading:">
|
||||
<!ENTITY HeadingMsg2.label "(A named anchor will be created automatically)">
|
||||
<!ENTITY RemoveLinkMsg.label "(Clear text to remove existing link from page.)">
|
||||
|
|
Загрузка…
Ссылка в новой задаче