mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-11 02:10:17 +01:00
1257 lines
44 KiB
JavaScript
1257 lines
44 KiB
JavaScript
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
||
|
*
|
||
|
* 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 CaScadeS, a stylesheet editor for Composer.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is
|
||
|
* Daniel Glazman.
|
||
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
||
|
* the Initial Developer. All Rights Reserved.
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
* Original author: Daniel Glazman <daniel@glazman.org>
|
||
|
* Charley Manske <cmanske@netscape.com>, for local fonts access
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||
|
* of those above. If you wish to allow use of your version of this file only
|
||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||
|
* use your version of this file under the terms of the MPL, indicate your
|
||
|
* decision by deleting the provisions above and replace them with the notice
|
||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||
|
* the provisions above, a recipient may use your version of this file under
|
||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
|
||
|
var gTimerID;
|
||
|
var textColor, backgroundColor, borderColor;
|
||
|
var gLocalFonts = null;
|
||
|
const kUrlString = "url(";
|
||
|
|
||
|
|
||
|
// * if |value| is not empty, sets the CSS property |property| to |value|
|
||
|
// in |elt| element's inline styles ; otherwise removes the property
|
||
|
// param XULElement elt
|
||
|
// param String property
|
||
|
// param String value
|
||
|
function AddStyleToElement(elt, property, value)
|
||
|
{
|
||
|
if (!elt || !elt.style) return;
|
||
|
if (value == "") {
|
||
|
elt.style.removeProperty(property);
|
||
|
}
|
||
|
else {
|
||
|
try {
|
||
|
elt.style.setProperty(property, value,
|
||
|
elt.style.getPropertyPriority(property));
|
||
|
}
|
||
|
catch (ex) { }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Callback from font-family selection XUL elts
|
||
|
// param String fontFamily
|
||
|
function onFontFamilySelect(fontFamily)
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
var enableCustomInput = false;
|
||
|
var enablePredefMenu = false;
|
||
|
if (fontFamily == "") {
|
||
|
// nothing to do here
|
||
|
}
|
||
|
else if (fontFamily == "-user-defined") {
|
||
|
// user wants to select a font that is not pre-defined
|
||
|
// so let's get that user defined name from the textarea
|
||
|
enableCustomInput = true;
|
||
|
fontFamily = gDialog.customFontFamilyInput.value;
|
||
|
}
|
||
|
else if (fontFamily == "-predefined"){
|
||
|
fontFamily = "";
|
||
|
enablePredefMenu = true;
|
||
|
// user wants a predefined font family
|
||
|
var valueElt = gDialog.predefFontFamilyMenulist.selectedItem;
|
||
|
if (valueElt) {
|
||
|
fontFamily = valueElt.value;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// all other cases are user defined fonts
|
||
|
enablePredefMenu = true;
|
||
|
}
|
||
|
|
||
|
EnableUI(gDialog.predefFontFamilyMenulist, enablePredefMenu);
|
||
|
EnableUI(gDialog.customFontFamilyInput, enableCustomInput);
|
||
|
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "font-family", fontFamily);
|
||
|
AddStyleToElement(gDialog.selectedObject, "font-family", fontFamily);
|
||
|
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when the color textarea's value is changed
|
||
|
// it sets the correspondinf property/value on the element elt
|
||
|
// and sets the color of the corresponding UI button
|
||
|
// param XULElement elt
|
||
|
// param String property
|
||
|
// param String id
|
||
|
// param String ColorWellID
|
||
|
function onColorZoneInput(elt, property, id, ColorWellID)
|
||
|
{
|
||
|
ChangeValueOnInput(elt, property, id);
|
||
|
setColorWell(ColorWellID, elt.value);
|
||
|
}
|
||
|
|
||
|
// * Opens a color picker for the requested property and handles
|
||
|
// the result
|
||
|
// param String ColorWellID
|
||
|
function GetColorAndUpdate(ColorWellID)
|
||
|
{
|
||
|
var colorObj = new Object;
|
||
|
var colorWell = document.getElementById(ColorWellID);
|
||
|
if (!colorWell) return;
|
||
|
|
||
|
// Don't allow a blank color, i.e., using the "default"
|
||
|
colorObj.NoDefault = true;
|
||
|
|
||
|
switch( ColorWellID )
|
||
|
{
|
||
|
case "textCW":
|
||
|
colorObj.Type = "Text";
|
||
|
colorObj.TextColor = textColor;
|
||
|
break;
|
||
|
case "backgroundCW":
|
||
|
colorObj.Type = "Page";
|
||
|
colorObj.PageColor = backgroundColor;
|
||
|
break;
|
||
|
case "bordertopCW":
|
||
|
case "borderleftCW":
|
||
|
case "borderrightCW":
|
||
|
case "borderbottomCW":
|
||
|
colorObj.Type = "Text";
|
||
|
colorObj.TextColor = borderColor;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
window.openDialog("chrome://editor/content/EdColorPicker.xul", "_blank", "chrome,close,titlebar,modal", "", colorObj);
|
||
|
|
||
|
// User canceled the dialog
|
||
|
if (colorObj.Cancel)
|
||
|
return;
|
||
|
|
||
|
var color = "";
|
||
|
var property = "";
|
||
|
var textZone = null;
|
||
|
switch( ColorWellID )
|
||
|
{
|
||
|
case "textCW":
|
||
|
color = textColor = colorObj.TextColor;
|
||
|
property = "color";
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "color", color);
|
||
|
textZone = gDialog.textColorInput;
|
||
|
break;
|
||
|
case "backgroundCW":
|
||
|
color = backgroundColor = colorObj.BackgroundColor;
|
||
|
property = "background-color";
|
||
|
textZone = gDialog.backgroundColorInput;
|
||
|
break;
|
||
|
case "bordertopCW":
|
||
|
color = textColor = colorObj.TextColor;
|
||
|
property = "border-top-color";
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-top-color", color);
|
||
|
textZone = gDialog.topBorderColorInput;
|
||
|
break;
|
||
|
case "borderleftCW":
|
||
|
color = textColor = colorObj.TextColor;
|
||
|
property = "border-left-color";
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-left-color", color);
|
||
|
textZone = gDialog.leftBorderColorInput;
|
||
|
break;
|
||
|
case "borderrightCW":
|
||
|
color = textColor = colorObj.TextColor;
|
||
|
property = "border-right-color";
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-right-color", color);
|
||
|
textZone = gDialog.rightBorderColorInput;
|
||
|
break;
|
||
|
case "borderbottomCW":
|
||
|
color = textColor = colorObj.TextColor;
|
||
|
property = "border-bottom-color";
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-bottom-color", color);
|
||
|
textZone = gDialog.bottomBorderColorInput;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
setColorWell(ColorWellID, color);
|
||
|
if (textZone != null) {
|
||
|
textZone.value = color;
|
||
|
if (ColorWellID == "bordertopCW")
|
||
|
IfFourSidesSameStyle('border', 'color', color, 'allFourBordersSame', 'borderPreview', null);
|
||
|
else if (ColorWellID == "backgroundCW")
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-color", color);
|
||
|
}
|
||
|
try {
|
||
|
gDialog.selectedObject.style.setProperty(property,
|
||
|
color,
|
||
|
gDialog.selectedObject.style.getPropertyPriority(property));
|
||
|
}
|
||
|
catch (ex) {}
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when a textarea's value is changed
|
||
|
// it sets the corresponding property/value on the element elt
|
||
|
// param XULElement elt
|
||
|
// param String property
|
||
|
// param String id
|
||
|
function ChangeValueOnInput(elt, property, id)
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
var value = elt.value;
|
||
|
if (id != null) {
|
||
|
elt = document.getElementById(id);
|
||
|
if (elt) {
|
||
|
AddStyleToElement(elt, property, value);
|
||
|
}
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, property, value);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when a pulldown menu entry is selected
|
||
|
// param String property
|
||
|
// param String value
|
||
|
// param String id
|
||
|
function onPullDownChanged(property, value, id)
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
if (id != null) {
|
||
|
var elt = document.getElementById(id);
|
||
|
if (elt) {
|
||
|
AddStyleToElement(elt, property, value);
|
||
|
}
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, property, value);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when the 'none' value is selected for the
|
||
|
// 'text-decoration' property; it unchecks all other checkboxes
|
||
|
// if the 'none' checkbox is checked
|
||
|
function onNoneTextDecorationChange()
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
|
||
|
var textDecoration = "";
|
||
|
if (gDialog.noDecorationCheckbox.checked) {
|
||
|
// uncheck other possible values for the property if 'none' is checked
|
||
|
gDialog.textUnderlineCheckbox.checked = false;
|
||
|
gDialog.textOverlineCheckbox.checked = false;
|
||
|
gDialog.textLinethroughCheckbox.checked = false;
|
||
|
gDialog.textBlinkCheckbox.checked = false;
|
||
|
textDecoration = "none";
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, "text-decoration", textDecoration);
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "text-decoration", textDecoration);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when one of the chekboxes but for 'none' for
|
||
|
// 'text-decoration' property sees his state changed ; it
|
||
|
// recomputes the value of the property appending the various
|
||
|
// individual values
|
||
|
function onTextDecorationChange()
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
|
||
|
var textDecoration = "";
|
||
|
if (gDialog.textUnderlineCheckbox.checked) textDecoration += "underline ";
|
||
|
if (gDialog.textOverlineCheckbox.checked) textDecoration += "overline ";
|
||
|
if (gDialog.textLinethroughCheckbox.checked) textDecoration += "line-through ";
|
||
|
if (gDialog.textBlinkCheckbox.checked) textDecoration += "blink ";
|
||
|
if (textDecoration != "") {
|
||
|
gDialog.noDecorationCheckbox.checked = false;
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, "text-decoration", textDecoration);
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "text-decoration", textDecoration);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * This function sets a timer when the user changes an image URL
|
||
|
// in a textarea. This leaves the user enough time to complete the
|
||
|
// URL and avoids Gecko trying to load an incomplete URL
|
||
|
function ChangeImageSrc()
|
||
|
{
|
||
|
if (gTimerID)
|
||
|
clearTimeout(gTimerID);
|
||
|
|
||
|
gTimerID = setTimeout("onBgImageUrlChanged()", 800);
|
||
|
}
|
||
|
|
||
|
// * This is the callback from ChangeImageSrc(). It loads an image and uses
|
||
|
// the cache.
|
||
|
function onBgImageUrlChanged()
|
||
|
{
|
||
|
var property = "background-image";
|
||
|
var id = "backgroundPreview";
|
||
|
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
var value = gDialog.backgroundImageInput.value;
|
||
|
if (value != "" && value != "none") {
|
||
|
try {
|
||
|
// 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
|
||
|
value = MakeAbsoluteUrl(value);
|
||
|
|
||
|
if (GetScheme(value))
|
||
|
{
|
||
|
var uri = IOService.newURI(value, null, 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
|
||
|
imgCache.removeEntry(uri);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch(e) {}
|
||
|
value = kUrlString + value + ")";
|
||
|
}
|
||
|
if (id != null) {
|
||
|
var xulElt = document.getElementById(id);
|
||
|
if (xulElt) {
|
||
|
AddStyleToElement(xulElt, property, value);
|
||
|
}
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, property, value);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
|
||
|
if (property == "background-image") {
|
||
|
enableBackgroundProps((value != ""));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * This function enable some of the background-* properties that
|
||
|
// only make sense if there is a background image specified
|
||
|
// param boolean enable
|
||
|
function enableBackgroundProps(enable)
|
||
|
{
|
||
|
var idArray = [ "backgroundRepeatLabel", "backgroundRepeatMenulist", "backgroundAttachmentCheckbox",
|
||
|
"backgroundPositionLabel", "xBackgroundPositionRadiogroup",
|
||
|
"yBackgroundPositionRadiogroup" ];
|
||
|
var i, elt, lookAtNextSibling;
|
||
|
|
||
|
for (i = 0; i < idArray.length; i++) {
|
||
|
elt = document.getElementById(idArray[i]);
|
||
|
lookAtNextSibling = false;
|
||
|
if (elt.nodeName.toLowerCase() == "radiogroup") {
|
||
|
elt = elt.firstChild;
|
||
|
lookAtNextSibling = true;
|
||
|
}
|
||
|
while (elt) {
|
||
|
EnableUI(elt, enable);
|
||
|
if (lookAtNextSibling) {
|
||
|
elt = elt.nextSibling;
|
||
|
}
|
||
|
else {
|
||
|
elt = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * open a file picker dialog for the requested file filter and
|
||
|
// returns the corresponding file URL into the element of ID id
|
||
|
// param String filterType
|
||
|
// param String id
|
||
|
function chooseFile(filterType, id)
|
||
|
{
|
||
|
// Get a local image file, converted into URL format
|
||
|
var fileName = GetLocalFileURL(filterType);
|
||
|
var elt = document.getElementById(id);
|
||
|
if (fileName)
|
||
|
{
|
||
|
// Always try to relativize local file URLs
|
||
|
if (gHaveDocumentUrl)
|
||
|
fileName = MakeRelativeUrl(fileName);
|
||
|
|
||
|
elt.value = fileName;
|
||
|
onBgImageUrlChanged();
|
||
|
}
|
||
|
SetTextboxFocus(elt);
|
||
|
}
|
||
|
|
||
|
// * Callback when the user changes the value for background-attachment
|
||
|
function onBackgroundAttachmentChange()
|
||
|
{
|
||
|
if (!gDialog.selectedObject) return;
|
||
|
// the checkbox is checked if the background scrolls with the page
|
||
|
var value = gDialog.backgroundAttachmentCheckbox.checked ? "" : "fixed";
|
||
|
AddStyleToElement(gDialog.selectedObject, "background-attachment", value);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Callback when one of the background positions (x or y) is changed
|
||
|
function onBackGroundPositionSelect()
|
||
|
{
|
||
|
var xPosition = gDialog.xBackgroundPositionRadiogroup.selectedItem.value;
|
||
|
var yPosition = gDialog.yBackgroundPositionRadiogroup.selectedItem.value;
|
||
|
var value = xPosition + " " + yPosition;
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-position", value);
|
||
|
AddStyleToElement(gDialog.selectedObject, "background-position", value);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * Inits the values shown in the Text tab panel
|
||
|
function InitTextTabPanel()
|
||
|
{
|
||
|
gDialog.selectedTab = TEXT_TAB;
|
||
|
if (!gDialog.selectedObject || !gDialog.selectedObject.style)
|
||
|
return;
|
||
|
|
||
|
/* INIT FONT-FAMILY */
|
||
|
var fontFamily = getSpecifiedStyle("font-family");
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "font-family", fontFamily);
|
||
|
var fontFamilyChoice = "noFontFamilyRadio";
|
||
|
var predefFontFamilyChoice = "";
|
||
|
var enableCustomInput = false;
|
||
|
var enablePredefMenu = false;
|
||
|
|
||
|
|
||
|
if (fontFamily == "arial,helvetica,sans-serif") {
|
||
|
fontFamilyChoice = "predefFontFamilyRadio";
|
||
|
predefFontFamilyChoice = "sansSerifFontFamilyMenuitem";
|
||
|
enablePredefMenu = true;
|
||
|
}
|
||
|
else if (fontFamily == "times new roman,times,serif") {
|
||
|
fontFamilyChoice = "predefFontFamilyRadio";
|
||
|
predefFontFamilyChoice = "serifFontFamilyMenuitem";
|
||
|
enablePredefMenu = true;
|
||
|
}
|
||
|
else if (fontFamily == "courier new,courier,monospace") {
|
||
|
fontFamilyChoice = "predefFontFamilyRadio";
|
||
|
predefFontFamilyChoice = "monospaceFontFamilyMenuitem";
|
||
|
enablePredefMenu = true;
|
||
|
}
|
||
|
else if (fontFamily != "") {
|
||
|
fontFamilyChoice = "customFontFamilyRadio";
|
||
|
gDialog.customFontFamilyInput.value = fontFamily;
|
||
|
enableCustomInput = true;
|
||
|
}
|
||
|
/* selects the radio button */
|
||
|
var fontFamilyItem = document.getElementById(fontFamilyChoice);
|
||
|
gDialog.fontFamilyRadiogroup.selectedItem = fontFamilyItem;
|
||
|
/* enablers/disablers */
|
||
|
if (enablePredefMenu) {
|
||
|
gDialog.predefFontFamilyMenulist.removeAttribute("disabled");
|
||
|
}
|
||
|
else {
|
||
|
gDialog.predefFontFamilyMenulist.setAttribute("disabled", "true");
|
||
|
}
|
||
|
if (enableCustomInput) {
|
||
|
gDialog.customFontFamilyInput.removeAttribute("disabled");
|
||
|
}
|
||
|
else {
|
||
|
gDialog.customFontFamilyInput.setAttribute("disabled", "true");
|
||
|
}
|
||
|
|
||
|
if (predefFontFamilyChoice != "") {
|
||
|
var predefFontFamilyMenuitem = document.getElementById(predefFontFamilyChoice);
|
||
|
gDialog.predefFontFamilyMenulist.selectedItem = predefFontFamilyMenuitem;
|
||
|
}
|
||
|
|
||
|
/* INIT COLOR */
|
||
|
textColor = ConvertRGBColorIntoHEXColor(getSpecifiedStyle("color"));
|
||
|
backgroundColor = ConvertRGBColorIntoHEXColor(getSpecifiedStyle("background-color"));
|
||
|
gDialog.textColorInput.setAttribute("value", textColor);
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "color", textColor);
|
||
|
if (backgroundColor == "")
|
||
|
backgroundColor = "white";
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "background-color", backgroundColor);
|
||
|
setColorWell("textCW", textColor);
|
||
|
|
||
|
/* INIT FONT-STYLE */
|
||
|
SelectsOneChoice("font-style", "fontStyleMenulist", "FontStyleMenu", gDialog.brownFoxLabel)
|
||
|
|
||
|
/* INIT FONT-WEIGHT */
|
||
|
SelectsOneChoice("font-weight", "fontWeightMenulist", "FontWeightMenu", gDialog.brownFoxLabel)
|
||
|
|
||
|
/* INIT TEXT-TRANSFORM */
|
||
|
SelectsOneChoice("text-transform", "textTransformMenulist", "TextTransformMenu", gDialog.brownFoxLabel)
|
||
|
|
||
|
/* INIT TEXT-ALIGN */
|
||
|
SelectsOneChoice("text-align", "textAlignMenulist", "TextAlignMenu", gDialog.brownFoxLabel)
|
||
|
|
||
|
/* INIT TEXT-DECORATION */
|
||
|
var textDecoration = getSpecifiedStyle("text-decoration");
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "text-decoration", textDecoration);
|
||
|
SelectsCheckboxIfValueContains(textDecoration, "underline", "underlineTextDecorationCheckbox");
|
||
|
SelectsCheckboxIfValueContains(textDecoration, "overline", "overlineTextDecorationCheckbox");
|
||
|
SelectsCheckboxIfValueContains(textDecoration, "line-through", "linethroughTextDecorationCheckbox");
|
||
|
SelectsCheckboxIfValueContains(textDecoration, "blink", "blinkTextDecorationCheckbox");
|
||
|
SelectsCheckboxIfValueContains(textDecoration, "none", "noneTextDecorationCheckbox");
|
||
|
|
||
|
/* INIT FONT SIZE */
|
||
|
var fontSize = getSpecifiedStyle("font-size");
|
||
|
if (!fontSize || fontSize == "")
|
||
|
gDialog.fontSizeInput.value = "";
|
||
|
else
|
||
|
gDialog.fontSizeInput.value = fontSize;
|
||
|
AddStyleToElement(gDialog.brownFoxLabel, "font-size", fontSize);
|
||
|
|
||
|
/* INIT LINE-HEIGHT */
|
||
|
var lineHeight = getSpecifiedStyle("line-height");
|
||
|
if (!lineHeight || lineHeight == "")
|
||
|
gDialog.lineHeightInput.value = "";
|
||
|
else
|
||
|
gDialog.lineHeightInput.value = lineHeight;
|
||
|
|
||
|
}
|
||
|
|
||
|
// * Utility function to check if the four side values of a property
|
||
|
// are equal so we an show a shorthand in the dialog
|
||
|
// param String top
|
||
|
// param String left
|
||
|
// param String right
|
||
|
// param String bottom
|
||
|
// return boolean
|
||
|
function AreAllFourValuesEqual(top, left, right, bottom)
|
||
|
{
|
||
|
return (top == left && top == right && top == bottom);
|
||
|
}
|
||
|
|
||
|
// * Retrieves the specified style for the property |prop| and
|
||
|
// makes it become the value of the XUL element of ID |id|
|
||
|
// param String id
|
||
|
// param String prop
|
||
|
function SetTextzoneValue(id, prop)
|
||
|
{
|
||
|
var elt = document.getElementById(id);
|
||
|
if (elt) {
|
||
|
var value = getSpecifiedStyle(prop);
|
||
|
if (!value)
|
||
|
elt.value = "";
|
||
|
else
|
||
|
elt.value = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Inits the values shown in the Aural tab panel
|
||
|
function InitAuralTabPanel()
|
||
|
{
|
||
|
gDialog.selectedTab = AURAL_TAB;
|
||
|
if (!gDialog.selectedObject || !gDialog.selectedObject.style)
|
||
|
return;
|
||
|
|
||
|
// observe the scrollbar and call onScrollbarAttrModified when an attribute is modified
|
||
|
gDialog.volumeScrollbar.removeEventListener("DOMAttrModified", onVolumeScrollbarAttrModified, false);
|
||
|
var volume = getSpecifiedStyle("volume");
|
||
|
if (volume == "silent") {
|
||
|
gDialog.muteVolumeCheckbox.checked = true;
|
||
|
gDialog.volumeScrollbar.setAttribute("disabled", "true");
|
||
|
}
|
||
|
else {
|
||
|
gDialog.muteVolumeCheckbox.checked = false;
|
||
|
gDialog.volumeScrollbar.removeAttribute("disabled");
|
||
|
}
|
||
|
// if no volume specified, display medium value
|
||
|
if (!volume)
|
||
|
volume = "50";
|
||
|
gDialog.volumeMenulist.value = volume;
|
||
|
UpdateScrollbar(gDialog.volumeMenulist, 'volumeScrollbar');
|
||
|
|
||
|
gDialog.volumeScrollbar.addEventListener("DOMAttrModified", onVolumeScrollbarAttrModified, false);
|
||
|
|
||
|
SelectsOneChoice("speak", "speakMenulist", "SpeakMenu", null);
|
||
|
SelectsOneChoice("speech-rate", "speechRateMenulist", "SpeechRateMenu", null);
|
||
|
}
|
||
|
|
||
|
// * this is a callback of a listener set on the scrollbar for volume setting
|
||
|
// param DOMMutationEvent aEvent
|
||
|
function onVolumeScrollbarAttrModified(aEvent)
|
||
|
{
|
||
|
if (aEvent.attrName == "curpos") {
|
||
|
var e = gDialog.volumeMenulist;
|
||
|
if (e.value == "silent") return;
|
||
|
var v = Math.floor(aEvent.newValue / 10);
|
||
|
e.value = v;
|
||
|
AddStyleToElement(gDialog.selectedObject, "volume", v);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onOpacityScrollbarAttrModified(aEvent)
|
||
|
{
|
||
|
if (aEvent.attrName == "curpos") {
|
||
|
var v = aEvent.newValue / 1000;
|
||
|
if (v == 1)
|
||
|
gDialog.opacityLabel.setAttribute("value", "transparent");
|
||
|
else
|
||
|
gDialog.opacityLabel.setAttribute("value", v);
|
||
|
AddStyleToElement(gDialog.selectedObject, "opacity", v);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * when the user checks the "mute" checkbox, 'silent' should become
|
||
|
// the new value of the 'volume' property. If the user unchecks it
|
||
|
// the value should be computed from the volume scrollbar's position
|
||
|
// param XULElement elt
|
||
|
function MuteVolume(elt)
|
||
|
{
|
||
|
var v;
|
||
|
if (elt.checked) {
|
||
|
v = "silent";
|
||
|
gDialog.volumeScrollbar.setAttribute("disable", "true");
|
||
|
}
|
||
|
else {
|
||
|
v = Math.floor(gDialog.volumeScrollbar.getAttribute("curpos") / 10);
|
||
|
gDialog.volumeScrollbar.removeAttribute("disable");
|
||
|
}
|
||
|
gDialog.volumeMenulist.value = v;
|
||
|
AddStyleToElement(gDialog.selectedObject, "volume", v);
|
||
|
SetModifiedFlagOnStylesheet();
|
||
|
}
|
||
|
|
||
|
// * updates the volume's scrollbar position using the value of the
|
||
|
// 'volume' property stored in the value of the XUL element |elt|.
|
||
|
// It also converts pre-defined volume names to the equivalent
|
||
|
// numerical value (defined in CSS 2 spec)
|
||
|
// param XULElement elt
|
||
|
// param String id
|
||
|
function UpdateScrollbar(elt, id)
|
||
|
{
|
||
|
var v = elt.value, x = 0;
|
||
|
if (v == "silent") return;
|
||
|
var e = document.getElementById(id);
|
||
|
switch (v) {
|
||
|
case "x-soft": x=0; break;
|
||
|
case "soft": x=250; break;
|
||
|
case "medium": x=500; break;
|
||
|
case "loud": x=750; break;
|
||
|
case "x-loud": x=1000; break;
|
||
|
default:
|
||
|
x = parseInt(v) * 10;
|
||
|
// if we don't have a number, it must be a pre-defined keyword
|
||
|
// and it can't be one because we checked that above
|
||
|
if (isNaN(x)) x = 0;
|
||
|
break;
|
||
|
}
|
||
|
// let's update the scrollbar's position
|
||
|
e.setAttribute("curpos", x);
|
||
|
}
|
||
|
|
||
|
// * Inits the values shown in the Box model tab panel
|
||
|
function InitBoxTabPanel()
|
||
|
{
|
||
|
gDialog.selectedTab = BOX_TAB;
|
||
|
if (!gDialog.selectedObject || !gDialog.selectedObject.style)
|
||
|
return;
|
||
|
|
||
|
SelectsOneChoice("display", "displayMenulist", "DisplayMenuitem", null);
|
||
|
SelectsOneChoice("visibility", "visibilityMenulist", "VisibilityMenuitem", null);
|
||
|
SelectsOneChoice("float", "floatMenulist", "FloatMenuitem", null);
|
||
|
SelectsOneChoice("clear", "clearMenulist", "ClearMenuitem", null);
|
||
|
SelectsOneChoice("position", "positionMenulist", "PositionMenuitem", null);
|
||
|
SelectsOneChoice("overflow", "overflowMenulist", "OverflowMenuitem", null);
|
||
|
|
||
|
SetTextzoneValue("zindexInput", "z-index");
|
||
|
SetTextzoneValue("margintopEditableMenulist", "margin-top");
|
||
|
SetTextzoneValue("paddingtopEditableMenulist", "padding-top");
|
||
|
SetTextzoneValue("topEditableMenulist", "top");
|
||
|
SetTextzoneValue("marginleftEditableMenulist", "margin-left");
|
||
|
SetTextzoneValue("paddingleftEditableMenulist", "padding-left");
|
||
|
SetTextzoneValue("leftEditableMenulist", "left");
|
||
|
SetTextzoneValue("marginrightEditableMenulist", "margin-right");
|
||
|
SetTextzoneValue("paddingrightEditableMenulist", "padding-right");
|
||
|
SetTextzoneValue("rightEditableMenulist", "right");
|
||
|
SetTextzoneValue("marginbottomEditableMenulist", "margin-bottom");
|
||
|
SetTextzoneValue("paddingbottomEditableMenulist","padding-bottom");
|
||
|
SetTextzoneValue("bottomEditableMenulist", "bottom");
|
||
|
|
||
|
SetTextzoneValue("widthEditableMenulist", "width");
|
||
|
SetTextzoneValue("minwidthEditableMenulist", "min-width");
|
||
|
SetTextzoneValue("maxwidthEditableMenulist", "max-width");
|
||
|
SetTextzoneValue("heightEditableMenulist", "height");
|
||
|
SetTextzoneValue("minheightEditableMenulist", "min-height");
|
||
|
SetTextzoneValue("maxheightEditableMenulist", "max-height");
|
||
|
|
||
|
}
|
||
|
|
||
|
// * Inits the values shown in the Border tab panel
|
||
|
function InitBorderTabPanel()
|
||
|
{
|
||
|
gDialog.selectedTab = BORDER_TAB;
|
||
|
if (!gDialog.selectedObject || !gDialog.selectedObject.style)
|
||
|
return;
|
||
|
|
||
|
/* INIT */
|
||
|
var style = [ getSpecifiedStyle("border-top-style"),
|
||
|
getSpecifiedStyle("border-left-style"),
|
||
|
getSpecifiedStyle("border-right-style"),
|
||
|
getSpecifiedStyle("border-bottom-style")
|
||
|
];
|
||
|
var width = [ getSpecifiedStyle("border-top-width"),
|
||
|
getSpecifiedStyle("border-left-width"),
|
||
|
getSpecifiedStyle("border-right-width"),
|
||
|
getSpecifiedStyle("border-bottom-width")
|
||
|
];
|
||
|
var color = [ ConvertRGBColorIntoHEXColor(getSpecifiedStyle("border-top-color")),
|
||
|
ConvertRGBColorIntoHEXColor(getSpecifiedStyle("border-left-color")),
|
||
|
ConvertRGBColorIntoHEXColor(getSpecifiedStyle("border-right-color")),
|
||
|
ConvertRGBColorIntoHEXColor(getSpecifiedStyle("border-bottom-color"))
|
||
|
];
|
||
|
|
||
|
var sameFourSides = false;
|
||
|
// let's see if we have same style/color/width for all four borders
|
||
|
if (AreAllFourValuesEqual(style[0], style[1], style[2], style[3]) &&
|
||
|
AreAllFourValuesEqual(width[0], width[1], width[2], width[3]) &&
|
||
|
AreAllFourValuesEqual(getHexColorFromColorName(color[0]),
|
||
|
getHexColorFromColorName(color[1]),
|
||
|
getHexColorFromColorName(color[2]),
|
||
|
getHexColorFromColorName(color[3]))) {
|
||
|
sameFourSides = true;
|
||
|
}
|
||
|
|
||
|
var sideArray = [ "top", "left", "right", "bottom" ];
|
||
|
|
||
|
for (var i=0; i<sideArray.length; i++) {
|
||
|
var styleMenu = document.getElementById( sideArray[i]+"BorderStyleMenulist" );
|
||
|
var colorInput = document.getElementById( sideArray[i]+"BorderColorInput" );
|
||
|
var widthInput = document.getElementById( sideArray[i]+"BorderWidthInput" );
|
||
|
if (!i || !sameFourSides) {
|
||
|
EnableUI(styleMenu, true);
|
||
|
EnableUI(colorInput, true);
|
||
|
EnableUI(widthInput, true);
|
||
|
|
||
|
SelectsOneChoice("border-"+sideArray[i]+"-style",
|
||
|
sideArray[i]+"BorderStyleMenulist",
|
||
|
sideArray[i]+"BorderStyle", gDialog.borderPreview)
|
||
|
|
||
|
colorInput.value = color[i];
|
||
|
setColorWell("border"+sideArray[i]+"CW", color[i]);
|
||
|
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-color", color[i]);
|
||
|
|
||
|
widthInput.value = width[i];
|
||
|
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-width", width[i]);
|
||
|
}
|
||
|
else {
|
||
|
EnableUI(styleMenu, false);
|
||
|
EnableUI(colorInput, false);
|
||
|
EnableUI(widthInput, false);
|
||
|
colorInput.value = "";
|
||
|
setColorWell("border"+sideArray[i]+"CW", "");
|
||
|
widthInput.value = "";
|
||
|
styleMenu.selectedItem = document.getElementById("unspecified" + sideArray[i] + "BorderStyle");
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-color", color[0]);
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-style", style[0]);
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-width", width[0]);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if (sameFourSides)
|
||
|
gDialog.allFourBordersSame.setAttribute("checked", "true");
|
||
|
else
|
||
|
gDialog.allFourBordersSame.removeAttribute("checked");
|
||
|
}
|
||
|
|
||
|
// * Inits the values shown in the Background tab panel
|
||
|
function InitBackgroundTabPanel()
|
||
|
{
|
||
|
gDialog.selectedTab = BACKGROUND_TAB;
|
||
|
if (!gDialog.selectedObject || !gDialog.selectedObject.style)
|
||
|
return;
|
||
|
|
||
|
gDialog.opacityScrollbar.removeEventListener("DOMAttrModified", onOpacityScrollbarAttrModified, false);
|
||
|
var opacity = getSpecifiedStyle("opacity");
|
||
|
if (opacity == "")
|
||
|
opacity = 1;
|
||
|
gDialog.opacityScrollbar.setAttribute("curpos", opacity*1000);
|
||
|
gDialog.opacityScrollbar.addEventListener("DOMAttrModified", onOpacityScrollbarAttrModified, false);
|
||
|
|
||
|
/* INIT BACKGROUND-COLOR */
|
||
|
backgroundColor = ConvertRGBColorIntoHEXColor(getSpecifiedStyle("background-color"));
|
||
|
gDialog.backgroundColorInput.setAttribute("value", backgroundColor);
|
||
|
if (backgroundColor == "")
|
||
|
backgroundColor = "white";
|
||
|
setColorWell("backgroundCW", backgroundColor);
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-color", backgroundColor);
|
||
|
|
||
|
/* INIT BACKGROUND-REPEAT */
|
||
|
var backgroundRepeat = getSpecifiedStyle("background-repeat");
|
||
|
var choice = "repeatBackgroundRepeatMenu";
|
||
|
if (backgroundRepeat == "no-repeat") {
|
||
|
choice = "norepeatBackgroundRepeatMenu";
|
||
|
}
|
||
|
else if (backgroundRepeat == "repeat-x") {
|
||
|
choice = "horizontallyBackgroundRepeatMenu";
|
||
|
}
|
||
|
else if (backgroundRepeat == "repeat-y") {
|
||
|
choice = "verticallyBackgroundRepeatMenu";
|
||
|
}
|
||
|
else if (backgroundRepeat == "repeat") {
|
||
|
choice = "repeatBackgroundRepeatMenu";
|
||
|
}
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-repeat", backgroundRepeat);
|
||
|
var choiceItem = document.getElementById(choice);
|
||
|
gDialog.backgroundRepeatMenulist.selectedItem = choiceItem;
|
||
|
|
||
|
/* INIT BACKGROUND-IMAGE */
|
||
|
var backgroundImage = getSpecifiedStyle("background-image");
|
||
|
gDialog.backgroundImageInput.setAttribute("value", backgroundImage);
|
||
|
enableBackgroundProps( (backgroundImage != "none" && backgroundImage != "") );
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-image", backgroundImage);
|
||
|
|
||
|
/* INIT BACKGROUND-ATTACHMENT */
|
||
|
var backgroundAttachment = getSpecifiedStyle("background-attachment");
|
||
|
gDialog.backgroundAttachmentCheckbox.checked = ( (backgroundAttachment == "fixed") ? false : true );
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-attachment", backgroundAttachment);
|
||
|
|
||
|
/* INIT BACKGROUND-POSITION */
|
||
|
var xBackgroundPosition = getSpecifiedStyle("-x-background-x-position");
|
||
|
var yBackgroundPosition = getSpecifiedStyle("-x-background-y-position");
|
||
|
var xRadio, yRadio;
|
||
|
if (xBackgroundPosition == "100%" || xBackgroundPosition == "right")
|
||
|
xRadio = "rightXBackgroundPositionRadio";
|
||
|
else if (xBackgroundPosition == "50%" || xBackgroundPosition == "center")
|
||
|
xRadio = "centerXBackgroundPositionRadio";
|
||
|
else
|
||
|
xRadio = "leftXBackgroundPositionRadio";
|
||
|
if (yBackgroundPosition == "100%" || yBackgroundPosition == "bottom")
|
||
|
yRadio = "bottomYBackgroundPositionRadio";
|
||
|
else if (xBackgroundPosition == "50%" || yBackgroundPosition == "center")
|
||
|
yRadio = "centerYBackgroundPositionRadio";
|
||
|
else
|
||
|
yRadio = "topYBackgroundPositionRadio";
|
||
|
|
||
|
gDialog.xBackgroundPositionRadiogroup.selectedItem = document.getElementById(xRadio);
|
||
|
gDialog.yBackgroundPositionRadiogroup.selectedItem = document.getElementById(yRadio);
|
||
|
AddStyleToElement(gDialog.backgroundPreview, "background-attachment",
|
||
|
xBackgroundPosition + " " + yBackgroundPosition);
|
||
|
}
|
||
|
|
||
|
// * if the string |value| contains the substring |searchedString|, the
|
||
|
// checkbox of id |id| is checked ; it's unchecked otherwise.
|
||
|
// param String value
|
||
|
// param String searchedString
|
||
|
// param String id
|
||
|
function SelectsCheckboxIfValueContains(value, searchedString, id)
|
||
|
{
|
||
|
if (checkbox) {
|
||
|
var state = (value.indexOf(searchedString) != -1);
|
||
|
var checkbox = document.getElementById(id);
|
||
|
checkbox.checked = state;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * First, if |xulElt| is not null, this function copies the
|
||
|
// specified style for the CSS property |property| to the inline
|
||
|
// styles carried by |xulElt|. Then it retrieves the property's
|
||
|
// value, remove possible dashes, and append |idSuffix| to it.
|
||
|
// It forms the ID of a menu item that will be selected in the
|
||
|
// menulist |idMenuList|.
|
||
|
// param String property
|
||
|
// param String idMenuList
|
||
|
// param String idSuffix
|
||
|
// param XULElement xulElt
|
||
|
function SelectsOneChoice(property, idMenulist, idSuffix, xulElt)
|
||
|
{
|
||
|
var propertyValue = getSpecifiedStyle(property);
|
||
|
if (xulElt) {
|
||
|
AddStyleToElement(xulElt, property, propertyValue);
|
||
|
}
|
||
|
propertyValue = TrimDashes(propertyValue);
|
||
|
var menulist = document.getElementById(idMenulist);
|
||
|
var choice = "unspecified" + idSuffix;
|
||
|
if (propertyValue && propertyValue != "") {
|
||
|
choice = propertyValue + idSuffix;
|
||
|
}
|
||
|
var choiceItem = document.getElementById(choice);
|
||
|
menulist.selectedItem = choiceItem;
|
||
|
}
|
||
|
|
||
|
// * utility function to convert predefined HTML4 color names
|
||
|
// into their #rrggbb equivalent
|
||
|
// param String color
|
||
|
// return String
|
||
|
function getHexColorFromColorName(color)
|
||
|
{
|
||
|
var namedColorsArray = [
|
||
|
{ name:"aqua", value:"#00ffff" },
|
||
|
{ name:"black", value:"#000000" },
|
||
|
{ name:"blue", value:"#0000ff" },
|
||
|
{ name:"fuchsia", value:"#ff00ff" },
|
||
|
{ name:"gray", value:"#808080" },
|
||
|
{ name:"green", value:"#008000" },
|
||
|
{ name:"lime", value:"#00ff00" },
|
||
|
{ name:"maroon", value:"#800000" },
|
||
|
{ name:"navy", value:"#000080" },
|
||
|
{ name:"olive", value:"#808000" },
|
||
|
{ name:"purple", value:"#800080" },
|
||
|
{ name:"red", value:"#ff0000" },
|
||
|
{ name:"silver", value:"#c0c0c0" },
|
||
|
{ name:"teal", value:"#008080" },
|
||
|
{ name:"white", value:"#ffffff" },
|
||
|
{ name:"yellow", value:"#ffff00" }
|
||
|
];
|
||
|
for (var i=0; i< namedColorsArray.length; i++) {
|
||
|
if (color == namedColorsArray[i].name) {
|
||
|
color = namedColorsArray[i].value;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return color;
|
||
|
}
|
||
|
|
||
|
// * retrieve the specified value for the CSS property |property|.
|
||
|
// The beauty of the CSS OM is that the same exact function can be
|
||
|
// used for both inline styles carried by an element, and rules in a
|
||
|
// stylesheet
|
||
|
// param String property
|
||
|
// return String
|
||
|
function getSpecifiedStyle(property)
|
||
|
{
|
||
|
if (gDialog.selectedObject && gDialog.selectedObject.style) {
|
||
|
return gDialog.selectedObject.style.getPropertyValue(property).toLowerCase();
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
// * This recreates the textual content of an embedded stylesheet
|
||
|
// param DOMCSSStyleSheet sheet
|
||
|
function SerializeEmbeddedSheet(sheet)
|
||
|
{
|
||
|
var ownerNode = sheet.ownerNode;
|
||
|
var cssText = "\n";
|
||
|
var l = sheet.cssRules.length;
|
||
|
var tmp;
|
||
|
for (var j = 0; j< l; j++) {
|
||
|
tmp = sheet.cssRules.item(j).cssText;
|
||
|
var re = /;\s*/;
|
||
|
var cssTextSplitted = tmp.split(re);
|
||
|
cssText += " ";
|
||
|
for (var k=0; k<cssTextSplitted.length; k++) {
|
||
|
cssText += cssTextSplitted[k];
|
||
|
if (k != cssTextSplitted.length-1)
|
||
|
cssText += ";\n ";
|
||
|
}
|
||
|
if (l > 1) cssText += "\n\n";
|
||
|
}
|
||
|
var child = ownerNode.lastChild;
|
||
|
while (child) {
|
||
|
tmp = child.previousSibling;
|
||
|
ownerNode.removeChild(child);
|
||
|
child = tmp;
|
||
|
}
|
||
|
var textNode = document.createTextNode(cssText + "\n");
|
||
|
ownerNode.appendChild(textNode);
|
||
|
}
|
||
|
|
||
|
// * This recreates the textual content of an external stylesheet
|
||
|
// param DOMCSSStyleSheet sheet
|
||
|
// param String href
|
||
|
function SerializeExternalSheet(sheet, href)
|
||
|
{
|
||
|
const classes = Components.classes;
|
||
|
const interfaces = Components.interfaces;
|
||
|
const nsILocalFile = interfaces.nsILocalFile;
|
||
|
const nsIFileOutputStream = interfaces.nsIFileOutputStream;
|
||
|
const FILEOUT_CTRID = '@mozilla.org/network/file-output-stream;1';
|
||
|
|
||
|
var fileHandler = GetFileProtocolHandler();
|
||
|
var localFile;
|
||
|
if (href)
|
||
|
localFile = fileHandler.getFileFromURLSpec(href).QueryInterface(nsILocalFile);
|
||
|
else
|
||
|
localFile = fileHandler.getFileFromURLSpec(sheet.href).QueryInterface(nsILocalFile);
|
||
|
|
||
|
var fileOuputStream = classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
|
||
|
try {
|
||
|
fileOuputStream.init(localFile, -1, -1, 0);
|
||
|
|
||
|
var cssText = "/* Generated by CaScadeS, a stylesheet editor for Mozilla Composer */\n\n";
|
||
|
var l = sheet.cssRules.length, tmp;
|
||
|
var re = /;\s*/;
|
||
|
var cssTextSplitted, ruleIndex, singleDeclIndex;
|
||
|
|
||
|
for (ruleIndex = 0; ruleIndex< l; ruleIndex++) {
|
||
|
tmp = sheet.cssRules.item(ruleIndex).cssText;
|
||
|
cssTextSplitted = tmp.split(re);
|
||
|
cssText += " ";
|
||
|
for (singleDeclIndex=0; singleDeclIndex<cssTextSplitted.length; singleDeclIndex++) {
|
||
|
cssText += cssTextSplitted[singleDeclIndex];
|
||
|
if (singleDeclIndex != cssTextSplitted.length-1)
|
||
|
cssText += ";\n ";
|
||
|
}
|
||
|
if (l > 1) cssText += "\n\n";
|
||
|
}
|
||
|
var textNode = document.createTextNode(cssText + "\n");
|
||
|
fileOuputStream.write(cssText, cssText.length);
|
||
|
fileOuputStream.close();
|
||
|
}
|
||
|
catch (ex) {}
|
||
|
}
|
||
|
|
||
|
// * if the checkbox of ID |checkboxID| is checked, copies the value |value|,
|
||
|
// supposed to be the one for the top side, to the other three sides, makes
|
||
|
// the XUL Element |elt| have that value. |propertyBase| and |propertySuffix|
|
||
|
// are used to create side properties like in border-*-style.
|
||
|
// The property and value are also added to the styles of the element of ID
|
||
|
// |previewID| if it not null.
|
||
|
// param String propertyBase
|
||
|
// param String propertySuffix
|
||
|
// param String value
|
||
|
// param String checkboxID
|
||
|
// param String previewID
|
||
|
// param XULElement elt
|
||
|
function IfFourSidesSameStyle(propertyBase, propertySuffix, value, checkboxID, previewID, elt)
|
||
|
{
|
||
|
// value is the value of the '*-top' property
|
||
|
var checkbox = document.getElementById(checkboxID);
|
||
|
if (!checkbox || !checkbox.checked) return;
|
||
|
|
||
|
if (!value) {
|
||
|
if (elt) {
|
||
|
value = elt.value;
|
||
|
}
|
||
|
}
|
||
|
var xulElt = document.getElementById(previewID);
|
||
|
var sideArray = [ "left", "right", "bottom" ];
|
||
|
for (var i=0; i<sideArray.length; i++) {
|
||
|
var property = propertyBase + "-" + sideArray[i] + "-" + propertySuffix;
|
||
|
if (xulElt) {
|
||
|
AddStyleToElement(xulElt, property, value);
|
||
|
}
|
||
|
AddStyleToElement(gDialog.selectedObject, property, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Callback when the user clicks on the "use same style for
|
||
|
// the four borders" checkbox. |elt| is that checkbox.
|
||
|
// param XULElement elt
|
||
|
function ToggleFourBorderSidesSameStyle(elt)
|
||
|
{
|
||
|
var sameStyle = elt.checked;
|
||
|
var sideArray = [ "left", "right", "bottom" ];
|
||
|
|
||
|
var style = getSpecifiedStyle("border-top-style");
|
||
|
if (!sameStyle && !style)
|
||
|
style = "unspecified";
|
||
|
var color = gDialog.topBorderColorInput.value;
|
||
|
var width = getSpecifiedStyle("border-top-width");
|
||
|
|
||
|
for (var i=0; i<sideArray.length; i++) {
|
||
|
var styleMenulist = document.getElementById( sideArray[i] + "BorderStyleMenulist" );
|
||
|
var widthInput = document.getElementById( sideArray[i] + "BorderWidthInput" );
|
||
|
var colorInput = document.getElementById( sideArray[i] + "BorderColorInput" );
|
||
|
var colorButton = document.getElementById( sideArray[i] + "BorderColorButton" );
|
||
|
if (sameStyle) {
|
||
|
styleMenulist.selectedItem = document.getElementById("unspecified" + sideArray[i] + "BorderStyle");
|
||
|
|
||
|
widthInput.value = "";
|
||
|
|
||
|
colorInput.value = "";
|
||
|
colorInput.setAttribute("disabled", "true");
|
||
|
setColorWell("border"+sideArray[i]+"CW", "");
|
||
|
|
||
|
widthInput.setAttribute("disabled", "true");
|
||
|
styleMenulist.setAttribute("disabled", "true");
|
||
|
colorButton.setAttribute("disabled", "true");
|
||
|
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-color", color);
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-style", style);
|
||
|
AddStyleToElement(gDialog.borderPreview, "border-"+sideArray[i]+"-width", width);
|
||
|
|
||
|
AddStyleToElement(gDialog.selectedObject, "border-"+sideArray[i]+"-color", color);
|
||
|
AddStyleToElement(gDialog.selectedObject, "border-"+sideArray[i]+"-style", style);
|
||
|
AddStyleToElement(gDialog.selectedObject, "border-"+sideArray[i]+"-width", width);
|
||
|
}
|
||
|
else {
|
||
|
styleMenulist.removeAttribute("disabled");
|
||
|
widthInput.removeAttribute("disabled");
|
||
|
colorInput.removeAttribute("disabled");
|
||
|
colorButton.removeAttribute("disabled");
|
||
|
|
||
|
colorInput.value = color;
|
||
|
setColorWell("border"+sideArray[i]+"CW", color);
|
||
|
widthInput.value = width;
|
||
|
var styleMenuitem = document.getElementById( style+sideArray[i]+"BorderStyle" );
|
||
|
styleMenulist.selectedItem = styleMenuitem;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Enable a XUL element depending on a boolean value
|
||
|
// param XULElement elt
|
||
|
// param boolean enabled
|
||
|
function EnableUI(elt, enabled)
|
||
|
{
|
||
|
if (enabled) {
|
||
|
elt.removeAttribute("disabled");
|
||
|
}
|
||
|
else {
|
||
|
elt.setAttribute("disabled", "true");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Initializes a menupopup containing length units. It looks for
|
||
|
// the current value of the property and if it is already a length,
|
||
|
// build the menu keeping the same numeric part and browsing all the
|
||
|
// possible units.
|
||
|
function InitLengthUnitMenuPopup(elt, property, id, allowsPercentages)
|
||
|
{
|
||
|
var value = elt.parentNode.value;
|
||
|
var re = /([+-]?\d*\.\d+|[+-]?\d+)\D*/ ;
|
||
|
var found = value.match(re);
|
||
|
var numPart = "0";
|
||
|
if (found && found.length != 0)
|
||
|
numPart = RegExp.$1;
|
||
|
|
||
|
var child = elt.firstChild, tmp;
|
||
|
while (child && child.nodeName.toLowerCase() != "menuseparator") {
|
||
|
tmp = child.nextSibling;
|
||
|
elt.removeChild(child);
|
||
|
child = tmp;
|
||
|
}
|
||
|
|
||
|
// below is an array of all valid CSS length units
|
||
|
var unitsArray = [ "%", "px", "pt", "cm", "in", "mm", "pc", "em", "ex" ];
|
||
|
var j, newitem, start = 0;
|
||
|
if (!allowsPercentages)
|
||
|
start = 1;
|
||
|
for (j=start; j<unitsArray.length; j++) {
|
||
|
var itemValue = numPart + unitsArray[j];
|
||
|
newitem = document.createElementNS(XUL_NS, "menuitem");
|
||
|
newitem.setAttribute("label", itemValue);
|
||
|
newitem.setAttribute("value", itemValue);
|
||
|
if (child)
|
||
|
elt.insertBefore(newitem, child);
|
||
|
else
|
||
|
elt.appendChild(newitem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * Removes all dashes from a string
|
||
|
// param String s
|
||
|
// return String
|
||
|
function TrimDashes(s)
|
||
|
{
|
||
|
var r = "", i;
|
||
|
for (i=0; i<s.length; i++)
|
||
|
if (s[i] != '-')
|
||
|
r += s[i];
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
// * Callback for spinbuttons. Increments of |increment| the length value of
|
||
|
// the XUL element of ID |id|.
|
||
|
// param integer increment
|
||
|
// param String id
|
||
|
function Spinbutton(increment, id)
|
||
|
{
|
||
|
var elt = document.getElementById(id);
|
||
|
if (elt) {
|
||
|
var value = elt.value;
|
||
|
var re = /([+-]?\d*\.\d+|[+-]?\d+)(\D*)/ ;
|
||
|
var found = value.match(re);
|
||
|
if (found && found.length != 0) {
|
||
|
var numPart = RegExp.$1;
|
||
|
var unitPart = RegExp.$2;
|
||
|
var unitIncrement;
|
||
|
switch (unitPart) {
|
||
|
case "cm":
|
||
|
case "in":
|
||
|
unitIncrement = 0.01;
|
||
|
break;
|
||
|
default:
|
||
|
unitIncrement = 1;
|
||
|
break;
|
||
|
}
|
||
|
elt.value = (Math.round(100 * (parseFloat(numPart) + (increment * unitIncrement)))/100) + unitPart;
|
||
|
}
|
||
|
else
|
||
|
elt.value = increment + "px";
|
||
|
elt.oninput();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// * code for initLocalFontFaceMenu shamelessly stolen from
|
||
|
// Charley Manske <cmanske@netscape.com>
|
||
|
// param XULElement menuPopup
|
||
|
function initLocalFontFaceMenu(menuPopup)
|
||
|
{
|
||
|
if (!menuPopup) return;
|
||
|
var menu = menuPopup.parentNode;
|
||
|
if (!gLocalFonts)
|
||
|
{
|
||
|
// Build list of all local fonts once per editor
|
||
|
try
|
||
|
{
|
||
|
var enumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"].createInstance();
|
||
|
if( enumerator )
|
||
|
enumerator = enumerator.QueryInterface(Components.interfaces.nsIFontEnumerator);
|
||
|
var localFontCount = { value: 0 }
|
||
|
var localFontsString = enumerator.EnumerateAllFonts(localFontCount);
|
||
|
if (localFontsString)
|
||
|
gLocalFonts = localFontsString.toString().split(",");
|
||
|
if (gLocalFonts)
|
||
|
{
|
||
|
// faces.sort(); Array is already sorted
|
||
|
for( var i = 0; i < gLocalFonts.length; i++ )
|
||
|
{
|
||
|
if( gLocalFonts[i] != "" )
|
||
|
{
|
||
|
var itemNode = document.createElement("menuitem");
|
||
|
itemNode.setAttribute("label", gLocalFonts[i]);
|
||
|
//itemNode.value = gLocalFonts[i];
|
||
|
itemNode.setAttribute("value", gLocalFonts[i]);
|
||
|
menuPopup.appendChild(itemNode);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(e) { }
|
||
|
}
|
||
|
//SetElementEnabledById("localFontFaceMenu", gLocalFonts != 0);
|
||
|
}
|
||
|
|
||
|
// * Handles a command in a menulist
|
||
|
// param XULElement elt
|
||
|
// param String property
|
||
|
// param String id
|
||
|
function DoMenulistCommand(elt, property, id) {
|
||
|
var choice = elt.selectedItem;
|
||
|
var value = choice.value;
|
||
|
onPullDownChanged(property, value, id);
|
||
|
if (property == "border-top-style") {
|
||
|
// this one is a special case : we need to check if the checkbox
|
||
|
// "all sides have same style" is checked ; if it's checked, make
|
||
|
// the other 3 sides acquire the style assigned to the top border
|
||
|
IfFourSidesSameStyle('border', 'style', value,
|
||
|
'allFourBordersSame', id, null);
|
||
|
}
|
||
|
}
|
||
|
|