зеркало из https://github.com/mozilla/gecko-dev.git
Fix 206780 - font selecting bastage. Patch by mal@mozilla.gr.jp.
This commit is contained in:
Родитель
dbe0fc80cf
Коммит
a4300fd5ec
|
@ -39,10 +39,6 @@
|
|||
|
||||
try
|
||||
{
|
||||
var fontList = Components.classes["@mozilla.org/gfx/fontlist;1"].createInstance();
|
||||
if (fontList)
|
||||
fontList = fontList.QueryInterface(Components.interfaces.nsIFontList);
|
||||
|
||||
var pref = Components.classes["@mozilla.org/preferences;1"].getService( Components.interfaces.nsIPref );
|
||||
}
|
||||
catch(e)
|
||||
|
@ -50,6 +46,8 @@ 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 = [];
|
||||
|
@ -258,6 +256,17 @@ function Startup()
|
|||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
|
@ -272,47 +281,171 @@ listElement.prototype =
|
|||
this.listElement.removeChild( this.listElement.firstChild );
|
||||
},
|
||||
|
||||
appendString:
|
||||
function ( aString )
|
||||
{
|
||||
var menuItemNode = document.createElement( "menuitem" );
|
||||
if( menuItemNode )
|
||||
{
|
||||
menuItemNode.setAttribute( "label", aString );
|
||||
this.listElement.firstChild.appendChild( menuItemNode );
|
||||
}
|
||||
},
|
||||
|
||||
appendFontNames:
|
||||
function ( aDataObject )
|
||||
{
|
||||
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" );
|
||||
var strDefaultFontFace = "";
|
||||
var fontName;
|
||||
while (aDataObject.hasMoreElements()) {
|
||||
fontName = aDataObject.getNext();
|
||||
fontName = fontName.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
var fontNameStr = fontName.toString();
|
||||
if (strDefaultFontFace == "")
|
||||
strDefaultFontFace = fontNameStr;
|
||||
var itemNode = document.createElement( "menuitem" );
|
||||
itemNode.setAttribute( "value", fontNameStr );
|
||||
itemNode.setAttribute( "label", fontNameStr );
|
||||
popupNode.appendChild( itemNode );
|
||||
}
|
||||
if (strDefaultFontFace != "") {
|
||||
this.listElement.removeAttribute( "disabled" );
|
||||
} else {
|
||||
this.listElement.setAttribute( "value", strDefaultFontFace );
|
||||
this.listElement.setAttribute( "label",
|
||||
gPrefutilitiesBundle.getString("nofontsforlang") );
|
||||
this.listElement.setAttribute( "disabled", "true" );
|
||||
}
|
||||
if (fonts.length > 0)
|
||||
{
|
||||
// always put the default font at the front of the list
|
||||
if (defaultFont)
|
||||
{
|
||||
var label = gPrefutilitiesBundle
|
||||
.getString("labelDefaultFont")
|
||||
.replace(/%font_family%/, defaultFont);
|
||||
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 strDefaultFontFace;
|
||||
|
||||
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 = parent.hPrefWindow.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 = parent.hPrefWindow.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 saveFontPrefs()
|
||||
{
|
||||
// if saveState function is available, assume can call it.
|
||||
|
@ -339,8 +472,30 @@ function saveFontPrefs()
|
|||
catch(e)
|
||||
{
|
||||
}
|
||||
if( currValue != dataObject.languageData[language].types[type] )
|
||||
pref.SetUnicharPref( fontPrefString, dataObject.languageData[language].types[type] );
|
||||
|
||||
var dataValue = dataObject.languageData[language].types[type];
|
||||
if( currValue != dataValue )
|
||||
{
|
||||
if (dataValue)
|
||||
{
|
||||
pref.SetUnicharPref( fontPrefString, dataValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
// A font name can't be blank. The special blank means the default.
|
||||
// Unset the pref entirely, letting Gfx to decide. GfxXft will use what
|
||||
// Xft says, whereas GfxWin and others will use the built-in settings
|
||||
// that are shipped for font.name and font.name-list.
|
||||
try
|
||||
{
|
||||
// ClearUserPref throws an exception...
|
||||
pref.ClearUserPref( fontPrefString );
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var variableSizePref = "font.size.variable." + language;
|
||||
var fixedSizePref = "font.size.fixed." + language;
|
||||
|
@ -452,123 +607,45 @@ function selectLanguage()
|
|||
|
||||
if( !currentLanguage )
|
||||
currentLanguage = languageList.value;
|
||||
else if( currentLanguage == languageList.value )
|
||||
return; // same as before, nothing changed
|
||||
|
||||
// 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++ )
|
||||
{
|
||||
// build and populate the font list for the newly chosen font type
|
||||
var fontEnumerator = fontList.availableFonts(languageList.value, fontTypes[i]);
|
||||
var selectElement = new listElement( fontTypes[i] );
|
||||
selectElement.clearList();
|
||||
var strDefaultFontFace = selectElement.appendFontNames(fontEnumerator);
|
||||
//the first font face name returned by the enumerator is our last resort
|
||||
var defaultListSelection = selectElement.listElement.getElementsByAttribute( "value", strDefaultFontFace)[0];
|
||||
var selectedItem;
|
||||
|
||||
//fall-back initialization values (first font face list entry)
|
||||
defaultListSelection = strDefaultFontFace ? selectElement.listElement.getElementsByAttribute( "value", strDefaultFontFace)[0] : null;
|
||||
|
||||
if( languageList.value in languageData )
|
||||
{
|
||||
// data exists for this language, pre-select items based on this information
|
||||
var dataElements = selectElement.listElement.getElementsByAttribute( "value", languageData[languageList.value].types[fontTypes[i]] );
|
||||
selectedItem = dataElements.length ? dataElements[0] : defaultListSelection;
|
||||
|
||||
minSizeSelect(languageData[languageList.value].minSize);
|
||||
if (strDefaultFontFace)
|
||||
{
|
||||
selectElement.listElement.selectedItem = selectedItem;
|
||||
variableSize.removeAttribute("disabled");
|
||||
fixedSize.removeAttribute("disabled");
|
||||
minSize.removeAttribute("disabled");
|
||||
variableSize.selectedItem = variableSize.getElementsByAttribute( "value", languageData[languageList.value].variableSize )[0];
|
||||
fixedSize.selectedItem = fixedSize.getElementsByAttribute( "value", languageData[languageList.value].fixedSize )[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
variableSize.setAttribute("disabled","true");
|
||||
fixedSize.setAttribute("disabled","true");
|
||||
minSize.setAttribute("disabled","true");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (strDefaultFontFace) {
|
||||
//initialze pref panel only if font faces are available for this language family
|
||||
|
||||
var selectVal;
|
||||
|
||||
try {
|
||||
var fontPrefString = "font.name." + fontTypes[i] + "." + languageList.value;
|
||||
selectVal = parent.hPrefWindow.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 = parent.hPrefWindow.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] : defaultListSelection;
|
||||
if (!dataEls.length)
|
||||
selectedVal = strDefaultFontFace;
|
||||
}
|
||||
catch(e) {
|
||||
//always initialize: fall-back to default values
|
||||
selectVal = strDefaultFontFace;
|
||||
selectedItem = defaultListSelection;
|
||||
}
|
||||
|
||||
selectElement.listElement.selectedItem = selectedItem;
|
||||
|
||||
variableSize.removeAttribute("disabled");
|
||||
fixedSize.removeAttribute("disabled");
|
||||
minSize.removeAttribute("disabled");
|
||||
|
||||
|
||||
try {
|
||||
var variableSizePref = "font.size.variable." + languageList.value;
|
||||
var fixedSizePref = "font.size.fixed." + languageList.value;
|
||||
|
||||
var sizeVarVal = parent.hPrefWindow.pref.GetIntPref( variableSizePref );
|
||||
var sizeFixedVal = parent.hPrefWindow.pref.GetIntPref( fixedSizePref );
|
||||
|
||||
variableSize.selectedItem = variableSize.getElementsByAttribute( "value", sizeVarVal )[0];
|
||||
|
||||
fixedSize.selectedItem = fixedSize.getElementsByAttribute( "value", sizeFixedVal )[0];
|
||||
}
|
||||
|
||||
catch(e) {
|
||||
//font size lists can simply deafult to the first entry
|
||||
}
|
||||
var minSizeVal = 0;
|
||||
try {
|
||||
var minSizePref = "font.minimum-size." + languageList.value;
|
||||
minSizeVal = pref.GetIntPref( minSizePref );
|
||||
}
|
||||
catch(e) {}
|
||||
minSizeSelect( minSizeVal );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//disable otherwise
|
||||
variableSize.setAttribute("disabled","true");
|
||||
fixedSize.setAttribute("disabled","true");
|
||||
minSize.setAttribute("disabled","true");
|
||||
minSizeSelect(0);
|
||||
}
|
||||
}
|
||||
var listElement = document.getElementById( fontTypes[i] );
|
||||
listElement.setAttribute( "value", "" );
|
||||
listElement.setAttribute( "label", "" );
|
||||
listElement.setAttribute( "disabled", "true" );
|
||||
}
|
||||
|
||||
// and set the font sizes
|
||||
try
|
||||
{
|
||||
var variableSizePref = "font.size.variable." + languageList.value;
|
||||
var sizeVarVal = parent.hPrefWindow.pref.GetIntPref( variableSizePref );
|
||||
variableSize.selectedItem = variableSize.getElementsByAttribute( "value", sizeVarVal )[0];
|
||||
|
||||
var fixedSizePref = "font.size.fixed." + languageList.value;
|
||||
var sizeFixedVal = parent.hPrefWindow.pref.GetIntPref( fixedSizePref );
|
||||
fixedSize.selectedItem = fixedSize.getElementsByAttribute( "value", sizeFixedVal )[0];
|
||||
}
|
||||
catch(e) { } // font size lists can simply default to the first entry
|
||||
|
||||
var minSizeVal = 0;
|
||||
try
|
||||
{
|
||||
var minSizePref = "font.minimum-size." + languageList.value;
|
||||
minSizeVal = pref.GetIntPref( minSizePref );
|
||||
}
|
||||
catch(e) { }
|
||||
minSizeSelect( minSizeVal );
|
||||
|
||||
currentLanguage = languageList.value;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче