Added support to use relative URLs in link and image dialogs and let user convert to/from absolute URLs, b=72583, r=brade,akkana, sr=kin

git-svn-id: svn://10.0.0.236/trunk@103003 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cmanske%netscape.com 2001-09-17 19:31:19 +00:00
parent 6f4b44bcf4
commit 8667c2b02f
8 changed files with 532 additions and 128 deletions

View File

@ -62,6 +62,7 @@ var backgroundStr = "background";
var colorStyle = "color: ";
var backColorStyle = "background-color: ";
var backImageStyle = "; background-image: url(";
var gHaveDocumentUrl = false;
// dialog initialization code
function Startup()
@ -110,6 +111,9 @@ function Startup()
defaultBackgroundColor= browserColors.BackgroundColor;
}
// We only need to test for this once per dialog load
gHaveDocumentUrl = GetDocumentBaseUrl();
InitDialog();
if (dialog.DefaultColorsRadio.checked)
@ -124,12 +128,14 @@ function InitDialog()
{
// Get image from document
backgroundImage = globalElement.getAttribute(backgroundStr);
if (backgroundImage.length > 0)
if (backgroundImage.length)
{
dialog.BackgroundImageInput.value = backgroundImage;
dialog.ColorPreview.setAttribute(styleStr, backImageStyle+backgroundImage+");");
}
SetRelativeCheckbox();
customTextColor = globalElement.getAttribute(textStr);
customLinkColor = globalElement.getAttribute(linkStr);
customActiveColor = globalElement.getAttribute(alinkStr);
@ -324,7 +330,14 @@ function chooseFile()
var fileName = GetLocalFileURL("img");
if (fileName)
{
// Always try to relativize local file URLs
if (gHaveDocumentUrl)
fileName = MakeRelativeUrl(fileName);
dialog.BackgroundImageInput.value = fileName;
SetRelativeCheckbox();
ValidateAndPreviewImage(true);
}
SetTextboxFocus(dialog.BackgroundImageInput);
@ -334,6 +347,7 @@ function ChangeBackgroundImage()
{
// Don't show error message for image while user is typing
ValidateAndPreviewImage(false);
SetRelativeCheckbox();
}
function ValidateAndPreviewImage(ShowErrorMessage)
@ -347,7 +361,8 @@ function ValidateAndPreviewImage(ShowErrorMessage)
{
if (IsValidImage(image))
{
backgroundImage = image;
backgroundImage = gHaveDocumentUrl ? MakeAbsoluteUrl(image) : image;
// Append image style
styleValue += backImageStyle+backgroundImage+");";
}

View File

@ -133,23 +133,21 @@
</groupbox>
<spring class="spacer"/>
<text class="label" value="&backgroundImage.label;"/>
<grid flex="1">
<columns><column flex="10"/><column flex="1"/></columns>
<rows>
<row autostretch="never" valign="middle" style="margin-bottom: 5px">
<textbox id="BackgroundImageInput" oninput="ChangeBackgroundImage()"
tooltip="aTooltip" tooltiptext="&backgroundImage.tooltip;"
style="min-width : 21em"/>
<!-- from EdDialogOverlay.xul -->
<button class="dialog" id="ChooseFile"/>
</row>
<row autostretch="never" valign="middle">
<spring flex="1"/>
<!-- from EdDialogOverlay.xul -->
<button class="dialog" id="AdvancedEditButton"/>
</row>
</rows>
</grid>
<hbox>
<textbox id="BackgroundImageInput" oninput="ChangeBackgroundImage()"
tooltip="aTooltip" tooltiptext="&backgroundImage.tooltip;"
style="min-width : 21em"/>
<!-- from EdDialogOverlay.xul -->
<button class="dialog" id="ChooseFile"/>
</hbox>
<!-- from EdDialogOverlay.xul 'for' identifies the textfield to get URL from -->
<checkbox id="MakeRelativeCheckbox" for="BackgroundImageInput"/>
<spring class="smallspacer"/>
<hbox>
<spring flex="1"/>
<!-- from EdDialogOverlay.xul -->
<button class="dialog" id="AdvancedEditButton"/>
</hbox>
<separator class="groove"/>
<hbox id="okCancelButtons"/>
<hbox id="okCancelButtonsRight"/>
</window>

View File

@ -44,6 +44,11 @@ var gOutputAbsoluteLinks = 128;
var gOutputEncodeEntities = 256;
var gStringBundle;
var gValidationError = false;
var gIOService;
var gOS = "";
const gWin = "Win";
const gUNIX = "UNIX";
const gMac = "Mac";
// Use for 'defaultIndex' param in InitPixelOrPercentMenulist
var gPixel = 0;
@ -1172,3 +1177,365 @@ function TextIsURI(selectedText)
}
return false;
}
function SetRelativeCheckbox()
{
var checkbox = document.getElementById("MakeRelativeCheckbox");
if (!checkbox)
return;
var input = document.getElementById(checkbox.getAttribute("for"));
if (!input)
return;
var url = TrimString(input.value);
var urlScheme = GetScheme(url);
// Check it if url is relative (no scheme).
checkbox.checked = url.length > 0 && !urlScheme;
// Now do checkbox enabling:
var enable = false;
var docUrl = GetDocumentBaseUrl();
var docScheme = GetScheme(docUrl);
if (url && docUrl && docScheme)
{
if (urlScheme)
{
// Url is absolute, scheme and host must be the same
if (urlScheme == docScheme)
{
var urlHost = GetHost(url);
var docHost = GetHost(docUrl);
enable = (urlHost == docHost);
}
}
else
{
// Url is relative
// Check if url is a named anchor
// but document doesn't have a filename
// (it's probably "index.html" or "index.htm",
// but we don't want to allow a malformed URL)
if (url[0] == "#")
{
var docFilename = GetFilename(docUrl);
enable = docFilename.length > 0;
}
else
{
// Any other url is assumed
// to be ok to try to make absolute
enable = true;
}
}
}
SetElementEnabledById("MakeRelativeCheckbox", enable);
}
// oncommand handler for the Relativize checkbox in EditorOverlay.xul
function MakeInputValueRelativeOrAbsolute()
{
var checkbox = document.getElementById("MakeRelativeCheckbox");
if (!checkbox)
return;
var input = document.getElementById(checkbox.getAttribute("for"));
if (!input)
return;
var docUrl = GetDocumentBaseUrl();
if (!docUrl)
{
// Checkbox should be disabled if not saved,
// but keep this error message in case we change that
AlertWithTitle("", GetString("SaveToUseRelativeUrl"));
window.focus();
}
else
{
// Note that "checked" is opposite of its last state,
// which determines what we want to do here
if (checkbox.checked)
input.value = MakeRelativeUrl(input.value);
else
input.value = MakeAbsoluteUrl(input.value);
// Reset checkbox to reflect url state
SetRelativeCheckbox(checkbox, input.value);
}
}
function MakeRelativeUrl(url)
{
var inputUrl = TrimString(url);
if (!inputUrl)
return inputUrl;
// Get the filespec relative to current document's location
// NOTE: Can't do this if file isn't saved yet!
var docUrl = GetDocumentBaseUrl();
var docScheme = GetScheme(docUrl);
// Can't relativize if no doc scheme (page hasn't been saved)
if (!docScheme)
return inputUrl;
var urlScheme = GetScheme(inputUrl);
// Do nothing if not the same scheme or url is already relativized
if (docScheme != urlScheme)
return inputUrl;
var IOService = GetIOService();
if (!IOService)
return inputUrl;
// Host must be the same
var docHost = GetHost(docUrl);
var urlHost = GetHost(inputUrl);
if (docHost != urlHost)
return inputUrl;
// Get just the file path part of the urls
var docPath = IOService.extractUrlPart(docUrl, IOService.url_Directory, {start:0}, {end:0});
var urlPath = IOService.extractUrlPart(inputUrl, IOService.url_Directory, {start:0}, {end:0});
// We only return "urlPath", so we can convert
// the entire docPath for case-insensitive comparisons
var os = GetOS();
var doCaseInsensitive = (docScheme.toLowerCase() == "file" && os == gWin);
if (doCaseInsensitive)
docPath = docPath.toLowerCase();
// Get document filename before we start chopping up the docPath
var docFilename = GetFilename(docPath);
// Both url and doc paths now begin with "/"
// Look for shared dirs starting after that
urlPath = urlPath.slice(1);
docPath = docPath.slice(1);
var firstDirTest = true;
var nextDocSlash = 0;
var done = false;
// Remove all matching subdirs common to both doc and input urls
do {
nextDocSlash = docPath.indexOf("\/");
var nextUrlSlash = urlPath.indexOf("\/");
if (nextUrlSlash == -1)
{
// We're done matching and all dirs in url
// what's left is the filename
done = true;
// Remove filename for named anchors in the same file
if (nextDocSlash == -1 && docFilename)
{
var anchorIndex = urlPath.indexOf("#");
if (anchorIndex > 0)
{
var urlFilename = doCaseInsensitive ? urlPath.toLowerCase() : urlPath;
if (urlFilename.indexOf(docFilename) == 0)
urlPath = urlPath.slice(anchorIndex);
}
}
}
else if (nextDocSlash >= 0)
{
// Test for matching subdir
var docDir = docPath.slice(0, nextDocSlash);
var urlDir = urlPath.slice(0, nextUrlSlash);
if (doCaseInsensitive)
urlDir = urlDir.toLowerCase();
if (urlDir == docDir)
{
// Remove matching dir+"/" from each path
// and continue to next dir
docPath = docPath.slice(nextDocSlash+1);
urlPath = urlPath.slice(nextUrlSlash+1);
}
else
{
// No match, we're done
done = true;
// Be sure we are on the same local drive or volume
// (the first "dir" in the path) because we can't
// relativize to different drives/volumes.
// UNIX doesn't have volumes, so we must not do this else
// the first directory will be misinterpreted as a volume name
if (firstDirTest && docScheme == "file" && os != gUNIX)
return inputUrl;
}
}
else // No more doc dirs left, we're done
done = true;
firstDirTest = false;
}
while (!done);
// Add "../" for each dir left in docPath
while (nextDocSlash > 0)
{
urlPath = "../" + urlPath;
nextDocSlash = docPath.indexOf("\/", nextDocSlash+1);
}
return urlPath;
}
function MakeAbsoluteUrl(url)
{
var resultUrl = TrimString(url);
if (!resultUrl)
return resultUrl;
// Check if URL is already absolute, i.e., it has a scheme
var urlScheme = GetScheme(resultUrl);
if (urlScheme)
return resultUrl;
var docUrl = GetDocumentBaseUrl();
var docScheme = GetScheme(docUrl);
// Can't relativize if no doc scheme (page hasn't been saved)
if (!docScheme)
return resultUrl;
var IOService = GetIOService();
if (!IOService)
return resultUrl;
// Make a URI object to use its "resolve" method
var absoluteUrl = resultUrl;
var docUri = IOService.newURI(docUrl, null);
try {
absoluteUrl = docUri.resolve(resultUrl);
// This is deprecated and buggy!
// If used, we must make it a path for the parent directory (remove filename)
//absoluteUrl = IOService.resolveRelativePath(resultUrl, docUrl);
} catch (e) {}
return absoluteUrl;
}
// Get the HREF of the page's <base> tag or the document location
// returns empty string if no base href and document hasn't been saved yet
function GetDocumentBaseUrl()
{
if (window.editorShell)
{
var docUrl;
// if document supplies a <base> tag, use that URL instead
var baseList = editorShell.editorDocument.getElementsByTagName("base");
if (baseList)
{
var base = baseList.item(0);
if (base)
docUrl = base.getAttribute("href");
}
if (!docUrl)
docUrl = editorShell.editorDocument.location.href;
if (docUrl != "about:blank")
return docUrl;
}
return "";
}
function GetIOService()
{
if (gIOService)
return gIOService;
var CID = Components.classes["@mozilla.org/network/io-service;1"];
gIOService = CID.getService(Components.interfaces.nsIIOService);
return gIOService;
}
// Extract the scheme (e.g., 'file', 'http') from a URL string
function GetScheme(url)
{
var resultUrl = TrimString(url);
// Unsaved document URL has no acceptable scheme yet
if (!resultUrl || resultUrl == "about:blank")
return "";
var IOService = GetIOService();
if (!IOService)
return "";
var scheme = "";
try {
// This fails if there's no scheme
scheme = IOService.extractScheme(resultUrl, {schemeStartPos:0}, {schemeEndPos:0});
} catch (e) {}
return scheme ? scheme : "";
}
function GetHost(url)
{
var IOService = GetIOService();
if (!IOService)
return "";
var host = "";
if (url)
{
try {
host = IOService.extractUrlPart(url, IOService.url_Host, {start:0}, {end:0});
} catch (e) {}
}
return host;
}
function GetFilename(url)
{
var IOService = GetIOService();
if (!IOService)
return "";
var filename;
if (url)
{
try {
filename = IOService.extractUrlPart(url, IOService.url_FileBaseName, {start:0}, {end:0});
if (filename)
{
var ext = IOService.extractUrlPart(url, IOService.url_FileExtension, {start:0}, {end:0});
if (ext)
filename += "."+ext;
}
} catch (e) {}
}
return filename ? filename : "";
}
function GetOS()
{
if (gOS)
return gOS;
if (navigator.platform.toLowerCase().indexOf("win") >= 0)
gOS = gWin;
else if (navigator.platform.toLowerCase().indexOf("mac") >=0)
gOS = gMac;
else
gOS = gUNIX;
return gOS;
}

