Files
tubestation/browser/components/prefwindow/content/pref-fonts.js
mkaply@us.ibm.com ed1c5f0a1e #222978
r=mkaply, a=mkaply
Get fonts working again on OS/2 Firebird
2003-11-19 20:38:06 +00:00

675 lines
26 KiB
JavaScript

# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: NPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Netscape Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Gervase Markham <gerv@gerv.net>
# Tuukka Tolvanen <tt@lament.cjb.net>
#
# 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 NPL, 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 NPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
try
{
var pref = Components.classes["@mozilla.org/preferences;1"].getService( Components.interfaces.nsIPref );
}
catch(e)
{
dump("failed to get font list or pref object: "+e+" in pref-fonts.js\n");
}
var fontEnumerator = null;
var globalFonts = null;
var fontTypes = ["serif", "sans-serif", "monospace"];
var variableSize, fixedSize, minSize, languageList;
var languageData = [];
var currentLanguage;
var gPrefutilitiesBundle;
var gPrefWindow = window.opener.parent.hPrefWindow;
// manual data retrieval function for PrefWindow
function GetFields()
{
var dataObject = { };
// store data for language independent widgets
var lists = ["selectLangs", "proportionalFont"];
for( var i = 0; i < lists.length; i++ )
{
if( !( "dataEls" in dataObject ) )
dataObject.dataEls = new Object;
dataObject.dataEls[ lists[i] ] = new Object;
dataObject.dataEls[ lists[i] ].value = document.getElementById( lists[i] ).value;
}
dataObject.defaultFont = document.getElementById( "proportionalFont" ).value;
dataObject.fontDPI = document.getElementById( "screenResolution" ).value;
dataObject.useMyFonts = document.getElementById( "useMyFonts" ).checked ? 1 : 0;
var items = ["foregroundText", "background", "unvisitedLinks", "visitedLinks", "browserUseSystemColors", "browserUnderlineAnchors", "useMyColors", "useMyFonts"];
for (i = 0; i < items.length; ++i)
dataObject.dataEls[items[i]] = new Object;
dataObject.dataEls["foregroundText"].value = document.getElementById("foregroundtextmenu").color;
dataObject.dataEls["background"].value = document.getElementById("backgroundmenu").color;
dataObject.dataEls["unvisitedLinks"].value = document.getElementById("unvisitedlinkmenu").color;
dataObject.dataEls["visitedLinks"].value = document.getElementById("visitedlinkmenu").color;
dataObject.dataEls["browserUseSystemColors"].checked = document.getElementById("browserUseSystemColors").checked;
dataObject.dataEls["browserUnderlineAnchors"].checked = document.getElementById("browserUnderlineAnchors").checked;
dataObject.dataEls["useMyColors"].checked = document.getElementById("useMyColors").checked;
dataObject.dataEls["useMyFonts"].checked = document.getElementById("useMyFonts").checked;
// save current state for language dependent fields and store
saveState();
dataObject.languageData = languageData;
return dataObject;
}
// manual data setting function for PrefWindow
function SetFields(aDataObject)
{
languageData = "languageData" in aDataObject ? aDataObject.languageData : languageData ;
currentLanguage = "currentLanguage" in aDataObject ? aDataObject.currentLanguage : null ;
var lists = ["selectLangs", "proportionalFont"];
var prefvalue;
for( var i = 0; i < lists.length; i++ )
{
var element = document.getElementById( lists[i] );
if( "dataEls" in aDataObject )
{
element.selectedItem = element.getElementsByAttribute( "value", aDataObject.dataEls[ lists[i] ].value )[0];
}
else
{
var prefstring = element.getAttribute( "prefstring" );
var preftype = element.getAttribute( "preftype" );
if( prefstring && preftype )
{
prefvalue = gPrefWindow.getPref( preftype, prefstring );
element.selectedItem = element.getElementsByAttribute( "value", prefvalue )[0];
}
}
}
var screenResolution = document.getElementById( "screenResolution" );
var resolution;
if( "fontDPI" in aDataObject )
{
resolution = aDataObject.fontDPI;
}
else
{
prefvalue = gPrefWindow.getPref( "int", "browser.display.screen_resolution" );
if( prefvalue != "!/!ERROR_UNDEFINED_PREF!/!" )
resolution = prefvalue;
else
resolution = 96; // If it all goes horribly wrong, fall back on 96.
}
setResolution( resolution );
if ( gPrefWindow.getPrefIsLocked( "browser.display.screen_resolution" ) ) {
screenResolution.disabled = true;
}
if ( gPrefWindow.getPrefIsLocked( "browser.display.use_document_fonts" ) ) {
useMyFontsCheckbox.disabled = true;
}
if ("dataEls" in aDataObject) {
document.getElementById("foregroundtextmenu").color = aDataObject.dataEls["foregroundText"].value
document.getElementById("backgroundmenu").color = aDataObject.dataEls["background"].value;
document.getElementById("unvisitedlinkmenu").color = aDataObject.dataEls["unvisitedLinks"].value;
document.getElementById("visitedlinkmenu").color = aDataObject.dataEls["visitedLinks"].value;
document.getElementById("browserUseSystemColors").checked = aDataObject.dataEls["browserUseSystemColors"].checked;
document.getElementById("browserUnderlineAnchors").checked = aDataObject.dataEls["browserUnderlineAnchors"].checked;
document.getElementById("useMyColors").checked = aDataObject.dataEls["useMyColors"].checked;
document.getElementById("useMyFonts").checked = aDataObject.dataEls["useMyFonts"].checked;
}
else {
var elt, prefstring;
var checkboxes = ["browserUseSystemColors", "browserUnderlineAnchors"];
for (i = 0; i < checkboxes.length; ++i) {
elt = document.getElementById(checkboxes[i]);
prefstring = elt.getAttribute( "prefstring" );
if( prefstring ) {
prefvalue = gPrefWindow.getPref( "bool", prefstring );
elt.checked = prefvalue;
}
}
var colors = ["foregroundtextmenu", "backgroundmenu", "unvisitedlinkmenu", "visitedlinkmenu"];
for (i = 0; i < colors.length; ++i) {
elt = document.getElementById(colors[i]);
prefstring = elt.nextSibling.getAttribute("prefstring");
if (prefstring) {
prefvalue = gPrefWindow.getPref("color", prefstring);
elt.color = prefvalue;
}
}
var useDocColors = gPrefWindow.getPref("bool", "browser.display.use_document_colors");
document.getElementById("useMyColors").checked = !useDocColors;
var useDocFonts = gPrefWindow.getPref("int", "browser.display.use_document_fonts");
document.getElementById("useMyFonts").checked = !useDocFonts;
}
}
function Startup()
{
// Initialize the sub-dialog
variableSize = document.getElementById( "sizeVar" );
fixedSize = document.getElementById( "sizeMono" );
minSize = document.getElementById( "minSize" );
languageList = document.getElementById( "selectLangs" );
gPrefutilitiesBundle = document.getElementById("bundle_prefutilities");
// eventually we should detect the default language and select it by default
selectLanguage();
// Allow user to ask the OS for a DPI if we are under X or OS/2
if ((navigator.appVersion.indexOf("X11") != -1) || (navigator.appVersion.indexOf("OS/2") != -1))
{
document.getElementById( "systemResolution" ).removeAttribute( "hidden" );
}
// Set up the labels for the standard issue resolutions
var resolution = document.getElementById( "screenResolution" );
// Set an attribute on the selected resolution item so we can fall back on
// it if an invalid selection is made (select "Other...", hit Cancel)
resolution.selectedItem.setAttribute("current", "true");
var defaultResolution;
var otherResolution;
// On OS/2, 120 is the default system resolution.
// 96 is valid, but used only for for 640x480.
if (navigator.appVersion.indexOf("OS/2") != -1)
{
defaultResolution = "120";
otherResolution = "96";
document.getElementById( "arbitraryResolution" ).setAttribute( "hidden", "true" );
document.getElementById( "resolutionSeparator" ).setAttribute( "hidden", "true" );
} else {
defaultResolution = "96";
otherResolution = "72";
}
var dpi = resolution.getAttribute( "dpi" );
resolution = document.getElementById( "defaultResolution" );
resolution.setAttribute( "value", defaultResolution );
resolution.setAttribute( "label", dpi.replace(/\$val/, defaultResolution ) );
resolution = document.getElementById( "otherResolution" );
resolution.setAttribute( "value", otherResolution );
resolution.setAttribute( "label", dpi.replace(/\$val/, otherResolution ) );
// Get the pref and set up the dialog appropriately. Startup is called
// after SetFields so we can't rely on that call to do the business.
var prefvalue = gPrefWindow.getPref( "int", "browser.display.screen_resolution" );
if( prefvalue != "!/!ERROR_UNDEFINED_PREF!/!" )
resolution = prefvalue;
else
resolution = 96; // If it all goes horribly wrong, fall back on 96.
setResolution( resolution );
// This prefstring is a contrived pref whose sole purpose is to lock some
// elements in this panel. The value of the pref is not used and does not matter.
if ( gPrefWindow.getPrefIsLocked( "browser.display.languageList" ) ) {
disableAllFontElements();
}
}
function onFontsDialogOK()
{
gPrefWindow.registerOKCallbackFunc(window.opener.saveFontPrefs);
gPrefWindow.wsm.savePageData(window.location.href, window);
return true;
}
function getFontEnumerator()
{
if (!fontEnumerator)
{
fontEnumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
.createInstance()
.QueryInterface(Components.interfaces.nsIFontEnumerator);
}
return fontEnumerator;
}
function listElement( aListID )
{
this.listElement = document.getElementById( aListID );
}
listElement.prototype =
{
clearList:
function ()
{
// remove the menupopup node child of the menulist.
this.listElement.removeChild( this.listElement.firstChild );
},
appendFontNames:
function ( aLanguage, aFontType )
{
var i;
var defaultFont = null;
var count = { value: 0 };
var fonts = getFontEnumerator().EnumerateFonts( aLanguage, aFontType, count );
if (fonts.length > 0)
{
defaultFont = getFontEnumerator().getDefaultFont( aLanguage, aFontType );
}
else
{
// if no specific fonts, relax 'aFontType' and try to get other
// fonts for this language so that we can group them on top
fonts = getFontEnumerator().EnumerateFonts( aLanguage, "", count );
if (fonts.length > 0)
{
defaultFont = getFontEnumerator().getDefaultFont( aLanguage, "" );
}
}
var itemNode = null;
var separatorNode = null;
var popupNode = document.createElement( "menupopup" );
if (fonts.length > 0)
{
// always put the default font at the front of the list
if (defaultFont)
{
var label = gPrefutilitiesBundle
.formatStringFromName("labelDefaultFont", defaultFont, 1);
itemNode = document.createElement( "menuitem" );
itemNode.setAttribute( "label", label );
itemNode.setAttribute( "value", "" ); // special blank value
popupNode.appendChild( itemNode );
separatorNode = document.createElement( "menuseparator" );
popupNode.appendChild( separatorNode );
}
for (i = 0; i < fonts.length; i++)
{
itemNode = document.createElement( "menuitem" );
itemNode.setAttribute( "value", fonts[i] );
itemNode.setAttribute( "label", fonts[i] );
popupNode.appendChild( itemNode );
}
}
// get all the fonts to complete the font lists
if (!globalFonts)
{
globalFonts = getFontEnumerator().EnumerateAllFonts( count );
}
// since the lists are sorted, we can get unique entries by just walking
// both lists linearly side-by-side, skipping those values already in
// the popup list
if (globalFonts.length > fonts.length)
{
var menuItem = separatorNode ? separatorNode.nextSibling : popupNode.firstChild;
var menuValue = menuItem ? menuItem.getAttribute( "value" ) : null;
separatorNode = document.createElement( "menuseparator" );
popupNode.appendChild( separatorNode );
for (i = 0; i < globalFonts.length; i++)
{
if (globalFonts[i] != menuValue)
{
itemNode = document.createElement( "menuitem" );
itemNode.setAttribute( "value", globalFonts[i] );
itemNode.setAttribute( "label", globalFonts[i] );
popupNode.appendChild( itemNode );
}
else
{
menuItem = menuItem.nextSibling;
menuValue = menuItem ? menuItem.getAttribute( "value" ) : null;
}
}
}
this.listElement.appendChild( popupNode );
return popupNode.firstChild;
}
};
function lazyAppendFontNames( i )
{
// schedule the build of the next font list
if (i+1 < fontTypes.length)
{
window.setTimeout(lazyAppendFontNames, 100, i+1);
}
// now build and populate the fonts for the requested font type
var defaultItem = null;
var selectElement = new listElement( fontTypes[i] );
selectElement.clearList();
try
{
defaultItem = selectElement.appendFontNames( languageList.value, fontTypes[i] );
}
catch(e) {
dump("pref-fonts.js: " + e + "\nFailed to build the font list for " + fontTypes[i] + "\n");
return;
}
// now set the selected font item for the drop down list
if (!defaultItem)
return; // nothing to select, so no need to bother
// the item returned by default is our last resort fall-back
var selectedItem = defaultItem;
if( languageList.value in languageData )
{
// data exists for this language, pre-select items based on this information
var dataVal = languageData[languageList.value].types[fontTypes[i]];
if (!dataVal.length) // special blank means the default
{
selectedItem = defaultItem;
}
else
{
var dataEls = selectElement.listElement.getElementsByAttribute( "value", dataVal );
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
}
}
else
{
try
{
var fontPrefString = "font.name." + fontTypes[i] + "." + languageList.value;
var selectVal = gPrefWindow.pref.CopyUnicharPref( fontPrefString );
var dataEls = selectElement.listElement.getElementsByAttribute( "value", selectVal );
// we need to honor name-list in case name is unavailable
if (!dataEls.length) {
var fontListPrefString = "font.name-list." + fontTypes[i] + "." + languageList.value;
var nameList = gPrefWindow.pref.CopyUnicharPref( fontListPrefString );
var fontNames = nameList.split(",");
var stripWhitespace = /^\s*(.*)\s*$/;
for (j = 0; j < fontNames.length; j++) {
selectVal = fontNames[j].replace(stripWhitespace, "$1");
dataEls = selectElement.listElement.getElementsByAttribute("value", selectVal);
if (dataEls.length)
break; // exit loop if we find one
}
}
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
}
catch(e) {
selectedItem = defaultItem;
}
}
selectElement.listElement.selectedItem = selectedItem;
selectElement.listElement.removeAttribute( "disabled" );
}
function saveState()
{
for( var i = 0; i < fontTypes.length; i++ )
{
// preliminary initialisation
if( currentLanguage && !( currentLanguage in languageData ) )
languageData[currentLanguage] = [];
if( currentLanguage && !( "types" in languageData[currentLanguage] ) )
languageData[currentLanguage].types = [];
// save data for the previous language
if( currentLanguage && currentLanguage in languageData &&
"types" in languageData[currentLanguage] )
languageData[currentLanguage].types[fontTypes[i]] = document.getElementById( fontTypes[i] ).value;
}
if( currentLanguage && currentLanguage in languageData &&
"types" in languageData[currentLanguage] )
{
languageData[currentLanguage].variableSize = parseInt( variableSize.value );
languageData[currentLanguage].fixedSize = parseInt( fixedSize.value );
languageData[currentLanguage].minSize = parseInt( minSize.value );
}
}
// Selects size (or the nearest entry that exists in the list)
// in the menulist minSize
function minSizeSelect(size)
{
var items = minSize.getElementsByAttribute( "value", size );
if (items.length > 0)
minSize.selectedItem = items[0];
else if (size < 6)
minSizeSelect(6);
else if (size > 24)
minSizeSelect(24);
else
minSizeSelect(size - 1);
}
function selectLanguage()
{
// save current state
saveState();
if( currentLanguage == languageList.value )
return; // same as before, nothing changed
currentLanguage = languageList.value;
// lazily populate the successive font lists at 100ms intervals.
// (Note: the third parameter to setTimeout() is going to be
// passed as argument to the callback function.)
window.setTimeout(lazyAppendFontNames, 100, 0);
// in the meantime, disable the menu lists
for( var i = 0; i < fontTypes.length; i++ )
{
var listElement = document.getElementById( fontTypes[i] );
listElement.setAttribute( "value", "" );
listElement.setAttribute( "label", "" );
listElement.setAttribute( "disabled", "true" );
}
// and set the font sizes
var dataObject = gPrefWindow.wsm.dataManager.pageData["chrome://browser/content/pref/pref-fonts.xul"].userData;
var langData = null;
try
{
var sizeVarVal, sizeFixedVal;
if ('languageData' in dataObject) {
langData = dataObject.languageData[currentLanguage];
sizeVarVal = langData.variableSize;
sizeFixedVal = langData.fixedSize;
}
else {
var variableSizePref = "font.size.variable." + languageList.value;
sizeVarVal = gPrefWindow.pref.GetIntPref( variableSizePref );
var fixedSizePref = "font.size.fixed." + languageList.value;
sizeFixedVal = gPrefWindow.pref.GetIntPref( fixedSizePref );
}
variableSize.selectedItem = variableSize.getElementsByAttribute( "value", sizeVarVal )[0];
fixedSize.selectedItem = fixedSize.getElementsByAttribute( "value", sizeFixedVal )[0];
}
catch(e) { } // font size lists can simply default to the first entry
var minSizeVal = 0;
try
{
if (langData) {
minSizeVal = langData.minSize;
}
else {
var minSizePref = "font.minimum-size." + languageList.value;
minSizeVal = gPrefWindow.pref.GetIntPref( minSizePref );
}
}
catch(e) { }
minSizeSelect( minSizeVal );
}
function changeScreenResolution()
{
var screenResolution = document.getElementById("screenResolution");
var userResolution = document.getElementById("userResolution");
var previousSelection = screenResolution.getElementsByAttribute("current", "true")[0];
if (screenResolution.value == "other")
{
// If the user selects "Other..." we bring up the calibrate screen dialog
var rv = { newdpi : 0 };
var calscreen = window.openDialog("chrome://browser/content/pref/pref-calibrate-screen.xul",
"_blank",
"modal,chrome,centerscreen,resizable=no,titlebar",
rv);
if (rv.newdpi != -1)
{
// They have entered values, and we have a DPI value back
setResolution ( rv.newdpi );
previousSelection.removeAttribute("current");
screenResolution.selectedItem.setAttribute("current", "true");
}
else
{
// They've cancelled. We can't leave "Other..." selected, so...
// we re-select the previously selected item.
screenResolution.selectedItem = previousSelection;
}
}
else if (!(screenResolution.value == userResolution.value))
{
// User has selected one of the hard-coded resolutions
userResolution.setAttribute("hidden", "true");
previousSelection.removeAttribute("current");
screenResolution.selectedItem.setAttribute("current", "true");
}
}
function setResolution( resolution )
{
// Given a number, if it's equal to a hard-coded resolution we use that,
// otherwise we set the userResolution field.
var screenResolution = document.getElementById( "screenResolution" );
var userResolution = document.getElementById( "userResolution" );
var items = screenResolution.getElementsByAttribute( "value", resolution );
if (items.length)
{
// If it's one of the hard-coded values, we'll select it directly
screenResolution.selectedItem = items[0];
userResolution.setAttribute( "hidden", "true" );
}
else
{
// Otherwise we need to set up the userResolution field
var dpi = screenResolution.getAttribute( "dpi" );
userResolution.setAttribute( "value", resolution );
userResolution.setAttribute( "label", dpi.replace(/\$val/, resolution) );
userResolution.removeAttribute( "hidden" );
screenResolution.selectedItem = userResolution;
}
}
// "Calibrate screen" dialog code
function Init()
{
sizeToContent();
doSetOKCancel(onOK, onCancel);
document.getElementById("horizSize").focus();
}
function onOK()
{
// Get value from the dialog to work out dpi
var horizSize = parseFloat(document.getElementById("horizSize").value);
var units = document.getElementById("units").value;
if (!horizSize || horizSize < 0)
{
// We can't calculate anything without a proper value
window.arguments[0].newdpi = -1;
return true;
}
// Convert centimetres to inches.
// The magic number is allowed because it's a fundamental constant :-)
if (units === "centimetres")
{
horizSize /= 2.54;
}
// These shouldn't change, but you can't be too careful.
var horizBarLengthPx = document.getElementById("horizRuler").boxObject.width;
var horizDPI = parseInt(horizBarLengthPx) / horizSize;
// Average the two <shrug>.
window.arguments[0].newdpi = Math.round(horizDPI);
return true;
}
function onCancel()
{
// We return -1 to show that no value has been given.
window.arguments[0].newdpi = -1;
return true;
}
// disable font items, but not the useMyFonts checkbox nor the resolution
// menulist
function disableAllFontElements()
{
var doc_ids = [ "selectLangs", "proportionalFont",
"sizeVar", "serif", "sans-serif",
"sizeMono", "minSize" ];
for (i=0; i<doc_ids.length; i++) {
element = document.getElementById( doc_ids[i] );
element.disabled = true;
}
}