[XForms] precedence order of content of hint element is wrong. Bug 338135, patch by msterlin, r=olli+aaronr

This commit is contained in:
aaronr%us.ibm.com 2006-06-26 22:12:09 +00:00
Родитель e93d1088d8
Коммит 79c450bcb0
3 изменённых файлов: 153 добавлений и 32 удалений

Просмотреть файл

@ -128,14 +128,19 @@ class nsXFormsMessageElement : public nsXFormsDelegateStub,
{
public:
NS_DECL_ISUPPORTS_INHERITED
// nsIXFormsDelegate
NS_IMETHOD GetValue(nsAString& aValue);
// nsIXTFElement overrides
NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper);
NS_IMETHOD WillChangeDocument(nsIDOMDocument *aNewDocument);
NS_IMETHOD OnDestroyed();
NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent);
NS_IMETHOD WillChangeParent(nsIDOMElement *aNewParent);
NS_IMETHOD AttributeSet(nsIAtom *aName, const nsAString &aSrc);
NS_IMETHOD AttributeRemoved(nsIAtom *aName);
NS_IMETHOD DoneAddingChildren();
NS_DECL_NSICHANNELEVENTSINK
NS_DECL_NSIREQUESTOBSERVER
@ -172,7 +177,8 @@ public:
nsXFormsMessageElement(MessageType aType) :
mType(aType), mPosX(-1), mPosY(-1), mDocument(nsnull),
mStopType(eStopType_None) {}
mStopType(eStopType_None), mSrcAttrText(""),
mDoneAddingChildren(PR_FALSE) {}
private:
nsresult HandleEphemeralMessage(nsIDOMDocument* aDoc, nsIDOMEvent* aEvent);
nsresult HandleModalAndModelessMessage(nsIDOMDocument* aDoc, nsAString& aLevel);
@ -198,6 +204,11 @@ private:
*/
void AddRemoveExternalResource(PRBool aAdd);
/**
* Determine if the message is Ephemeral.
*/
PRBool IsEphemeral();
MessageType mType;
// The position of the ephemeral message
@ -207,7 +218,9 @@ private:
nsCOMPtr<nsITimer> mEphemeralTimer;
nsIDOMDocument* mDocument;
nsCOMPtr<nsIChannel> mChannel;
StopType mStopType;
StopType mStopType;
nsCString mSrcAttrText;
PRBool mDoneAddingChildren;
};
NS_IMPL_ADDREF_INHERITED(nsXFormsMessageElement, nsXFormsDelegateStub)
@ -223,6 +236,18 @@ NS_INTERFACE_MAP_END_INHERITING(nsXFormsDelegateStub)
// nsIXTFElement
NS_IMETHODIMP
nsXFormsMessageElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper)
{
nsresult rv = nsXFormsDelegateStub::OnCreated(aWrapper);
NS_ENSURE_SUCCESS(rv, rv);
aWrapper->SetNotificationMask(kStandardNotificationMask |
nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT |
nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsMessageElement::WillChangeDocument(nsIDOMDocument *aNewDocument)
{
@ -379,15 +404,19 @@ nsXFormsMessageElement::ParentChanged(nsIDOMElement *aNewParent)
NS_IMETHODIMP
nsXFormsMessageElement::AttributeSet(nsIAtom *aName, const nsAString &aValue)
{
if (aName == nsXFormsAtoms::src) {
// If we are currently trying to load an external message, cancel the
// request.
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
if (mDoneAddingChildren) {
if (aName == nsXFormsAtoms::src) {
// If we are currently trying to load an external message, cancel the
// request.
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
mStopType = eStopType_None;
TestExternalFile();
mStopType = eStopType_None;
// The src attribute has changed so retest the external file.
TestExternalFile();
}
}
return nsXFormsDelegateStub::AttributeSet(aName, aValue);
@ -396,19 +425,31 @@ nsXFormsMessageElement::AttributeSet(nsIAtom *aName, const nsAString &aValue)
NS_IMETHODIMP
nsXFormsMessageElement::AttributeRemoved(nsIAtom *aName)
{
if (aName == nsXFormsAtoms::src) {
// If we are currently trying to test an external resource, cancel the
// request.
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
if (mDoneAddingChildren) {
if (aName == nsXFormsAtoms::src) {
// If we are currently trying to test an external resource, cancel the
// request.
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
mStopType = eStopType_None;
mSrcAttrText.Truncate();
mStopType = eStopType_None;
}
}
return nsXFormsDelegateStub::AttributeRemoved(aName);
}
NS_IMETHODIMP
nsXFormsMessageElement::DoneAddingChildren()
{
mDoneAddingChildren = PR_TRUE;
TestExternalFile();
return NS_OK;
}
NS_IMETHODIMP
nsXFormsMessageElement::HandleAction(nsIDOMEvent* aEvent,
nsIXFormsActionElement *aParentAction)
@ -960,18 +1001,17 @@ nsXFormsMessageElement::TestExternalFile()
// and in most cases we pass off the URL to another browser service to
// get and display the message so no good to try to look at the contents
// anyway.
// XXX ephemeral messages should probably get their full contents here once
// they are set up to handle external resources.
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
if (httpChannel) {
PRBool isReallyHTTP = PR_FALSE;
uri->SchemeIs("http", &isReallyHTTP);
if (!isReallyHTTP) {
uri->SchemeIs("https", &isReallyHTTP);
}
if (isReallyHTTP) {
httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("HEAD"));
if (!IsEphemeral()) {
PRBool isReallyHTTP = PR_FALSE;
uri->SchemeIs("http", &isReallyHTTP);
if (!isReallyHTTP) {
uri->SchemeIs("https", &isReallyHTTP);
}
if (isReallyHTTP) {
httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("HEAD"));
}
}
}
@ -995,6 +1035,32 @@ nsXFormsMessageElement::TestExternalFile()
return NS_OK;
}
NS_IMETHODIMP
nsXFormsMessageElement::GetValue(nsAString& aValue)
{
// The order of precedence for determining the text of the message
// is: single node binding, linking, inline text (8.3.5). We cache
// the value of the external message (via mSrcAttrText) for hints
// and ephemeral messages.
nsXFormsDelegateStub::GetValue(aValue);
if (aValue.IsVoid()) {
if (!mSrcAttrText.IsEmpty()) {
// handle linking ('src') attribute
aValue = NS_ConvertUTF8toUTF16(mSrcAttrText);
}
else {
// Return inline value
nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(mElement);
if (node) {
node->GetTextContent(aValue);
}
}
}
return NS_OK;
}
// nsIInterfaceRequestor
NS_IMETHODIMP
@ -1050,6 +1116,12 @@ nsXFormsMessageElement::OnStartRequest(nsIRequest *aRequest,
NS_ASSERTION(aRequest == mChannel, "unexpected request");
NS_ASSERTION(mChannel, "no channel");
if (!mElement) {
AddRemoveExternalResource(PR_FALSE);
mChannel = nsnull;
return NS_BINDING_ABORTED;
}
nsresult status;
nsresult rv = mChannel->GetStatus(&status);
// DNS errors and other obvious problems will return failure status
@ -1094,6 +1166,15 @@ nsXFormsMessageElement::OnStartRequest(nsIRequest *aRequest,
}
}
// If the type is Hint or Ephemeral we want to return ns_ok so that callbacks
// continue and we can read the contents of the src attribute during
// OnDataAvailable. For all others, we return ns_binding_aborted because we
// don't care to actually read the data at this point. The external content
// for these other elements will be retrieved by the services that actually
// display the popups.
if (IsEphemeral() && mStopType == eStopType_None)
return NS_OK;
AddRemoveExternalResource(PR_FALSE);
mChannel = nsnull;
@ -1107,8 +1188,28 @@ nsXFormsMessageElement::OnDataAvailable(nsIRequest *aRequest,
PRUint32 aOffset,
PRUint32 aCount)
{
NS_NOTREACHED("nsXFormsMessageElement::OnDataAvailable");
return NS_BINDING_ABORTED;
if (!mElement) {
AddRemoveExternalResource(PR_FALSE);
mChannel = nsnull;
return NS_BINDING_ABORTED;
}
if (!IsEphemeral())
return NS_BINDING_ABORTED;
nsresult rv;
PRUint32 size, bytesRead;
char buffer[256];
while (aCount) {
size = PR_MIN(aCount, sizeof(buffer));
rv = aInputStream->Read(buffer, size, &bytesRead);
NS_ENSURE_SUCCESS(rv, rv);
mSrcAttrText.Append(buffer, bytesRead);
aCount -= bytesRead;
}
return NS_OK;
}
NS_IMETHODIMP
@ -1116,6 +1217,15 @@ nsXFormsMessageElement::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode)
{
if (IsEphemeral()) {
nsCOMPtr<nsIXFormsUIWidget> widget = do_QueryInterface(mElement);
if (widget)
widget->Refresh();
AddRemoveExternalResource(PR_FALSE);
mChannel = nsnull;
}
return NS_OK;
}
@ -1170,6 +1280,16 @@ nsXFormsMessageElement::AddRemoveExternalResource(PRBool aAdd)
}
}
PRBool nsXFormsMessageElement::IsEphemeral()
{
if (mType == eType_Hint)
return PR_TRUE;
nsAutoString level;
mElement->GetAttribute(NS_LITERAL_STRING("level"), level);
return level.Equals(NS_LITERAL_STRING("ephemeral"));
}
NS_HIDDEN_(nsresult)
NS_NewXFormsMessageElement(nsIXTFElement **aResult)
{

Просмотреть файл

@ -105,7 +105,7 @@ html|*:root select1[appearance='full'] choices {
display: none;
}
message, alert {
message, alert, help {
display: none;
}

Просмотреть файл

@ -375,7 +375,8 @@
<method name="refresh">
<body>
if (this.accessors.hasBoundNode()) {
if (this.accessors.hasBoundNode() ||
this.hasAttribute('src')) {
this.bindingData.textContent = this.stringValue;
this.inlineData.style.display = "none";
this.bindingData.style.display = "inherit";