View File

@ -64,4 +64,12 @@
oncommand = "chooseFile()"
label = "&chooseButton.label;"/>
<checkbox
id = "MakeRelativeCheckbox"
label = "&makeUrlRelative.label;"
oncommand = "MakeInputValueRelativeOrAbsolute()"
tooltip = "aTooltip"
tooltiptext = "&makeUrlRelative.tooltip;"
style = "margin-top: 0px"/>
</overlay>

View File

@ -42,6 +42,7 @@ var doAltTextError = false;
var actualWidth = "";
var gOriginalSrc = "";
var actualHeight = "";
var gHaveDocumentUrl = false;
// These must correspond to values in EditorDialog.css for each theme
// (unfortunately, setting "style" attribute here doesn't work!)
@ -74,11 +75,9 @@ function Startup()
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.actualSizeRadio = document.getElementById( "actualSizeRadio" );
dialog.actualSizeRadio = document.getElementById( "actualSizeRadio" );
dialog.constrainCheckbox = document.getElementById( "constrainCheckbox" );
dialog.widthInput = document.getElementById( "widthInput" );
dialog.heightInput = document.getElementById( "heightInput" );
@ -124,6 +123,9 @@ function Startup()
// Make a copy to use for AdvancedEdit
globalElement = imageElement.cloneNode(false);
// We only need to test for this once per dialog load
gHaveDocumentUrl = GetDocumentBaseUrl();
InitDialog();
// Save initial source URL
@ -155,8 +157,13 @@ function InitDialog()
{
// Set the controls to the image's attributes
dialog.srcInput.value= globalElement.getAttribute("src");
GetImageFromURL();
dialog.srcInput.value = globalElement.getAttribute("src");
// Set "Relativize" checkbox according to current URL state
SetRelativeCheckbox();
// Force loading of image from its source and show preview image
LoadPreviewImage();
dialog.altTextInput.value = globalElement.getAttribute("alt");
@ -244,10 +251,16 @@ function chooseFile()
var fileName = GetLocalFileURL("img");
if (fileName)
{
// Always try to relativize local file URLs
if (gHaveDocumentUrl)
fileName = MakeRelativeUrl(fileName);
dialog.srcInput.value = fileName;
SetRelativeCheckbox();
doOverallEnabling();
}
GetImageFromURL();
LoadPreviewImage();
// Put focus into the input field
SetTextboxFocus(dialog.srcInput);
@ -293,13 +306,13 @@ function PreviewImageLoaded()
}
}
function GetImageFromURL()
function LoadPreviewImage()
{
dialog.PreviewSize.setAttribute("collapsed", "true");
var imageSrc = dialog.srcInput.value;
if (imageSrc) imageSrc = imageSrc.trimString();
if (!imageSrc) return;
var imageSrc = TrimString(dialog.srcInput.value);
if (!imageSrc)
return;
if (IsValidImage(dialog.srcInput.value))
{
@ -307,17 +320,27 @@ function GetImageFromURL()
// Remove the image URL from image cache so it loads fresh
// (if we don't do this, loads after the first will always use image cache
// and we won't see image edit changes or be able to get actual width and height)
var IOService = GetIOService();
if (IOService)
{
// We must have an absolute URL to preview it or remove it from the cache
imageSrc = MakeAbsoluteUrl(imageSrc);
var uri = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIURI);
uri.spec = imageSrc;
var imgCacheService = Components.classes["@mozilla.org/image/cache;1"].getService();
var imgCache = imgCacheService.QueryInterface(Components.interfaces.imgICache);
// This returns error if image wasn't in the cache; ignore that
imgCache.removeEntry(uri);
if (GetScheme(imageSrc))
{
var uri = IOService.newURI(imageSrc, null);
if (uri)
{
var imgCacheService = Components.classes["@mozilla.org/image/cache;1"].getService();
var imgCache = imgCacheService.QueryInterface(Components.interfaces.imgICache);
// This returns error if image wasn't in the cache; ignore that
if (imgCache)
imgCache.removeEntry(uri);
}
}
}
} catch(e) {}
if(dialog.PreviewImage)
@ -347,39 +370,11 @@ function SetActualSize()
function ChangeImageSrc()
{
GetImageFromURL();
SetRelativeCheckbox();
LoadPreviewImage();
doOverallEnabling();
}
// This overrides the default onMoreFewer in EdDialogCommon.js
function onMoreFewer()
{
if (SeeMore)
{
dialog.MoreSection.setAttribute("collapsed","true");
dialog.MoreFewerButton.setAttribute("label", GetString("MoreProperties"));
dialog.MoreFewerButton.setAttribute("more","0");
SeeMore = false;
// Show the "Advanced Edit" button on same line as "More Properties"
dialog.AdvancedEditButton.setAttribute("collapsed","false");
dialog.AdvancedEditButton2.setAttribute("collapsed","true");
// Weird caret appearing when we collapse, so force focus to URL textbox
dialog.srcInput.focus();
}
else
{
dialog.MoreSection.setAttribute("collapsed","false");
dialog.MoreFewerButton.setAttribute("label", GetString("FewerProperties"));
dialog.MoreFewerButton.setAttribute("more","1");
SeeMore = true;
// Show the "Advanced Edit" button at bottom
dialog.AdvancedEditButton.setAttribute("collapsed","true");
dialog.AdvancedEditButton2.setAttribute("collapsed","false");
}
window.sizeToContent();
}
function doDimensionEnabling()
{
// Enabled only if "Custom" is checked
@ -414,7 +409,6 @@ function doOverallEnabling()
wasEnableAll = canEnableOk;
SetElementEnabledById("ok", canEnableOk );
SetElementEnabledById( "imagemapLabel", canEnableOk );
//TODO: Restore when Image Map editor is finished
//SetElementEnabledById( "editImageMap", canEnableOk );

View File

@ -57,35 +57,37 @@
<groupbox orient="vertical">
<caption label="&locationBox.label;"/>
<!--/////// Src URL and ALT Text //////-->
<grid>
<columns><column/><column/><column flex="1"/></columns>
<rows>
<row align="center">
<text class = "label"
for = "srcInput"
value = "&locationEditField.label;"
tooltip="aTooltip" tooltiptext="&locationEditField.tooltip;"
/>
<textbox
id = "srcInput"
oninput = "ChangeImageSrc()"
style = "min-width : 20em"/>
<!-- from EdDialogOverlay.xul -->
<button id="ChooseFile"/>
</row>
<row align="center">
<text class = "label"
id = "altTextLabel"
for = "altTextInput"
tooltip = "aTooltip" tooltiptext="&altTextEditField.tooltip;"
value = "&altTextEditField.label;" />
<textbox
id ="altTextInput"
style = "min-width : 20em"/>
<spring/> <!-- placeholder for 3rd column -->
</row>
</rows>
</grid>
<text class = "label"
for = "srcInput"
value = "&locationEditField.label;"
tooltip="aTooltip" tooltiptext="&locationEditField.tooltip;"
/>
<textbox
id = "srcInput"
oninput = "ChangeImageSrc()"
style = "min-width : 20em"
flex = "1"/>
<hbox>
<checkbox
id = "MakeRelativeCheckbox"
for = "srcInput"/>
<spring flex="1"/>
<!-- from EdDialogOverlay.xul -->
<button id="ChooseFile"/>
</hbox>
<spring class="spacer"/>
<hbox>
<text class = "label"
id = "altTextLabel"
for = "altTextInput"
tooltip = "aTooltip" tooltiptext="&altTextEditField.tooltip;"
value = "&altTextEditField.label;"/>
<textbox
id ="altTextInput"
style = "min-width : 20em"
tooltip = "aTooltip" tooltiptext="&altTextEditField.tooltip;"
flex = "1"/>
</hbox>
<spring class="spacer"/>
</groupbox>
<spring class="spacer"/>
@ -96,8 +98,9 @@
oncommand = "onMoreFewer()"
tooltip = "aTooltip" tooltiptext = "&MoreFewerButton.tooltip;"
persist = "more"/>
<spring class="spacer"/>
<groupbox style="padding: 4px">
<spring class="bigspacer"/>
<groupbox style="padding-left: 8px; padding-right: 8px">
<caption label="&previewBox.label;"/>
<hbox id="preview-image-box" align="center">
<spring flex="1"/>
<html id="preview-image-holder"/>
@ -119,9 +122,6 @@
<spring flex="1"/>
</vbox>
</groupbox>
<spring flex="1"/>
<!-- From EdDialogOverlay.xul -->
<button id="AdvancedEditButton"/>
</hbox>
<spring class="spacer"/>
<!-- Area that shows and hides via MoreFewerButton -->
@ -288,16 +288,9 @@
</groupbox>
</vbox> <!-- Bottom Right region -->
</hbox> <!-- The horizontal box -->
<!-- buttons along bottom -->
<spring class="spacer"/>
<hbox>
<spring flex="1"/>
<!-- From EdDialogOverlay -->
<button id="AdvancedEditButton2"/>
</hbox>
</vbox> <!-- END OF MORE/FEWER SECTION -->
<separator class="groove"/>
<!-- from EdDialogOverlay -->
<vbox id="AdvancedEdit"/>
<!-- from global dialogOverlay -->
<hbox id="okCancelHelpButtonsRight"/>
</window>

View File

@ -33,6 +33,7 @@ var gHaveNamedAnchors = false;
var gHaveHeadings = false;
var gCanChangeHeadingSelected = true;
var gCanChangeAnchorSelected = true;
var gHaveDocumentUrl = false;
var dialog;
// NOTE: Use "href" instead of "a" to distinguish from Named Anchor
@ -150,9 +151,10 @@ function Startup()
if (insertLinkAtCaret)
{
// Groupbox caption:
dialog.linkTextCaption.setAttribute("value",GetString("LinkText"));
dialog.linkTextCaption.setAttribute("label", GetString("LinkText"));
// Message above input field:
dialog.linkTextMessage.setAttribute("value", GetString("EnterLinkText"));
dialog.linkTextMessage.setAttribute("label", GetString("EnterLinkText"));
}
else
{
@ -182,16 +184,16 @@ function Startup()
// Set "caption" for link source and the source text or image URL
if (imageElement)
{
dialog.linkTextCaption.setAttribute("value",GetString("LinkImage"));
dialog.linkTextCaption.setAttribute("label",GetString("LinkImage"));
// Link source string is the source URL of image
// TODO: THIS DOESN'T HANDLE MULTIPLE SELECTED IMAGES!
dialog.linkTextMessage.setAttribute("value",imageElement.src);
} else {
dialog.linkTextCaption.setAttribute("value",GetString("LinkText"));
dialog.linkTextCaption.setAttribute("label",GetString("LinkText"));
if (selectedText)
{
// Use just the first 40 characters and add "..."
dialog.linkTextMessage.setAttribute("value",TruncateStringAtWordEnd(ReplaceWhitespace(selectedText, " "), 40, true));
// Use just the first 60 characters and add "..."
dialog.linkTextMessage.setAttribute("value",TruncateStringAtWordEnd(ReplaceWhitespace(selectedText, " "), 60, true));
} else {
dialog.linkTextMessage.setAttribute("value",GetString("MixedSelection"));
}
@ -204,6 +206,9 @@ function Startup()
// Get the list of existing named anchors and headings
FillListboxes();
// We only need to test for this once per dialog load
gHaveDocumentUrl = GetDocumentBaseUrl();
// Set data for the dialog controls
InitDialog();
@ -228,7 +233,7 @@ function Startup()
InitMoreFewer();
// This sets enable state on OK button
ChangeText();
doEnabling();
SetWindowLocation();
}
@ -241,16 +246,25 @@ function InitDialog()
// Must use getAttribute, not "globalElement.href",
// or foreign chars aren't coverted correctly!
dialog.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");
if (fileName) {
if (fileName)
{
// Always try to relativize local file URLs
if (gHaveDocumentUrl)
fileName = MakeRelativeUrl(fileName);
dialog.hrefInput.value = fileName;
// Call this to do OK button enabling
ChangeText();
SetRelativeCheckbox();
doEnabling();
}
// Put focus into the input field
SetTextboxFocus(dialog.hrefInput);
@ -322,10 +336,11 @@ function FillListboxes()
}
}
function ChangeText()
function doEnabling()
{
// We disable Ok button when there's no href text only if inserting a new link
var enable = insertNew ? (dialog.hrefInput.value.trimString().length > 0) : true;
SetElementEnabledById( "ok", enable);
}
@ -339,8 +354,11 @@ function ChangeLocation()
UnselectNamedAnchor();
UnselectHeadings();
}
SetRelativeCheckbox();
// Set OK button enable state
ChangeText();
doEnabling();
}
function GetExistingHeadingIndex(text)
@ -365,8 +383,10 @@ function SelectNamedAnchor()
dialog.hrefInput.value = "#"+GetSelectedTreelistValue(dialog.NamedAnchorList);
gClearListSelections = true;
SetRelativeCheckbox();
// ChangeLocation isn't always called, so be sure Ok is enabled
ChangeText();
doEnabling();
}
else
UnselectNamedAnchor();
@ -385,7 +405,8 @@ function SelectHeading()
dialog.hrefInput.value = "#"+GetSelectedTreelistValue(dialog.HeadingsList);
gClearListSelections = true;
ChangeText();
SetRelativeCheckbox();
doEnabling();
}
else
UnselectHeadings();

