зеркало из https://github.com/mozilla/pjs.git
fixed bug where <select> assummed all children were <option>s
This commit is contained in:
Родитель
1f3c80a00b
Коммит
677fc6c2c6
|
@ -355,7 +355,8 @@ nsContentAttr nsInput::GetAttribute(nsIAtom* aAttribute, nsString& aValue) const
|
|||
return eContentAttr_HasValue;
|
||||
}
|
||||
else {
|
||||
aValue = "";
|
||||
//aValue = ""; // XXX string class was crashing on this line
|
||||
aValue.SetLength(0);
|
||||
return eContentAttr_NoValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,10 +43,16 @@
|
|||
#include "nsStyleUtil.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
#define NS_IOPTION_IID \
|
||||
{ 0xfa6a8b11, 0x2af2, 0x11d2, \
|
||||
{ 0x80, 0x3a, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
|
||||
|
||||
static NS_DEFINE_IID(kListWidgetIID, NS_ILISTWIDGET_IID);
|
||||
static NS_DEFINE_IID(kComboBoxIID, NS_ICOMBOBOX_IID);
|
||||
static NS_DEFINE_IID(kListBoxIID, NS_ILISTBOX_IID);
|
||||
static NS_DEFINE_IID(kOptionIID, NS_IOPTION_IID);
|
||||
|
||||
class nsOption;
|
||||
|
||||
class nsSelectFrame : public nsInputFrame {
|
||||
public:
|
||||
|
@ -88,6 +94,8 @@ public:
|
|||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aResult);
|
||||
|
||||
nsOption* GetNthOption(PRInt32 aIndex);
|
||||
|
||||
virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue);
|
||||
|
||||
virtual nsContentAttr GetAttribute(nsIAtom* aAttribute,
|
||||
|
@ -126,6 +134,8 @@ public:
|
|||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aResult);
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue);
|
||||
|
||||
virtual nsContentAttr GetAttribute(nsIAtom* aAttribute,
|
||||
|
@ -242,23 +252,28 @@ nsSelectFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
nsSize styleSize;
|
||||
GetStyleSize(*aPresContext, aReflowState, styleSize);
|
||||
|
||||
// get the size of the longest child
|
||||
// get the size of the longest option child
|
||||
PRInt32 maxWidth = 1;
|
||||
PRInt32 numChildren = select->ChildCount();
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
nsOption* option = (nsOption*) select->ChildAt(i); // YYY this had better be an option
|
||||
option->CompressContent();
|
||||
nsString text;
|
||||
if (PR_FALSE == option->GetContent(text)) {
|
||||
continue;
|
||||
for (int childX = 0; childX < numChildren; childX++) {
|
||||
nsIContent* child = select->ChildAt(childX);
|
||||
nsOption* option;
|
||||
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
|
||||
if (NS_OK == result) {
|
||||
option->CompressContent();
|
||||
nsString text;
|
||||
if (PR_FALSE == option->GetContent(text)) {
|
||||
continue;
|
||||
}
|
||||
nsSize textSize;
|
||||
// use the style for the select rather that the option, since widgets don't support it
|
||||
nsInputFrame::GetTextSize(*aPresContext, this, text, textSize);
|
||||
if (textSize.width > maxWidth) {
|
||||
maxWidth = textSize.width;
|
||||
}
|
||||
NS_RELEASE(option);
|
||||
}
|
||||
nsSize textSize;
|
||||
// use the style for the select rather that the option, since widgets don't support it
|
||||
nsInputFrame::GetTextSize(*aPresContext, this, text, textSize);
|
||||
if (textSize.width > maxWidth) {
|
||||
maxWidth = textSize.width;
|
||||
}
|
||||
NS_RELEASE(option); // YYY remove this comment if ok
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
|
||||
PRInt32 rowHeight = 0;
|
||||
|
@ -363,14 +378,21 @@ nsSelectFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
|
|||
}
|
||||
|
||||
PRInt32 numChildren = select->ChildCount();
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
nsOption* option = (nsOption*) select->ChildAt(i); // YYY this had better be an option
|
||||
nsString text;
|
||||
if (PR_TRUE != option->GetContent(text)) {
|
||||
text = " ";
|
||||
int optionX = -1;
|
||||
for (int childX = 0; childX < numChildren; childX++) {
|
||||
nsIContent* child = select->ChildAt(childX);
|
||||
nsOption* option;
|
||||
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
|
||||
if (NS_OK == result) {
|
||||
optionX++;
|
||||
nsString text;
|
||||
if (PR_TRUE != option->GetContent(text)) {
|
||||
text = " ";
|
||||
}
|
||||
list->AddItemAt(text, optionX);
|
||||
NS_RELEASE(option);
|
||||
}
|
||||
list->AddItemAt(text, i);
|
||||
NS_RELEASE(option); // YYY remove comment if ok
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
|
||||
NS_RELEASE(view);
|
||||
|
@ -443,6 +465,27 @@ nsSelect::GetMaxNumValues()
|
|||
}
|
||||
}
|
||||
|
||||
nsOption* nsSelect::GetNthOption(PRInt32 aIndex)
|
||||
{
|
||||
int optionX = -1;
|
||||
PRInt32 numChildren = ChildCount();
|
||||
for (int childX = 0; childX < numChildren; childX++) {
|
||||
nsIContent* child = ChildAt(childX);
|
||||
nsOption* option;
|
||||
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
|
||||
if (NS_OK == result) {
|
||||
optionX++;
|
||||
if (aIndex == optionX) {
|
||||
NS_RELEASE(child);
|
||||
return option;
|
||||
}
|
||||
NS_RELEASE(option);
|
||||
}
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSelect::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
||||
nsString* aValues, nsString* aNames)
|
||||
|
@ -459,11 +502,13 @@ nsSelect::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
|||
NS_ASSERTION((NS_OK == stat), "invalid widget");
|
||||
PRInt32 index = list->GetSelectedIndex();
|
||||
if (index >= 0) {
|
||||
nsOption* selected = (nsOption*)ChildAt(index);
|
||||
selected->GetNamesValues(aMaxNumValues, aNumValues, aValues, aNames);
|
||||
aNames[0] = *mName;
|
||||
NS_RELEASE(selected); // YYY remove this comment if ok
|
||||
return PR_TRUE;
|
||||
nsOption* selected = GetNthOption(index);
|
||||
if (selected) {
|
||||
selected->GetNamesValues(aMaxNumValues, aNumValues, aValues, aNames);
|
||||
aNames[0] = *mName;
|
||||
NS_RELEASE(selected); // YYY remove this comment if ok
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aNumValues = 0;
|
||||
|
@ -482,13 +527,16 @@ nsSelect::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
|||
PRInt32 numValues;
|
||||
aNumValues = 0;
|
||||
for (int i = 0; i < numSelections; i++) {
|
||||
nsOption* selected = (nsOption*)ChildAt(selections[i]);
|
||||
selected->GetNamesValues(aMaxNumValues - i, numValues,
|
||||
aValues + i, aNames + i); // options can only have 1 value
|
||||
aNames[i] = *mName;
|
||||
aNumValues += 1;
|
||||
NS_RELEASE(selected); // YYY remove this comment if ok
|
||||
nsOption* selected = GetNthOption(selections[i]);
|
||||
if (selected) {
|
||||
selected->GetNamesValues(aMaxNumValues - i, numValues,
|
||||
aValues + i, aNames + i); // options can only have 1 value
|
||||
aNames[i] = *mName;
|
||||
aNumValues += 1;
|
||||
NS_RELEASE(selected); // YYY remove this comment if ok
|
||||
}
|
||||
}
|
||||
delete [] selections;
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
|
@ -496,6 +544,8 @@ nsSelect::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
|||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
aNumValues = 0;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -513,18 +563,25 @@ nsSelect::Reset()
|
|||
list->Deselect();
|
||||
|
||||
PRInt32 selIndex = -1;
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
nsOption* option = (nsOption*)ChildAt(i); // YYY this had better be an option
|
||||
PRInt32 selAttr;
|
||||
((nsInput *)option)->GetAttribute(nsHTMLAtoms::selected, selAttr);
|
||||
if (ATTR_NOTSET != selAttr) {
|
||||
list->SelectItem(i);
|
||||
selIndex = i;
|
||||
if (!mMultiple) {
|
||||
break;
|
||||
int optionX = -1;
|
||||
for (int childX = 0; childX < numChildren; childX++) {
|
||||
nsIContent* child = ChildAt(childX);
|
||||
nsOption* option;
|
||||
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
|
||||
if (NS_OK == result) {
|
||||
optionX++;
|
||||
PRInt32 selAttr;
|
||||
((nsInput *)option)->GetAttribute(nsHTMLAtoms::selected, selAttr);
|
||||
if (ATTR_NOTSET != selAttr) {
|
||||
list->SelectItem(optionX);
|
||||
selIndex = optionX;
|
||||
if (!mMultiple) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(option);
|
||||
}
|
||||
NS_RELEASE(option); // YYY remove this comment if ok
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
|
||||
// if none were selected, select 1st one if we are a combo box
|
||||
|
@ -571,6 +628,16 @@ nsOption::CreateFrame(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsOption::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aIID.Equals(kOptionIID)) {
|
||||
AddRef();
|
||||
*aInstancePtr = (void**) this;
|
||||
return NS_OK;
|
||||
}
|
||||
return nsInput::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
void nsOption::SetAttribute(nsIAtom* aAttribute,
|
||||
const nsString& aValue)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче