Bug 16999: Get default button labels from .properties file instead of html.css (GfxButtonControlFrame -> anonymous content creator). r=rods a=rickg

git-svn-id: svn://10.0.0.236/trunk@61376 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pollmann%netscape.com
2000-02-21 05:55:25 +00:00
parent b39123b16a
commit 28d2487189
8 changed files with 500 additions and 106 deletions

View File

@@ -25,9 +25,16 @@
#include "nsWidgetsCID.h"
#include "nsIFontMetrics.h"
#include "nsFormControlFrame.h"
#include "nsIServiceManager.h"
#include "nsIIOService.h"
#include "nsIURI.h"
#include "nsIStringBundle.h"
#include "nsITextContent.h"
#include "nsISupportsArray.h"
#include "nsXPIDLString.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
const nscoord kSuggestedNotSet = -1;
@@ -36,6 +43,7 @@ nsGfxButtonControlFrame::nsGfxButtonControlFrame()
mRenderer.SetNameSpace(kNameSpaceID_None);
mSuggestedWidth = kSuggestedNotSet;
mSuggestedHeight = kSuggestedNotSet;
mUpdateValue = "";
}
PRBool
@@ -127,6 +135,42 @@ nsGfxButtonControlFrame::IsSubmit(PRInt32 type)
}
}
// Special check for the browse button of a file input.
//
// Since this is actually type "NS_FORM_INPUT_BUTTON", we
// can't tell if it is part of a file input by the type.
// We'll return PR_TRUE if either:
// (a) type is NS_FORM_BROWSE or
// (b) type is NS_FORM_INPUT_BUTTON and our parent is a file input
PRBool
nsGfxButtonControlFrame::IsBrowse(PRInt32 type)
{
if (NS_FORM_BROWSE == type) {
return PR_TRUE;
}
if (NS_FORM_INPUT_BUTTON == type) {
// Check to see if parent is a file input
nsIContent* parentContent;
mContent->GetParent(parentContent);
nsIAtom* atom;
if (parentContent->GetTag(atom) == NS_OK && atom == nsHTMLAtoms::input) {
// It's an input, is it a file input?
nsString value;
if (NS_CONTENT_ATTR_HAS_VALUE == parentContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, value)) {
value.ToUpperCase();
nsString file("FILE");
if (value == file) {
return PR_TRUE;
}
}
}
NS_RELEASE(parentContent);
}
return PR_FALSE;
}
/*
* FIXME: this ::GetIID() method has no meaning in life and should be
* removed.
@@ -184,33 +228,11 @@ nsGfxButtonControlFrame::DoNavQuirksReflow(nsIPresContext* aPresContext
// Get the text from the "value" attribute
// for measuring the height, width of the text
// if there is no value attr or its length is 0
// then go to the generated content to get it
// This shouldn't be zero because if it was we set it to
// a default. See CreateAnonymousContent and Reflow
nsAutoString value;
GetValue(&value);
// if there was no value specified
// then go get the content of the generated content
// we can't make any assumption as to what the default would be
// because of the value is specified in the html.css and for
// for non-english platforms it might not be the string
// "Reset" or "Submit Query"
if (value.Length() == 0) {
value = " ";
// The child frame will br the generated content
nsIFrame* fKid;
firstKid->FirstChild(aPresContext, nsnull, &fKid);
if (fKid) {
const nsStyleContent* content;
fKid->GetStyleData(eStyleStruct_Content, (const nsStyleStruct *&)content);
PRUint32 count = content->ContentCount();
// XXX not sure if I need to get more than the first index?
if (count > 0) {
nsStyleContentType contentType = eStyleContentType_String;
content->GetContentAt(0, contentType, value);
}
}
}
const nsStyleText* textStyle;
GetStyleData(eStyleStruct_Text, (const nsStyleStruct *&)textStyle);
if (!textStyle->WhiteSpaceIsSignificant()) {
@@ -320,6 +342,164 @@ nsGfxButtonControlFrame::DoNavQuirksReflow(nsIPresContext* aPresContext
return NS_OK;
}
// Create the text content used as label for the button.
// The frame will be generated by the frame constructor.
NS_IMETHODIMP
nsGfxButtonControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
nsISupportsArray& aChildList)
{
nsresult result;
// Get the text from the "value" attribute.
// If it is zero length, set it to a default value (localized)
nsAutoString initvalue, value;
GetValue(&initvalue);
value = initvalue;
if (value.Length() == 0) {
// Generate localized label.
// We can't make any assumption as to what the default would be
// because the value is localized for non-english platforms, thus
// it might not be the string "Reset", "Submit Query", or "Browse..."
result = GetDefaultLabel(value);
if (NS_FAILED(result)) {
return result;
}
}
// Compress whitespace out of label if needed.
const nsStyleText* textStyle;
GetStyleData(eStyleStruct_Text, (const nsStyleStruct *&)textStyle);
if (!textStyle->WhiteSpaceIsSignificant()) {
value.CompressWhitespace();
if (value.Length() == 0) {
value = " ";
}
}
// Cache this value away until we have created
// a frame so we can update the value attribute.
// This makes input.value return the default string as in Nav and IE.
if (initvalue != value) {
mUpdateValue = value;
}
// Add a child text content node for the label
nsCOMPtr<nsIContent> labelContent;
result = NS_NewTextNode(getter_AddRefs(labelContent));
if (NS_SUCCEEDED(result) && labelContent) {
// set the value of the text node
labelContent->QueryInterface(NS_GET_IID(nsITextContent), getter_AddRefs(mTextContent));
mTextContent->SetText(value.GetUnicode(), value.Length(), PR_TRUE);
aChildList.AppendElement(mTextContent);
}
return result;
}
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
} else if (aIID.Equals(NS_GET_IID(nsIAnonymousContentCreator))) {
*aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
return NS_OK;
}
return nsHTMLButtonControlFrame::QueryInterface(aIID, aInstancePtr);
}
// Initially we hardcoded the default strings here.
// Next, we used html.css to store the default label for various types
// of buttons. (nsGfxButtonControlFrame::DoNavQuirksReflow rev 1.20)
// However, since html.css is not internationalized, we now grab the default
// label from a string bundle as is done for all other UI strings.
// See bug 16999 for further details.
NS_IMETHODIMP
nsGfxButtonControlFrame::GetDefaultLabel(nsString& aString)
{
nsresult rv = NS_OK;
PRInt32 type;
GetType(&type);
if (IsReset(type)) {
rv = ButtonLocalize("Reset", aString);
}
else if (IsSubmit(type)) {
rv = ButtonLocalize("Submit", aString);
}
else if (IsBrowse(type)) {
rv = ButtonLocalize("Browse", aString);
}
else {
aString = " ";
rv = NS_OK;
}
return rv;
}
#define form_properties "chrome://layout/locale/HtmlForm.properties"
// Return localised string for resource string (e.g. "Submit" -> "Submit Query")
// This code is derived from nsBookmarksService::Init() and cookie_Localize()
NS_IMETHODIMP
nsGfxButtonControlFrame::ButtonLocalize(char* aKey, nsString& oVal)
{
nsresult rv;
nsCOMPtr<nsIStringBundle> bundle;
// Create a URL for the string resource file
// Create a bundle for the localization
NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv);
if (NS_SUCCEEDED(rv) && pNetService) {
nsCOMPtr<nsIURI> uri;
rv = pNetService->NewURI(form_properties, nsnull, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv) && uri) {
// Create bundle
NS_WITH_SERVICE(nsIStringBundleService, stringService, kStringBundleServiceCID, &rv);
if (NS_SUCCEEDED(rv) && stringService) {
nsXPIDLCString spec;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_SUCCEEDED(rv) && spec) {
nsCOMPtr<nsILocale> locale = nsnull;
rv = stringService->CreateBundle(spec, locale, getter_AddRefs(bundle));
}
}
}
}
// Determine default label from string bundle
if (NS_SUCCEEDED(rv) && bundle && aKey) {
nsXPIDLString valUni;
nsAutoString key(aKey);
rv = bundle->GetStringFromName(key.GetUnicode(), getter_Copies(valUni));
if (NS_SUCCEEDED(rv) && valUni) {
oVal = valUni;
} else {
oVal.Truncate();
}
}
return rv;
}
NS_IMETHODIMP
nsGfxButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
// If the value attribute is set, update the text of the label
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
if (nsnull != mTextContent && NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, value)) {
mTextContent->SetText(value.GetUnicode(), value.Length(), PR_TRUE);
}
}
return nsHTMLButtonControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
}
NS_IMETHODIMP
nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -328,8 +508,27 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
{
// The mFormFrame is set in the initial reflow within nsHTMLButtonControlFrame
nsresult rv = NS_OK;
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
if (eReflowReason_Initial == aReflowState.reason) {
if (!mFormFrame) {
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
// If we cached a value (mUpdateValue) in CreateAnonymousContent(),
// set the value attribute of the button to this generated label.
// This will allow e.g. submit inputs to return a value of Submit Query
// when none is specified, as they do in IE 5.0 and Nav 4.x. We have to
// wait until now because updating our value attribute will cause a
// reflow and the frame must exist.
if (mUpdateValue.Length() != 0) {
if (mContent) {
nsIHTMLContent* formControl = nsnull;
rv = mContent->QueryInterface(kIHTMLContentIID, (void**)&formControl);
if (NS_SUCCEEDED(rv) && formControl) {
rv = formControl->SetHTMLAttribute(nsHTMLAtoms::value, mUpdateValue, PR_TRUE);
NS_RELEASE(formControl);
}
}
mUpdateValue = "";
}
}
#if 0