View File

@ -26,6 +26,7 @@
<?xml-stylesheet href="chrome://editor/skin/EditorDialog.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://editor/content/EdDialogOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://editor/locale/EditorLinkProperties.dtd">
@ -45,20 +46,27 @@
<broadcaster id="args" value=""/>
<spring id="location" offsetY="50" persist="offsetX offsetY"/>
<keyset id="dialogKeys"/>
<popupset id="aTooltipSet" />
<vbox style="min-width: 20em">
<groupbox orient="vertical"><caption id="linkTextCaption"/>
<text class="label" id="linkTextMessage"/>
<textbox id="linkTextInput" flex="1" oninput="ChangeText()"/>
<textbox id="linkTextInput" flex="1"/>
</groupbox>
<groupbox orient="vertical"><caption label="&LinkURLBox.label;"/>
<text class="label" value="&LinkURLEditField.label;"/>
<hbox autostretch="never" valign="middle">
<textbox id="hrefInput" flex="1" style="min-width: 18em" oninput="ChangeLocation()"/>
</hbox>
<hbox autostretch="never" valign="middle">
<!-- from EdDialogOverlay.xul 'for' identifies the textfield to get URL from -->
<checkbox id="MakeRelativeCheckbox" for="hrefInput"/>
<spring flex="1"/>
<button class="dialog" id="ChooseFile"/>
</hbox>
<html class="wrap" flex="1" id="RemoveLinkMsg" style="margin-bottom: 7px">&RemoveLinkMsg.label;</html>
<spring class="smallspacer"/>
<hbox autostretch="never">
<button class="dialog" id="MoreFewerButton" oncommand="onMoreFewer()" persist="more"/>
</hbox>