!import
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-1999
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38 /*
39 Behavior notes:
40 Radio buttons select "UseDefaultColors" vs. "UseCustomColors" modes.
41 If any color attribute is set in the body, mode is "Custom Colors",
42 even if 1 or more (but not all) are actually null (= "use default")
43 When in "Custom Colors" mode, all colors will be set on body tag,
44 even if they are just default colors, to assure compatable colors in page.
45 User cannot select "use default" for individual colors
46 */
47
48 //Cancel() is in EdDialogCommon.js
49
50 var gBodyElement;
51 var prefs;
52 var gBackgroundImage;
53
54 // Initialize in case we can't get them from prefs???
55 const defaultTextColor="#000000";
56 const defaultLinkColor="#000099";
57 const defaultActiveColor="#000099";
58 const defaultVisitedColor="#990099";
59 const defaultBackgroundColor="#FFFFFF";
60 const styleStr = "style";
61 const textStr = "text";
62 const linkStr = "link";
63 const vlinkStr = "vlink";
64 const alinkStr = "alink";
65 const bgcolorStr = "bgcolor";
66 const backgroundStr = "background";
67 const cssColorStr = "color";
68 const cssBackgroundColorStr = "background-color";
69 const cssBackgroundImageStr = "background-image";
70 const colorStyle = cssColorStr + ": ";
71 const backColorStyle = cssBackgroundColorStr + ": ";
72 const backImageStyle = "; " + cssBackgroundImageStr + ": url(";
73
74 var customTextColor;
75 var customLinkColor;
76 var customActiveColor;
77 var customVisitedColor;
78 var customBackgroundColor;
79 var previewBGColor;
80 var gHaveDocumentUrl = false;
81
82 // dialog initialization code
Startup
83 function Startup()
84 {
85 var editor = GetCurrentEditor();
86 if (!editor)
87 {
88 window.close();
89 return;
90 }
91
92 gDialog.ColorPreview = document.getElementById("ColorPreview");
93 gDialog.NormalText = document.getElementById("NormalText");
94 gDialog.LinkText = document.getElementById("LinkText");
95 gDialog.ActiveLinkText = document.getElementById("ActiveLinkText");
96 gDialog.VisitedLinkText = document.getElementById("VisitedLinkText");
97 gDialog.PageColorGroup = document.getElementById("PageColorGroup");
98 gDialog.DefaultColorsRadio = document.getElementById("DefaultColorsRadio");
99 gDialog.CustomColorsRadio = document.getElementById("CustomColorsRadio");
100 gDialog.BackgroundImageInput = document.getElementById("BackgroundImageInput");
101
102 try {
103 gBodyElement = editor.rootElement;
104 } catch (e) {}
105
106 if (!gBodyElement)
107 {
108 dump("Failed to get BODY element!\n");
109 window.close();
110 }
111
112 // Set element we will edit
113 globalElement = gBodyElement.cloneNode(false);
114
115 // Initialize default colors from browser prefs
116 var browserColors = GetDefaultBrowserColors();
117 if (browserColors)
118 {
119 // Use author's browser pref colors passed into dialog
120 defaultTextColor = browserColors.TextColor;
121 defaultLinkColor = browserColors.LinkColor;
122 defaultActiveColor = browserColors.ActiveLinkColor;
123 defaultVisitedColor = browserColors.VisitedLinkColor;
124 defaultBackgroundColor= browserColors.BackgroundColor;
125 }
126
127 // We only need to test for this once per dialog load
128 gHaveDocumentUrl = GetDocumentBaseUrl();
129
130 InitDialog();
131
132 gDialog.PageColorGroup.focus();
133
134 SetWindowLocation();
135 }
136
InitDialog
137 function InitDialog()
138 {
139 // Get image from document
140 gBackgroundImage = GetHTMLOrCSSStyleValue(globalElement, backgroundStr, cssBackgroundImageStr);
141 if (/url\((.*)\)/.test( gBackgroundImage ))
142 gBackgroundImage = RegExp.$1;
143
144 gDialog.BackgroundImageInput.value = gBackgroundImage;
145
146 if (gBackgroundImage)
147 gDialog.ColorPreview.setAttribute(styleStr, backImageStyle+gBackgroundImage+");");
148
149 SetRelativeCheckbox();
150
151 customTextColor = GetHTMLOrCSSStyleValue(globalElement, textStr, cssColorStr);
152 customTextColor = ConvertRGBColorIntoHEXColor(customTextColor);
153 customLinkColor = globalElement.getAttribute(linkStr);
154 customActiveColor = globalElement.getAttribute(alinkStr);
155 customVisitedColor = globalElement.getAttribute(vlinkStr);
156 customBackgroundColor = GetHTMLOrCSSStyleValue(globalElement, bgcolorStr, cssBackgroundColorStr);
157 customBackgroundColor = ConvertRGBColorIntoHEXColor(customBackgroundColor);
158
159 var haveCustomColor =
160 customTextColor ||
161 customLinkColor ||
162 customVisitedColor ||
163 customActiveColor ||
164 customBackgroundColor;
165
166 // Set default color explicitly for any that are missing
167 // PROBLEM: We are using "windowtext" and "window" for the Windows OS
168 // default color values. This works with CSS in preview window,
169 // but we should NOT use these as values for HTML attributes!
170
171 if (!customTextColor) customTextColor = defaultTextColor;
172 if (!customLinkColor) customLinkColor = defaultLinkColor;
173 if (!customActiveColor) customActiveColor = defaultActiveColor;
174 if (!customVisitedColor) customVisitedColor = defaultVisitedColor;
175 if (!customBackgroundColor) customBackgroundColor = defaultBackgroundColor;
176
177 if (haveCustomColor)
178 {
179 // If any colors are set, then check the "Custom" radio button
180 gDialog.PageColorGroup.selectedItem = gDialog.CustomColorsRadio;
181 UseCustomColors();
182 }
183 else
184 {
185 gDialog.PageColorGroup.selectedItem = gDialog.DefaultColorsRadio;
186 UseDefaultColors();
187 }
188 }
189
GetColorAndUpdate
190 function GetColorAndUpdate(ColorWellID)
191 {
192 // Only allow selecting when in custom mode
193 if (!gDialog.CustomColorsRadio.selected) return;
194
195 var colorWell = document.getElementById(ColorWellID);
196 if (!colorWell) return;
197
198 // Don't allow a blank color, i.e., using the "default"
199 var colorObj = { NoDefault:true, Type:"", TextColor:0, PageColor:0, Cancel:false };
200
201 switch( ColorWellID )
202 {
203 case "textCW":
204 colorObj.Type = "Text";
205 colorObj.TextColor = customTextColor;
206 break;
207 case "linkCW":
208 colorObj.Type = "Link";
209 colorObj.TextColor = customLinkColor;
210 break;
211 case "activeCW":
212 colorObj.Type = "ActiveLink";
213 colorObj.TextColor = customActiveColor;
214 break;
215 case "visitedCW":
216 colorObj.Type = "VisitedLink";
217 colorObj.TextColor = customVisitedColor;
218 break;
219 case "backgroundCW":
220 colorObj.Type = "Page";
221 colorObj.PageColor = customBackgroundColor;
222 break;
223 }
224
225 window.openDialog("chrome://editor/content/EdColorPicker.xul", "_blank", "chrome,close,titlebar,modal", "", colorObj);
226
227 // User canceled the dialog
228 if (colorObj.Cancel)
229 return;
230
231 var color = "";
232 switch( ColorWellID )
233 {
234 case "textCW":
235 color = customTextColor = colorObj.TextColor;
236 break;
237 case "linkCW":
238 color = customLinkColor = colorObj.TextColor;
239 break;
240 case "activeCW":
241 color = customActiveColor = colorObj.TextColor;
242 break;
243 case "visitedCW":
244 color = customVisitedColor = colorObj.TextColor;
245 break;
246 case "backgroundCW":
247 color = customBackgroundColor = colorObj.BackgroundColor;
248 break;
249 }
250
251 setColorWell(ColorWellID, color);
252 SetColorPreview(ColorWellID, color);
253 }
254
SetColorPreview
255 function SetColorPreview(ColorWellID, color)
256 {
257 switch( ColorWellID )
258 {
259 case "textCW":
260 gDialog.NormalText.setAttribute(styleStr,colorStyle+color);
261 break;
262 case "linkCW":
263 gDialog.LinkText.setAttribute(styleStr,colorStyle+color);
264 break;
265 case "activeCW":
266 gDialog.ActiveLinkText.setAttribute(styleStr,colorStyle+color);
267 break;
268 case "visitedCW":
269 gDialog.VisitedLinkText.setAttribute(styleStr,colorStyle+color);
270 break;
271 case "backgroundCW":
272 // Must combine background color and image style values
273 var styleValue = backColorStyle+color;
274 if (gBackgroundImage)
275 styleValue += ";"+backImageStyle+gBackgroundImage+");";
276
277 gDialog.ColorPreview.setAttribute(styleStr,styleValue);
278 previewBGColor = color;
279 break;
280 }
281 }
282
UseCustomColors
283 function UseCustomColors()
284 {
285 SetElementEnabledById("TextButton", true);
286 SetElementEnabledById("LinkButton", true);
287 SetElementEnabledById("ActiveLinkButton", true);
288 SetElementEnabledById("VisitedLinkButton", true);
289 SetElementEnabledById("BackgroundButton", true);
290 SetElementEnabledById("Text", true);
291 SetElementEnabledById("Link", true);
292 SetElementEnabledById("Active", true);
293 SetElementEnabledById("Visited", true);
294 SetElementEnabledById("Background", true);
295
296 SetColorPreview("textCW", customTextColor);
297 SetColorPreview("linkCW", customLinkColor);
298 SetColorPreview("activeCW", customActiveColor);
299 SetColorPreview("visitedCW", customVisitedColor);
300 SetColorPreview("backgroundCW", customBackgroundColor);
301
302 setColorWell("textCW", customTextColor);
303 setColorWell("linkCW", customLinkColor);
304 setColorWell("activeCW", customActiveColor);
305 setColorWell("visitedCW", customVisitedColor);
306 setColorWell("backgroundCW", customBackgroundColor);
307 }
308
UseDefaultColors
309 function UseDefaultColors()
310 {
311 SetColorPreview("textCW", defaultTextColor);
312 SetColorPreview("linkCW", defaultLinkColor);
313 SetColorPreview("activeCW", defaultActiveColor);
314 SetColorPreview("visitedCW", defaultVisitedColor);
315 SetColorPreview("backgroundCW", defaultBackgroundColor);
316
317 // Setting to blank color will remove color from buttons,
318 setColorWell("textCW", "");
319 setColorWell("linkCW", "");
320 setColorWell("activeCW", "");
321 setColorWell("visitedCW", "");
322 setColorWell("backgroundCW", "");
323
324 // Disable color buttons and labels
325 SetElementEnabledById("TextButton", false);
326 SetElementEnabledById("LinkButton", false);
327 SetElementEnabledById("ActiveLinkButton", false);
328 SetElementEnabledById("VisitedLinkButton", false);
329 SetElementEnabledById("BackgroundButton", false);
330 SetElementEnabledById("Text", false);
331 SetElementEnabledById("Link", false);
332 SetElementEnabledById("Active", false);
333 SetElementEnabledById("Visited", false);
334 SetElementEnabledById("Background", false);
335 }
336
chooseFile
337 function chooseFile()
338 {
339 // Get a local image file, converted into URL format
340 var fileName = GetLocalFileURL("img");
341 if (fileName)
342 {
343 // Always try to relativize local file URLs
344 if (gHaveDocumentUrl)
345 fileName = MakeRelativeUrl(fileName);
346
347 gDialog.BackgroundImageInput.value = fileName;
348
349 SetRelativeCheckbox();
350
351 ValidateAndPreviewImage(true);
352 }
353 SetTextboxFocus(gDialog.BackgroundImageInput);
354 }
355
ChangeBackgroundImage
356 function ChangeBackgroundImage()
357 {
358 // Don't show error message for image while user is typing
359 ValidateAndPreviewImage(false);
360 SetRelativeCheckbox();
361 }
362
ValidateAndPreviewImage
363 function ValidateAndPreviewImage(ShowErrorMessage)
364 {
365 // First make a string with just background color
366 var styleValue = backColorStyle+previewBGColor+";";
367
368 var retVal = true;
369 var image = TrimString(gDialog.BackgroundImageInput.value);
370 if (image)
371 {
372 gBackgroundImage = image;
373
374 // Display must use absolute URL if possible
375 var displayImage = gHaveDocumentUrl ? MakeAbsoluteUrl(image) : image;
376 styleValue += backImageStyle+displayImage+");";
377 }
378 else gBackgroundImage = null;
379
380 // Set style on preview (removes image if not valid)
381 gDialog.ColorPreview.setAttribute(styleStr, styleValue);
382
383 // Note that an "empty" string is valid
384 return retVal;
385 }
386
ValidateData
387 function ValidateData()
388 {
389 var editor = GetCurrentEditor();
390 try {
391 // Colors values are updated as they are picked, no validation necessary
392 if (gDialog.DefaultColorsRadio.selected)
393 {
394 editor.removeAttributeOrEquivalent(globalElement, textStr, true);
395 globalElement.removeAttribute(linkStr);
396 globalElement.removeAttribute(vlinkStr);
397 globalElement.removeAttribute(alinkStr);
398 editor.removeAttributeOrEquivalent(globalElement, bgcolorStr, true);
399 }
400 else
401 {
402 //Do NOT accept the CSS "WindowsOS" color strings!
403 // Problem: We really should try to get the actual color values
404 // from windows, but I don't know how to do that!
405 var tmpColor = customTextColor.toLowerCase();
406 if (tmpColor != "windowtext")
407 editor.setAttributeOrEquivalent(globalElement, textStr,
408 customTextColor, true);
409 else
410 editor.removeAttributeOrEquivalent(globalElement, textStr, true);
411
412 tmpColor = customBackgroundColor.toLowerCase();
413 if (tmpColor != "window")
414 editor.setAttributeOrEquivalent(globalElement, bgcolorStr, customBackgroundColor, true);
415 else
416 editor.removeAttributeOrEquivalent(globalElement, bgcolorStr, true);
417
418 globalElement.setAttribute(linkStr, customLinkColor);
419 globalElement.setAttribute(vlinkStr, customVisitedColor);
420 globalElement.setAttribute(alinkStr, customActiveColor);
421 }
422
423 if (ValidateAndPreviewImage(true))
424 {
425 // A valid image may be null for no image
426 if (gBackgroundImage)
427 globalElement.setAttribute(backgroundStr, gBackgroundImage);
428 else
429 editor.removeAttributeOrEquivalent(globalElement, backgroundStr, true);
430
431 return true;
432 }
433 } catch (e) {}
434 return false;
435 }
436
onAccept
437 function onAccept()
438 {
439 if (ValidateData())
440 {
441 // Copy attributes to element we are changing
442 try {
443 GetCurrentEditor().cloneAttributes(gBodyElement, globalElement);
444 } catch (e) {}
445
446 SaveWindowLocation();
447 return true; // do close the window
448 }
449 return false;
450 }