Bug 293834. Save As, Complete should save form input state. r=bzbarsky, sr=sicking

This commit is contained in:
Ben Karel [eschew] 2008-07-28 22:59:25 -07:00
Родитель 198f21c6c3
Коммит 81953ae791
4 изменённых файлов: 110 добавлений и 24 удалений

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

@ -44,7 +44,7 @@ interface nsISelection;
interface nsIDOMNode;
interface nsIOutputStream;
[scriptable, uuid(e770c650-b3d3-11da-a94d-0800200c9a66)]
[scriptable, uuid(3c556e41-0f73-4e1d-b724-1474884fe2e3)]
interface nsIDocumentEncoderNodeFixup : nsISupports
{
/**
@ -53,9 +53,12 @@ interface nsIDocumentEncoderNodeFixup : nsISupports
* may return a new node with fixed up attributes or null. If null is
* returned the node should be used as-is.
* @param aNode Node to fixup.
* @param [OUT] aSerializeCloneKids True if the document encoder should
* apply recursive serialization to the children of the fixed up node
* instead of the children of the original node.
* @return The resulting fixed up node.
*/
nsIDOMNode fixupNode(in nsIDOMNode aNode);
nsIDOMNode fixupNode(in nsIDOMNode aNode, out boolean aSerializeCloneKids);
};
[scriptable, uuid(f85c5a20-258d-11db-a98b-0800200c9a66)]

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

@ -97,7 +97,8 @@ public:
protected:
void Initialize();
nsresult SerializeNodeStart(nsIDOMNode* aNode, PRInt32 aStartOffset,
PRInt32 aEndOffset, nsAString& aStr);
PRInt32 aEndOffset, nsAString& aStr,
nsIDOMNode* aOriginalNode = nsnull);
nsresult SerializeToStringRecursive(nsIDOMNode* aNode,
nsAString& aStr,
PRBool aDontSerializeRoot);
@ -259,28 +260,34 @@ nsDocumentEncoder::IncludeInContext(nsIDOMNode *aNode)
}
nsresult
nsDocumentEncoder::SerializeNodeStart(nsIDOMNode* aNode, PRInt32 aStartOffset,
nsDocumentEncoder::SerializeNodeStart(nsIDOMNode* aNode,
PRInt32 aStartOffset,
PRInt32 aEndOffset,
nsAString& aStr)
nsAString& aStr,
nsIDOMNode* aOriginalNode)
{
PRUint16 type;
nsCOMPtr<nsIDOMNode> node;
if (mNodeFixup)
{
mNodeFixup->FixupNode(aNode, getter_AddRefs(node));
// Caller didn't do fixup, so we'll do it ourselves
if (!aOriginalNode && mNodeFixup) {
aOriginalNode = aNode;
PRBool dummy;
mNodeFixup->FixupNode(aNode, &dummy, getter_AddRefs(node));
}
// Either there was no fixed-up node,
// or the caller did fixup themselves and aNode is already fixed
if (!node)
{
node = do_QueryInterface(aNode);
}
node = aNode;
node->GetNodeType(&type);
switch (type) {
case nsIDOMNode::ELEMENT_NODE:
{
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node);
nsCOMPtr<nsIDOMElement> originalElement = do_QueryInterface(aNode);
nsCOMPtr<nsIDOMElement> originalElement = do_QueryInterface(aOriginalNode);
mSerializer->AppendElementStart(element, originalElement, aStr);
break;
}
@ -345,18 +352,32 @@ nsDocumentEncoder::SerializeToStringRecursive(nsIDOMNode* aNode,
PRBool aDontSerializeRoot)
{
nsresult rv = NS_OK;
PRBool serializeClonedChildren;
nsCOMPtr<nsIDOMNode> maybeFixedNode;
if (mNodeFixup)
mNodeFixup->FixupNode(aNode, &serializeClonedChildren, getter_AddRefs(maybeFixedNode));
if (!maybeFixedNode)
maybeFixedNode = aNode;
if (!aDontSerializeRoot) {
rv = SerializeNodeStart(aNode, 0, -1, aStr);
rv = SerializeNodeStart(maybeFixedNode, 0, -1, aStr, aNode);
NS_ENSURE_SUCCESS(rv, rv);
}
PRBool hasChildren = PR_FALSE;
nsIDOMNode *node;
if (serializeClonedChildren)
node = maybeFixedNode;
else
node = aNode;
aNode->HasChildNodes(&hasChildren);
PRBool hasChildren = PR_FALSE;
node->HasChildNodes(&hasChildren);
if (hasChildren) {
nsCOMPtr<nsIDOMNodeList> childNodes;
rv = aNode->GetChildNodes(getter_AddRefs(childNodes));
rv = node->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_TRUE(childNodes, NS_SUCCEEDED(rv) ? NS_ERROR_FAILURE : rv);
PRInt32 index, count;
@ -374,7 +395,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsIDOMNode* aNode,
}
if (!aDontSerializeRoot) {
rv = SerializeNodeEnd(aNode, aStr);
rv = SerializeNodeEnd(node, aStr);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -86,6 +86,8 @@
#include "nsIPrompt.h"
#include "nsISHEntry.h"
#include "nsIWebPageDescriptor.h"
#include "nsIFormControl.h"
#include "nsIDOM3Node.h"
#include "nsIDOMNodeFilter.h"
#include "nsIDOMProcessingInstruction.h"
@ -105,7 +107,10 @@
#include "nsIDOMHTMLEmbedElement.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsIDOMHTMLAppletElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMText.h"
#ifdef MOZ_SVG
#include "nsIDOMSVGImageElement.h"
#include "nsIDOMSVGScriptElement.h"
@ -2971,11 +2976,12 @@ nsWebBrowserPersist::GetNodeToFixup(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut)
}
nsresult
nsWebBrowserPersist::CloneNodeWithFixedUpURIAttributes(
nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut)
nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
nsIDOMNode *aNodeIn, PRBool *aSerializeCloneKids, nsIDOMNode **aNodeOut)
{
nsresult rv;
*aNodeOut = nsnull;
*aSerializeCloneKids = PR_FALSE;
// Fixup xml-stylesheet processing instructions
nsCOMPtr<nsIDOMProcessingInstruction> nodeAsPI = do_QueryInterface(aNodeIn);
@ -3266,6 +3272,62 @@ nsWebBrowserPersist::CloneNodeWithFixedUpURIAttributes(
imgCon->SetLoadingEnabled(PR_FALSE);
FixupNodeAttribute(*aNodeOut, "src");
nsAutoString valueStr;
NS_NAMED_LITERAL_STRING(valueAttr, "value");
// Update element node attributes with user-entered form state
nsCOMPtr<nsIDOMHTMLInputElement> outElt = do_QueryInterface(*aNodeOut);
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(*aNodeOut);
switch (formControl->GetType()) {
case NS_FORM_INPUT_TEXT:
nodeAsInput->GetValue(valueStr);
// Avoid superfluous value="" serialization
if (valueStr.IsEmpty())
outElt->RemoveAttribute(valueAttr);
else
outElt->SetAttribute(valueAttr, valueStr);
break;
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
PRBool checked;
nodeAsInput->GetChecked(&checked);
outElt->SetDefaultChecked(checked);
break;
default:
break;
}
}
return rv;
}
nsCOMPtr<nsIDOMHTMLTextAreaElement> nodeAsTextArea = do_QueryInterface(aNodeIn);
if (nodeAsTextArea)
{
rv = GetNodeToFixup(aNodeIn, aNodeOut);
if (NS_SUCCEEDED(rv) && *aNodeOut)
{
// Tell the document encoder to serialize the text child we create below
*aSerializeCloneKids = PR_TRUE;
nsAutoString valueStr;
nodeAsTextArea->GetValue(valueStr);
nsCOMPtr<nsIDOM3Node> out = do_QueryInterface(*aNodeOut);
out->SetTextContent(valueStr);
}
return rv;
}
nsCOMPtr<nsIDOMHTMLOptionElement> nodeAsOption = do_QueryInterface(aNodeIn);
if (nodeAsOption)
{
rv = GetNodeToFixup(aNodeIn, aNodeOut);
if (NS_SUCCEEDED(rv) && *aNodeOut)
{
nsCOMPtr<nsIDOMHTMLOptionElement> outElt = do_QueryInterface(*aNodeOut);
PRBool selected;
nodeAsOption->GetSelected(&selected);
outElt->SetDefaultSelected(selected);
}
return rv;
}
@ -4097,7 +4159,7 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP nsEncoderNodeFixup::FixupNode(
nsIDOMNode *aNode, nsIDOMNode **aOutNode)
nsIDOMNode *aNode, PRBool *aSerializeCloneKids, nsIDOMNode **aOutNode)
{
NS_ENSURE_ARG_POINTER(aNode);
NS_ENSURE_ARG_POINTER(aOutNode);
@ -4111,7 +4173,7 @@ NS_IMETHODIMP nsEncoderNodeFixup::FixupNode(
if (type == nsIDOMNode::ELEMENT_NODE ||
type == nsIDOMNode::PROCESSING_INSTRUCTION_NODE)
{
return mWebBrowserPersist->CloneNodeWithFixedUpURIAttributes(aNode, aOutNode);
return mWebBrowserPersist->CloneNodeWithFixedUpAttributes(aNode, aSerializeCloneKids, aOutNode);
}
return NS_OK;

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

@ -90,8 +90,8 @@ public:
// Protected members
protected:
virtual ~nsWebBrowserPersist();
nsresult CloneNodeWithFixedUpURIAttributes(
nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut);
nsresult CloneNodeWithFixedUpAttributes(
nsIDOMNode *aNodeIn, PRBool *aSerializeCloneKids, nsIDOMNode **aNodeOut);
nsresult SaveURIInternal(
nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
nsIInputStream *aPostData, const char *aExtraHeaders, nsIURI *aFile,
@ -250,7 +250,7 @@ public:
nsEncoderNodeFixup();
NS_DECL_ISUPPORTS
NS_IMETHOD FixupNode(nsIDOMNode *aNode, nsIDOMNode **aOutNode);
NS_IMETHOD FixupNode(nsIDOMNode *aNode, PRBool *aSerializeCloneKids, nsIDOMNode **aOutNode);
nsWebBrowserPersist *mWebBrowserPersist;