Bug 583863: Refactor <input> implementation to deal with files that aren't on the disk. r=sicking a=blocking-fennec

--HG--
extra : rebase_source : 2b3605042aea4e4c8273cdad5ec7f05af15959cc
This commit is contained in:
Kyle Huey 2010-09-05 14:00:05 -04:00
Родитель 176e3c8824
Коммит 55beafe241
27 изменённых файлов: 1023 добавлений и 976 удалений

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

@ -45,6 +45,11 @@ function test() {
return false;
}
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
filePath = file.path;
let fieldList = {
"//input[@name='input']": Date.now().toString(),
"//input[@name='spaced 1']": Math.random().toString(),
@ -59,7 +64,7 @@ function test() {
"//textarea[1]": "",
"//textarea[2]": "Some text... " + Math.random(),
"//textarea[3]": "Some more text\n" + new Date(),
"//input[@type='file']": "/dev/null"
"//input[@type='file']": filePath
};
function getElementByXPath(aTab, aQuery) {

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

@ -36,6 +36,19 @@
function test() {
/** Test for Bug 346337 **/
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
file.append("346337_test1.file");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
filePath1 = file.path;
file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
file.append("346337_test2.file");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
filePath2 = file.path;
let fieldList = {
"//input[@name='input']": Date.now().toString(),
@ -51,8 +64,8 @@ function test() {
"//textarea[1]": "",
"//textarea[2]": "Some text... " + Math.random(),
"//textarea[3]": "Some more text\n" + new Date(),
"//input[@type='file'][1]": ["/dev/null"],
"//input[@type='file'][2]": ["/dev/null", "/dev/stdin"]
"//input[@type='file'][1]": [filePath1],
"//input[@type='file'][2]": [filePath1, filePath2]
};
function getElementByXPath(aTab, aQuery) {

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

@ -38,10 +38,16 @@ function test() {
/** Test for Bug 466937 **/
waitForExplicitFinish();
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
file.append("466937_test.file");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
let testPath = file.path;
let testURL = "http://mochi.test:8888/browser/" +
"browser/components/sessionstore/test/browser/browser_466937_sample.html";
let testPath = "/home/user/regular.file";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {

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

@ -99,7 +99,6 @@ XPIDLSRCS = \
nsIDocumentEncoder.idl \
nsIDOMFile.idl \
nsIDOMFileReader.idl \
nsIDOMFileInternal.idl \
nsIDOMFileList.idl \
nsIDOMFileException.idl \
nsIDOMFileError.idl \

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

@ -41,34 +41,42 @@
#include "nsICharsetDetectionObserver.h"
#include "nsIDOMFile.h"
#include "nsIDOMFileInternal.h"
#include "nsIDOMFileList.h"
#include "nsIDOMFileError.h"
#include "nsIInputStream.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "mozilla/AutoRestore.h"
#include "nsString.h"
#include "nsIWeakReference.h"
#include "nsIWeakReferenceUtils.h"
#include "nsIDocument.h"
#include "nsIXMLHttpRequest.h"
class nsIDOMDocument;
class nsIFile;
class nsIInputStream;
class nsDOMFile : public nsIDOMFile,
public nsIDOMFileInternal,
public nsIXHRSendable,
public nsICharsetDetectionObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMFILE
NS_DECL_NSIDOMFILEINTERNAL
NS_DECL_NSIXHRSENDABLE
nsDOMFile(nsIFile *aFile, nsIDocument* aRelatedDoc, nsAString& aContentType)
: mFile(aFile),
mRelatedDoc(do_GetWeakReference(aRelatedDoc)),
mContentType(aContentType)
{}
nsDOMFile(nsIFile *aFile, nsIDocument* aRelatedDoc)
: mFile(aFile),
mRelatedDoc(do_GetWeakReference(aRelatedDoc))
{}
~nsDOMFile() {}
// from nsICharsetDetectionObserver
@ -87,6 +95,30 @@ private:
nsAString &aResult);
};
class nsDOMMemoryFile : public nsDOMFile
{
public:
nsDOMMemoryFile(void *aMemoryBuffer,
PRUint64 aLength,
nsAString& aContentType,
nsIDocument *aRelatedDoc)
: nsDOMFile(nsnull, aRelatedDoc, aContentType),
mInternalData(aMemoryBuffer), mLength(aLength)
{ }
~nsDOMMemoryFile()
{ free(mInternalData); }
NS_IMETHOD GetName(nsAString&);
NS_IMETHOD GetSize(PRUint64*);
NS_IMETHOD GetInternalStream(nsIInputStream**);
NS_IMETHOD GetMozFullPathInternal(nsAString&);
protected:
void* mInternalData;
PRUint64 mLength;
};
class nsDOMFileList : public nsIDOMFileList
{
public:
@ -136,4 +168,13 @@ private:
PRUint16 mCode;
};
class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
public:
nsDOMFileInternalUrlHolder(nsIDOMFile* aFile MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM);
~nsDOMFileInternalUrlHolder();
nsAutoString mUrl;
private:
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
};
#endif

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

@ -38,8 +38,10 @@
#include "domstubs.idl"
interface nsIDOMFileError;
interface nsIInputStream;
interface nsIURI;
[scriptable, uuid(b10293e1-d531-4bdd-9b2b-4d8c1c9bc633)]
[scriptable, uuid(e72e2d6e-e267-4ea1-a798-6703d3a2c362)]
interface nsIDOMFile : nsISupports
{
//fileName and fileSize are now deprecated attributes
@ -56,4 +58,11 @@ interface nsIDOMFile : nsISupports
DOMString getAsText(in DOMString encoding); // raises(FileException) on retrieval
DOMString getAsDataURL(); // raises(FileException) on retrieval
DOMString getAsBinary(); // raises(FileException) on retrieval
[noscript] readonly attribute nsIInputStream internalStream;
// The caller is responsible for releasing the internalUrl from the
// moz-filedata: protocol handler
[noscript] readonly attribute DOMString internalUrl;
// This performs no security checks!
[noscript] readonly attribute DOMString mozFullPathInternal;
};

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

@ -1,46 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "domstubs.idl"
interface nsIFile;
[scriptable, uuid(047CA6C4-52B3-46F1-8976-E198B724F72F)]
interface nsIDOMFileInternal : nsISupports
{
attribute nsIFile internalFile;
};

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

@ -15,7 +15,7 @@
* The Original Code is mozila.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
@ -61,6 +61,7 @@
#include "nsNetUtil.h"
#include "nsIUUIDGenerator.h"
#include "nsFileDataProtocolHandler.h"
#include "nsStringStream.h"
#include "plbase64.h"
#include "prmem.h"
@ -72,7 +73,7 @@ DOMCI_DATA(File, nsDOMFile)
NS_INTERFACE_MAP_BEGIN(nsDOMFile)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
NS_INTERFACE_MAP_ENTRY(nsIDOMFile)
NS_INTERFACE_MAP_ENTRY(nsIDOMFileInternal)
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(File)
NS_INTERFACE_MAP_END
@ -116,12 +117,18 @@ NS_IMETHODIMP
nsDOMFile::GetMozFullPath(nsAString &aFileName)
{
if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
return mFile->GetPath(aFileName);
return GetMozFullPathInternal(aFileName);
}
aFileName.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::GetMozFullPathInternal(nsAString &aFilename)
{
return mFile->GetPath(aFilename);
}
NS_IMETHODIMP
nsDOMFile::GetSize(PRUint64 *aFileSize)
{
@ -162,36 +169,56 @@ nsDOMFile::GetType(nsAString &aType)
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::GetInternalStream(nsIInputStream **aStream)
{
return NS_NewLocalFileInputStream(aStream, mFile, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND);
}
NS_IMETHODIMP
nsDOMFile::GetUrl(nsAString& aURL)
{
if (mURL.IsEmpty()) {
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsID id;
rv = uuidgen->GenerateUUIDInPlace(&id);
NS_ENSURE_SUCCESS(rv, rv);
char chars[NSID_LENGTH];
id.ToProvidedString(chars);
nsCString url = NS_LITERAL_CSTRING(FILEDATA_SCHEME ":") +
Substring(chars + 1, chars + NSID_LENGTH - 2);
GetInternalUrl(mURL);
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mRelatedDoc);
if (doc) {
doc->RegisterFileDataUri(url);
nsFileDataProtocolHandler::AddFileDataEntry(url, mFile,
doc->NodePrincipal());
}
CopyASCIItoUTF16(url, mURL);
NS_LossyConvertUTF16toASCII shortURL(mURL);
doc->RegisterFileDataUri(shortURL);
}
aURL = mURL;
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::GetInternalUrl(nsAString& aURL)
{
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsID id;
rv = uuidgen->GenerateUUIDInPlace(&id);
NS_ENSURE_SUCCESS(rv, rv);
char chars[NSID_LENGTH];
id.ToProvidedString(chars);
nsCString url = NS_LITERAL_CSTRING(FILEDATA_SCHEME ":") +
Substring(chars + 1, chars + NSID_LENGTH - 2);
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mRelatedDoc);
if (doc) {
nsFileDataProtocolHandler::AddFileDataEntry(url,
this,
doc->NodePrincipal());
}
CopyASCIItoUTF16(url, aURL);
return NS_OK;
}
@ -202,9 +229,7 @@ nsDOMFile::GetAsText(const nsAString &aCharset, nsAString &aResult)
aResult.Truncate();
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewLocalFileInputStream
(getter_AddRefs(stream),
mFile, -1, -1, 0);
nsresult rv = GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, DOMFileResult(rv));
nsCAutoString charsetGuess;
@ -231,43 +256,33 @@ nsDOMFile::GetAsText(const nsAString &aCharset, nsAString &aResult)
return ConvertStream(stream, charset.get(), aResult);
}
NS_IMETHODIMP
nsDOMFile::GetInternalFile(nsIFile **aFile)
{
NS_IF_ADDREF(*aFile = mFile);
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::SetInternalFile(nsIFile *aFile)
{
mFile = aFile;
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::GetAsDataURL(nsAString &aResult)
{
aResult.AssignLiteral("data:");
nsresult rv;
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!mContentType.Length()) {
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString contentType;
rv = mimeService->GetTypeFromFile(mFile, contentType);
if (NS_SUCCEEDED(rv)) {
AppendUTF8toUTF16(contentType, aResult);
nsCAutoString contentType;
rv = mimeService->GetTypeFromFile(mFile, contentType);
if (NS_SUCCEEDED(rv)) {
CopyUTF8toUTF16(contentType, mContentType);
}
}
if (mContentType.Length()) {
aResult.Append(mContentType);
} else {
aResult.AppendLiteral("application/octet-stream");
}
aResult.AppendLiteral(";base64,");
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream),
mFile, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF);
rv = GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, DOMFileResult(rv));
char readBuf[4096];
@ -307,10 +322,7 @@ nsDOMFile::GetAsBinary(nsAString &aResult)
aResult.Truncate();
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewLocalFileInputStream
(getter_AddRefs(stream),
mFile, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF);
nsresult rv = GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, DOMFileResult(rv));
PRUint32 numRead;
@ -423,6 +435,29 @@ nsDOMFile::GuessCharset(nsIInputStream *aStream,
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::GetSendInfo(nsIInputStream** aBody,
nsACString& aContentType,
nsACString& aCharset)
{
nsresult rv;
nsCOMPtr<nsIInputStream> stream;
rv = this->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
nsString contentType;
rv = this->GetType(contentType);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(contentType, aContentType);
aCharset.Truncate();
stream.forget(aBody);
return NS_OK;
}
NS_IMETHODIMP
nsDOMFile::Notify(const char* aCharset, nsDetectionConfident aConf)
{
@ -463,6 +498,39 @@ nsDOMFile::ConvertStream(nsIInputStream *aStream,
return rv;
}
// nsDOMMemoryFile Implementation
NS_IMETHODIMP
nsDOMMemoryFile::GetName(nsAString &aFileName)
{
aFileName.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDOMMemoryFile::GetSize(PRUint64 *aFileSize)
{
*aFileSize = mLength;
return NS_OK;
}
NS_IMETHODIMP
nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
{
if (mLength > PR_INT32_MAX)
return NS_ERROR_FAILURE;
PRInt32 l = mLength;
return NS_NewByteInputStream(aStream, (const char*)mInternalData, l);
}
NS_IMETHODIMP
nsDOMMemoryFile::GetMozFullPathInternal(nsAString &aFilename)
{
aFilename.Truncate();
return NS_OK;
}
// nsDOMFileList implementation
DOMCI_DATA(FileList, nsDOMFileList)
@ -511,3 +579,17 @@ nsDOMFileError::GetCode(PRUint16* aCode)
*aCode = mCode;
return NS_OK;
}
nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMFile* aFile
MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
aFile->GetInternalUrl(mUrl);
}
nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
if (!mUrl.IsEmpty()) {
nsCAutoString narrowUrl;
CopyUTF16toUTF8(mUrl, narrowUrl);
nsFileDataProtocolHandler::RemoveFileDataEntry(narrowUrl);
}
}

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

@ -15,7 +15,7 @@
* The Original Code is mozila.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
@ -71,13 +71,13 @@
#include "nsJSEnvironment.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMClassInfo.h"
#include "nsIDOMFileInternal.h"
#include "nsCExternalHandlerService.h"
#include "nsIStreamConverterService.h"
#include "nsEventDispatcher.h"
#include "nsCycleCollectionParticipant.h"
#include "nsLayoutStatics.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsFileDataProtocolHandler.h"
#define LOAD_STR "load"
#define ERROR_STR "error"
@ -485,6 +485,7 @@ nsDOMFileReader::ReadFileContent(nsIDOMFile* aFile,
const nsAString &aCharset,
eDataFormat aDataFormat)
{
nsresult rv;
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
//Implicit abort to clear any other activity going on
@ -496,26 +497,28 @@ nsDOMFileReader::ReadFileContent(nsIDOMFile* aFile,
mReadyState = nsIDOMFileReader::EMPTY;
FreeFileData();
mFile = aFile;
mDataFormat = aDataFormat;
mCharset = aCharset;
//Obtain the nsDOMFile's underlying nsIFile
nsresult rv;
nsCOMPtr<nsIDOMFileInternal> domFile(do_QueryInterface(aFile));
rv = domFile->GetInternalFile(getter_AddRefs(mFile));
NS_ENSURE_SUCCESS(rv, rv);
//Establish a channel with our file
nsCOMPtr<nsIURI> uri;
rv = NS_NewFileURI(getter_AddRefs(uri), mFile);
NS_ENSURE_SUCCESS(rv, rv);
{
// Hold the internal URL alive only as long as necessary
// After the channel is created it will own whatever is backing
// the DOMFile.
nsDOMFileInternalUrlHolder urlHolder(mFile);
rv = NS_NewChannel(getter_AddRefs(mChannel), uri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), urlHolder.mUrl);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewChannel(getter_AddRefs(mChannel), uri);
NS_ENSURE_SUCCESS(rv, rv);
}
//Obtain the total size of the file before reading
mReadTotal = -1;
mFile->GetFileSize(&mReadTotal);
mFile->GetSize(&mReadTotal);
rv = mChannel->AsyncOpen(this, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
@ -604,7 +607,7 @@ nsDOMFileReader::GetAsText(const nsAString &aCharset,
}
nsresult
nsDOMFileReader::GetAsDataURL(nsIFile *aFile,
nsDOMFileReader::GetAsDataURL(nsIDOMFile *aFile,
const char *aFileData,
PRUint32 aDataLen,
nsAString& aResult)
@ -612,14 +615,10 @@ nsDOMFileReader::GetAsDataURL(nsIFile *aFile,
aResult.AssignLiteral("data:");
nsresult rv;
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString contentType;
rv = mimeService->GetTypeFromFile(aFile, contentType);
if (NS_SUCCEEDED(rv)) {
AppendUTF8toUTF16(contentType, aResult);
nsString contentType;
rv = aFile->GetType(contentType);
if (NS_SUCCEEDED(rv) && !contentType.IsEmpty()) {
aResult.Append(contentType);
} else {
aResult.AppendLiteral("application/octet-stream");
}

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

@ -120,7 +120,7 @@ protected:
nsresult ReadFileContent(nsIDOMFile *aFile, const nsAString &aCharset, eDataFormat aDataFormat);
nsresult GetAsText(const nsAString &aCharset,
const char *aFileData, PRUint32 aDataLen, nsAString &aResult);
nsresult GetAsDataURL(nsIFile *aFile, const char *aFileData, PRUint32 aDataLen, nsAString &aResult);
nsresult GetAsDataURL(nsIDOMFile *aFile, const char *aFileData, PRUint32 aDataLen, nsAString &aResult);
nsresult GuessCharset(const char *aFileData, PRUint32 aDataLen, nsACString &aCharset);
nsresult ConvertStream(const char *aFileData, PRUint32 aDataLen, const char *aCharset, nsAString &aResult);
void DispatchError(nsresult rv);
@ -133,7 +133,7 @@ protected:
}
char *mFileData;
nsCOMPtr<nsIFile> mFile;
nsCOMPtr<nsIDOMFile> mFile;
nsString mCharset;
PRUint32 mDataLen;
@ -150,7 +150,7 @@ protected:
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIChannel> mChannel;
PRInt64 mReadTotal;
PRUint64 mReadTotal;
PRUint64 mReadTransferred;
nsRefPtr<nsDOMEventListenerWrapper> mOnLoadEndListener;

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

@ -42,7 +42,7 @@
#include "nsNetUtil.h"
#include "nsIURIWithPrincipal.h"
#include "nsIPrincipal.h"
#include "nsIFileChannel.h"
#include "nsIDOMFile.h"
#include "nsISerializable.h"
#include "nsIClassInfo.h"
#include "nsIObjectInputStream.h"
@ -55,14 +55,15 @@ static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
// Hash table
struct FileDataInfo
{
nsCOMPtr<nsIURI> mFileUri;
nsCOMPtr<nsIDOMFile> mFile;
nsCOMPtr<nsIPrincipal> mPrincipal;
};
static nsClassHashtable<nsCStringHashKey, FileDataInfo>* gFileDataTable;
void
nsFileDataProtocolHandler::AddFileDataEntry(nsACString& aUri, nsIFile* aFile,
nsFileDataProtocolHandler::AddFileDataEntry(nsACString& aUri,
nsIDOMFile* aFile,
nsIPrincipal* aPrincipal)
{
if (!gFileDataTable) {
@ -72,7 +73,7 @@ nsFileDataProtocolHandler::AddFileDataEntry(nsACString& aUri, nsIFile* aFile,
FileDataInfo* info = new FileDataInfo;
NS_NewFileURI(getter_AddRefs(info->mFileUri), aFile);
info->mFile = aFile;
info->mPrincipal = aPrincipal;
gFileDataTable->Put(aUri, info);
@ -413,8 +414,14 @@ nsFileDataProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
}
#endif
nsCOMPtr<nsIInputStream> stream;
nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel), info->mFileUri);
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
uri,
stream);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);

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

@ -41,7 +41,7 @@
#define FILEDATA_SCHEME "moz-filedata"
class nsIFile;
class nsIDOMFile;
class nsIPrincipal;
class nsFileDataProtocolHandler : public nsIProtocolHandler
@ -57,7 +57,8 @@ public:
virtual ~nsFileDataProtocolHandler() {}
// Methods for managing uri->file mapping
static void AddFileDataEntry(nsACString& aUri, nsIFile* aFile,
static void AddFileDataEntry(nsACString& aUri,
nsIDOMFile* aFile,
nsIPrincipal* aPrincipal);
static void RemoveFileDataEntry(nsACString& aUri);

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

@ -36,9 +36,8 @@
#include "nsFormData.h"
#include "nsIVariant.h"
#include "nsIDOMFileInternal.h"
#include "nsIInputStream.h"
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsContentUtils.h"
nsFormData::nsFormData()
@ -84,7 +83,7 @@ nsFormData::AddNameValuePair(const nsAString& aName,
nsresult
nsFormData::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
nsIDOMFile* aFile)
{
FormDataTuple* data = mFormData.AppendElement();
data->name = aName;
@ -113,13 +112,9 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
nsMemory::Free(iid);
nsCOMPtr<nsIDOMFileInternal> domFile = do_QueryInterface(supports);
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(supports);
if (domFile) {
nsCOMPtr<nsIFile> file;
rv = domFile->GetInternalFile(getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
return AddNameFilePair(aName, file);
return AddNameFilePair(aName, domFile);
}
}

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

@ -42,6 +42,8 @@
#include "nsFormSubmission.h"
#include "nsTArray.h"
class nsIDOMFile;
class nsFormData : public nsIDOMFormData,
public nsIXHRSendable,
public nsFormSubmission
@ -59,16 +61,14 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
nsIDOMFile* aFile);
private:
struct FormDataTuple
{
nsString name;
nsString stringValue;
nsCOMPtr<nsIFile> fileValue;
nsCOMPtr<nsIDOMFile> fileValue;
PRBool valueIsFile;
};

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

@ -63,7 +63,6 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMClassInfo.h"
#include "nsIDOMElement.h"
#include "nsIDOMFileInternal.h"
#include "nsIDOMWindow.h"
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
@ -2328,29 +2327,6 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
return NS_OK;
}
// nsIDOMFile?
nsCOMPtr<nsIDOMFileInternal> file = do_QueryInterface(supports);
if (file) {
aCharset.Truncate();
nsCOMPtr<nsIFile> internalFile;
rv = file->GetInternalFile(getter_AddRefs(internalFile));
NS_ENSURE_SUCCESS(rv, rv);
// Get the mimetype
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mimeService->GetTypeFromFile(internalFile, aContentType);
if (NS_FAILED(rv)) {
aContentType.Truncate();
}
// Feed local file input stream into our upload channel
return NS_NewLocalFileInputStream(aResult, internalFile);
}
// nsIXHRSendable?
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
if (sendable) {

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

@ -22,6 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=345339
/** Test for Bug 345339 **/
SimpleTest.waitForExplicitFinish();
var filePath;
function afterLoad() {
var iframeDoc = $("testframe").contentDocument;
@ -31,8 +33,15 @@ function afterLoad() {
iframeDoc.getElementById("password").value = "123456";
iframeDoc.getElementById("hidden").value = "gecko";
netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
iframeDoc.getElementById("file").value = "dummyfile.txt";
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
file.append("345339_test.file");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
filePath = file.path;
iframeDoc.getElementById("file").value = filePath;
/* Reload the page */
$("testframe").setAttribute("onload", "afterReload()");
@ -55,7 +64,7 @@ function afterReload() {
is(iframeDoc.getElementById("hidden").value, "gecko",
"hidden field value preserved");
netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
is(iframeDoc.getElementById("file").value, "dummyfile.txt",
is(iframeDoc.getElementById("file").value, filePath,
"file field value preserved");
SimpleTest.finish();

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

@ -60,7 +60,6 @@ EXPORTS = \
nsIRadioVisitor.h \
nsIRadioGroupContainer.h \
nsITextControlElement.h \
nsIFileControlElement.h \
nsFormSubmission.h \
nsIFrameSetElement.h \
nsHTMLAudioElement.h \

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

@ -52,6 +52,7 @@ class nsIDocShell;
class nsIRequest;
class nsISaveAsCharset;
class nsIMultiplexInputStream;
class nsIDOMFile;
/**
* Class for form submissions; encompasses the function to call to submit as
@ -81,7 +82,7 @@ public:
* @param aFile the file to submit
*/
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile) = 0;
nsIDOMFile* aFile) = 0;
/**
* Reports whether the instance supports AddIsindex().
@ -187,7 +188,7 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
nsIDOMFile* aFile);
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream);

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

@ -1,86 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIFileControlElement_h___
#define nsIFileControlElement_h___
#include "nsISupports.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsCOMArray.h"
class nsIFile;
// IID for the nsIFileControl interface
#define NS_IFILECONTROLELEMENT_IID \
{ 0x1f6a32fd, 0x9cda, 0x43e9, \
{ 0x90, 0xef, 0x18, 0x0a, 0xd5, 0xe6, 0xcd, 0xa9 } }
/**
* This interface is used for the file control frame to store its value away
* into the content.
*/
class nsIFileControlElement : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFILECONTROLELEMENT_IID)
/**
* Gets a readable string representing the list of files currently
* selected by this control. This value might not be a valid file name
* and should not be used for anything but displaying the filename to the
* user.
*/
virtual void GetDisplayFileName(nsAString& aFileName) = 0;
/**
* Sets the list of filenames currently selected by this control.
*/
virtual void SetFileNames(const nsTArray<nsString>& aFileNames) = 0;
/**
* Gets a list of nsIFile objects for the files currently selected by
* this control.
*/
virtual void GetFileArray(nsCOMArray<nsIFile>& aFiles) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFileControlElement,
NS_IFILECONTROLELEMENT_IID)
#endif // nsIFileControlElement_h___

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

@ -49,9 +49,8 @@
#include "nsDOMError.h"
#include "nsGenericHTMLElement.h"
#include "nsISaveAsCharset.h"
// JBK added for submit move from content frame
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsDirectoryServiceDefs.h"
#include "nsStringStream.h"
#include "nsIURI.h"
@ -110,7 +109,7 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
nsIDOMFile* aFile);
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream);
@ -196,7 +195,7 @@ nsFSURLEncoded::AddIsindex(const nsAString& aValue)
nsresult
nsFSURLEncoded::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
nsIDOMFile* aFile)
{
if (!mWarnedFileControl) {
SendJSWarning(mDocument, "ForgotFileEnctypeWarning", nsnull, 0);
@ -205,7 +204,7 @@ nsFSURLEncoded::AddNameFilePair(const nsAString& aName,
nsAutoString filename;
if (aFile) {
aFile->GetLeafName(filename);
aFile->GetName(filename);
}
return AddNameValuePair(aName, filename);
@ -469,7 +468,7 @@ nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
nsresult
nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
nsIDOMFile* aFile)
{
// Encode the control name
nsCAutoString nameStr;
@ -477,12 +476,13 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
NS_ENSURE_SUCCESS(rv, rv);
nsCString filenameStr;
nsCAutoString contentType;
nsAutoString contentType;
nsCOMPtr<nsIInputStream> fileStream;
if (aFile) {
// Get and encode the filename
nsAutoString filename;
aFile->GetLeafName(filename);
rv = aFile->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString encodedFileName;
rv = EncodeVal(filename, encodedFileName);
NS_ENSURE_SUCCESS(rv, rv);
@ -493,20 +493,14 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
nsLinebreakConverter::eLinebreakNet));
// Get content type
nsCOMPtr<nsIMIMEService> MIMEService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = MIMEService->GetTypeFromFile(aFile, contentType);
if (NS_FAILED(rv)) {
rv = aFile->GetType(contentType);
if (NS_FAILED(rv) || contentType.IsEmpty()) {
contentType.AssignLiteral("application/octet-stream");
}
// Get input stream
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
aFile, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND);
rv = aFile->GetInternalStream(getter_AddRefs(fileStream));
NS_ENSURE_SUCCESS(rv, rv);
if (fileStream) {
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
@ -534,8 +528,9 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"; filename=\"")
+ filenameStr + NS_LITERAL_CSTRING("\"" CRLF)
+ NS_LITERAL_CSTRING("Content-Type: ") + contentType
+ NS_LITERAL_CSTRING(CRLF CRLF);
+ NS_LITERAL_CSTRING("Content-Type: ");
AppendUTF16toUTF8(contentType, mPostDataChunk);
mPostDataChunk += NS_LITERAL_CSTRING(CRLF CRLF);
// Add the file to the stream
if (fileStream) {
@ -605,7 +600,7 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
nsIDOMFile* aFile);
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream);
@ -628,11 +623,11 @@ nsFSTextPlain::AddNameValuePair(const nsAString& aName,
nsresult
nsFSTextPlain::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
nsIDOMFile* aFile)
{
nsAutoString filename;
if (aFile) {
aFile->GetLeafName(filename);
aFile->GetName(filename);
}
AddNameValuePair(aName, filename);

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

@ -1315,6 +1315,18 @@ NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo, \
NS_INTERFACE_TABLE_ENTRY(_class, _i6) \
NS_OFFSET_AND_INTERFACE_TABLE_END
#define NS_HTML_CONTENT_INTERFACE_TABLE7(_class, _i1, _i2, _i3, _i4, _i5, \
_i6, _i7) \
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(_class) \
NS_INTERFACE_TABLE_ENTRY(_class, _i1) \
NS_INTERFACE_TABLE_ENTRY(_class, _i2) \
NS_INTERFACE_TABLE_ENTRY(_class, _i3) \
NS_INTERFACE_TABLE_ENTRY(_class, _i4) \
NS_INTERFACE_TABLE_ENTRY(_class, _i5) \
NS_INTERFACE_TABLE_ENTRY(_class, _i6) \
NS_INTERFACE_TABLE_ENTRY(_class, _i7) \
NS_OFFSET_AND_INTERFACE_TABLE_END
#define NS_HTML_CONTENT_INTERFACE_TABLE8(_class, _i1, _i2, _i3, _i4, _i5, \
_i6, _i7, _i8) \
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(_class) \

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

@ -38,7 +38,6 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsITextControlElement.h"
#include "nsIFileControlElement.h"
#include "nsIDOMNSEditableElement.h"
#include "nsIRadioVisitor.h"
#include "nsIPhonetic.h"
@ -93,8 +92,8 @@
#include "nsRuleData.h"
// input type=radio
#include "nsIRadioGroupContainer.h"
// input type=radio
#include "nsIRadioGroupContainer.h"
// input type=file
#include "nsIFile.h"
@ -207,12 +206,13 @@ class nsHTMLInputElementState : public nsISupports
mValue = aValue;
}
const nsTArray<nsString>& GetFilenames() {
return mFilenames;
const nsCOMArray<nsIDOMFile>& GetFiles() {
return mFiles;
}
void SetFilenames(const nsTArray<nsString> &aFilenames) {
mFilenames = aFilenames;
void SetFiles(const nsCOMArray<nsIDOMFile> &aFiles) {
mFiles.Clear();
mFiles.AppendObjects(aFiles);
}
nsHTMLInputElementState()
@ -223,7 +223,7 @@ class nsHTMLInputElementState : public nsISupports
protected:
nsString mValue;
nsTArray<nsString> mFilenames;
nsCOMArray<nsIDOMFile> mFiles;
PRPackedBool mChecked;
PRPackedBool mCheckedSet;
};
@ -268,21 +268,21 @@ AsyncClickHandler::Run()
// Check if page is allowed to open the popup
if (mPopupControlState != openAllowed) {
nsCOMPtr<nsIPopupWindowManager> pm =
do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
if (!pm) {
return NS_OK;
}
PRUint32 permission;
pm->TestPermission(doc->GetDocumentURI(), &permission);
if (permission == nsIPopupWindowManager::DENY_POPUP) {
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
nsGlobalWindow::FirePopupBlockedEvent(domDoc, win, nsnull, EmptyString(), EmptyString());
nsCOMPtr<nsIPopupWindowManager> pm =
do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
if (!pm) {
return NS_OK;
}
}
PRUint32 permission;
pm->TestPermission(doc->GetDocumentURI(), &permission);
if (permission == nsIPopupWindowManager::DENY_POPUP) {
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
nsGlobalWindow::FirePopupBlockedEvent(domDoc, win, nsnull, EmptyString(), EmptyString());
return NS_OK;
}
}
// Get Loc title
nsXPIDLString title;
@ -325,17 +325,24 @@ AsyncClickHandler::Run()
// Set default directry and filename
nsAutoString defaultName;
nsCOMArray<nsIFile> oldFiles;
mInput->GetFileArray(oldFiles);
const nsCOMArray<nsIDOMFile>& oldFiles = mInput->GetFiles();
if (oldFiles.Count()) {
// set directory
nsCOMPtr<nsIFile> parentFile;
oldFiles[0]->GetParent(getter_AddRefs(parentFile));
if (parentFile) {
nsCOMPtr<nsILocalFile> parentLocalFile = do_QueryInterface(parentFile, &rv);
if (parentLocalFile) {
filePicker->SetDisplayDirectory(parentLocalFile);
nsString path;
oldFiles[0]->GetMozFullPathInternal(path);
nsCOMPtr<nsILocalFile> localFile;
rv = NS_NewLocalFile(path, PR_FALSE, getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIFile> parentFile;
rv = localFile->GetParent(getter_AddRefs(parentFile));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsILocalFile> parentLocalFile = do_QueryInterface(parentFile, &rv);
if (parentLocalFile) {
filePicker->SetDisplayDirectory(parentLocalFile);
}
}
}
@ -344,7 +351,7 @@ AsyncClickHandler::Run()
// one file was selected before.
if (oldFiles.Count() == 1) {
nsAutoString leafName;
oldFiles[0]->GetLeafName(leafName);
oldFiles[0]->GetName(leafName);
if (!leafName.IsEmpty()) {
filePicker->SetDefaultString(leafName);
}
@ -375,7 +382,7 @@ AsyncClickHandler::Run()
return NS_OK;
// Collect new selected filenames
nsTArray<nsString> newFileNames;
nsCOMArray<nsIDOMFile> newFiles;
if (multi) {
nsCOMPtr<nsISimpleEnumerator> iter;
rv = filePicker->GetFiles(getter_AddRefs(iter));
@ -389,7 +396,9 @@ AsyncClickHandler::Run()
nsString unicodePath;
rv = localFile->GetPath(unicodePath);
if (!unicodePath.IsEmpty()) {
newFileNames.AppendElement(unicodePath);
nsCOMPtr<nsIDOMFile> domFile =
do_QueryObject(new nsDOMFile(localFile, doc));
newFiles.AppendObject(domFile);
}
if (!prefSaved) {
// Store the last used directory using the content pref service
@ -408,7 +417,9 @@ AsyncClickHandler::Run()
nsString unicodePath;
rv = localFile->GetPath(unicodePath);
if (!unicodePath.IsEmpty()) {
newFileNames.AppendElement(unicodePath);
nsCOMPtr<nsIDOMFile> domFile=
do_QueryObject(new nsDOMFile(localFile, doc));
newFiles.AppendObject(domFile);
}
// Store the last used directory using the content pref service
rv = nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(doc->GetDocumentURI(),
@ -418,7 +429,7 @@ AsyncClickHandler::Run()
}
// Set new selected files
if (!newFileNames.IsEmpty()) {
if (newFiles.Count()) {
// Tell mTextFrame that this update of the value is a user initiated
// change. Otherwise it'll think that the value is being set by a script
// and not fire onchange when it should.
@ -428,7 +439,7 @@ AsyncClickHandler::Run()
textFrame->SetFireChangeEventState(PR_TRUE);
}
mInput->SetFileNames(newFileNames);
mInput->SetFiles(newFiles);
if (textFrame) {
textFrame->SetFireChangeEventState(oldState);
// May need to fire an onchange here
@ -669,10 +680,9 @@ DOMCI_NODE_DATA(HTMLInputElement, nsHTMLInputElement)
// QueryInterface implementation for nsHTMLInputElement
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
NS_HTML_CONTENT_INTERFACE_TABLE9(nsHTMLInputElement,
NS_HTML_CONTENT_INTERFACE_TABLE8(nsHTMLInputElement,
nsIDOMHTMLInputElement,
nsITextControlElement,
nsIFileControlElement,
nsIPhonetic,
imgIDecoderObserver,
nsIImageLoadingContent,
@ -721,7 +731,14 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
}
break;
case NS_FORM_INPUT_FILE:
it->mFileNames = mFileNames;
if (it->GetOwnerDoc()->IsStaticDocument()) {
// We're going to be used in print preview. Since the doc is static
// we can just grab the pretty string and use it as wallpaper
GetDisplayFileName(it->mStaticDocFileList);
} else {
it->mFiles.Clear();
it->mFiles.AppendObjects(mFiles);
}
break;
case NS_FORM_INPUT_RADIO:
case NS_FORM_INPUT_CHECKBOX:
@ -1025,17 +1042,15 @@ nsHTMLInputElement::GetValue(nsAString& aValue)
if (mType == NS_FORM_INPUT_FILE) {
if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) {
if (!mFileNames.IsEmpty()) {
aValue = mFileNames[0];
if (mFiles.Count()) {
return mFiles[0]->GetMozFullPath(aValue);
}
else {
aValue.Truncate();
}
} else {
// Just return the leaf name
nsCOMArray<nsIFile> files;
GetFileArray(files);
if (files.Count() == 0 || NS_FAILED(files[0]->GetLeafName(aValue))) {
if (mFiles.Count() == 0 || NS_FAILED(mFiles[0]->GetName(aValue))) {
aValue.Truncate();
}
}
@ -1065,10 +1080,11 @@ nsHTMLInputElement::SetValue(const nsAString& aValue)
// UniversalFileRead privilege
return NS_ERROR_DOM_SECURITY_ERR;
}
SetSingleFileName(aValue);
const PRUnichar *name = PromiseFlatString(aValue).get();
return MozSetFileNameArray(&name, 1);
}
else {
ClearFileNames();
ClearFiles();
}
}
else {
@ -1087,12 +1103,14 @@ nsHTMLInputElement::MozGetFileNameArray(PRUint32 *aLength, PRUnichar ***aFileNam
return NS_ERROR_DOM_SECURITY_ERR;
}
*aLength = mFileNames.Length();
*aLength = mFiles.Count();
PRUnichar **ret =
static_cast<PRUnichar **>(NS_Alloc(mFileNames.Length() * sizeof(PRUnichar*)));
static_cast<PRUnichar **>(NS_Alloc(mFiles.Count() * sizeof(PRUnichar*)));
for (PRUint32 i = 0; i < mFileNames.Length(); i++) {
ret[i] = NS_strdup(mFileNames[i].get());
for (PRUint32 i = 0; i < mFiles.Count(); i++) {
nsString str;
mFiles[i]->GetMozFullPath(str);
ret[i] = NS_strdup(str.get());
}
*aFileNames = ret;
@ -1109,12 +1127,36 @@ nsHTMLInputElement::MozSetFileNameArray(const PRUnichar **aFileNames, PRUint32 a
return NS_ERROR_DOM_SECURITY_ERR;
}
nsTArray<nsString> fileNames(aLength);
nsCOMArray<nsIDOMFile> files;
for (PRUint32 i = 0; i < aLength; ++i) {
fileNames.AppendElement(aFileNames[i]);
nsCOMPtr<nsIFile> file;
if (StringBeginsWith(nsDependentString(aFileNames[i]),
NS_LITERAL_STRING("file:"),
nsASCIICaseInsensitiveStringComparator())) {
// Converts the URL string into the corresponding nsIFile if possible
// A local file will be created if the URL string begins with file://
NS_GetFileFromURLSpec(NS_ConvertUTF16toUTF8(aFileNames[i]),
getter_AddRefs(file));
}
if (!file) {
// this is no "file://", try as local file
nsCOMPtr<nsILocalFile> localFile;
NS_NewLocalFile(nsDependentString(aFileNames[i]),
PR_FALSE, getter_AddRefs(localFile));
file = do_QueryInterface(localFile);
}
if (file) {
nsCOMPtr<nsIDOMFile> domFile = new nsDOMFile(file, GetOwnerDoc());
files.AppendObject(domFile);
} else {
continue; // Not much we can do if the file doesn't exist
}
}
SetFileNames(fileNames);
SetFiles(files);
return NS_OK;
}
@ -1136,7 +1178,8 @@ nsHTMLInputElement::SetUserInput(const nsAString& aValue)
if (mType == NS_FORM_INPUT_FILE)
{
SetSingleFileName(aValue);
const PRUnichar* name = PromiseFlatString(aValue).get();
return MozSetFileNameArray(&name, 1);
} else {
SetValueInternal(aValue, PR_TRUE, PR_TRUE);
}
@ -1241,28 +1284,32 @@ nsHTMLInputElement::SetPlaceholderClass(PRBool aVisible, PRBool aNotify)
}
void
nsHTMLInputElement::GetDisplayFileName(nsAString& aValue)
nsHTMLInputElement::GetDisplayFileName(nsAString& aValue) const
{
if (GetOwnerDoc()->IsStaticDocument()) {
aValue = mStaticDocFileList;
return;
}
aValue.Truncate();
for (PRUint32 i = 0; i < mFileNames.Length(); ++i) {
for (PRUint32 i = 0; i < (PRUint32)mFiles.Count(); ++i) {
nsString str;
mFiles[i]->GetMozFullPath(str);
if (i == 0) {
aValue.Append(mFileNames[i]);
aValue.Append(str);
}
else {
aValue.Append(NS_LITERAL_STRING(", ") + mFileNames[i]);
aValue.Append(NS_LITERAL_STRING(", ") + str);
}
}
}
void
nsHTMLInputElement::SetFileNames(const nsTArray<nsString>& aFileNames)
nsHTMLInputElement::SetFiles(const nsCOMArray<nsIDOMFile>& aFiles)
{
mFileNames = aFileNames;
#if DEBUG
for (PRUint32 i = 0; i < (PRUint32)aFileNames.Length(); ++i) {
NS_ASSERTION(!aFileNames[i].IsEmpty(), "Empty file name");
}
#endif
mFiles.Clear();
mFiles.AppendObjects(aFiles);
// No need to flush here, if there's no frame at this point we
// don't need to force creation of one just to tell it about this
// new value. We just want the display to update as needed.
@ -1279,37 +1326,10 @@ nsHTMLInputElement::SetFileNames(const nsTArray<nsString>& aFileNames)
UpdateAllValidityStates(PR_TRUE);
}
void
nsHTMLInputElement::GetFileArray(nsCOMArray<nsIFile> &aFiles)
const nsCOMArray<nsIDOMFile>&
nsHTMLInputElement::GetFiles()
{
aFiles.Clear();
if (mType != NS_FORM_INPUT_FILE) {
return;
}
for (PRUint32 i = 0; i < mFileNames.Length(); ++i) {
nsCOMPtr<nsIFile> file;
if (StringBeginsWith(mFileNames[i], NS_LITERAL_STRING("file:"),
nsCaseInsensitiveStringComparator())) {
// Converts the URL string into the corresponding nsIFile if possible.
// A local file will be created if the URL string begins with file://.
NS_GetFileFromURLSpec(NS_ConvertUTF16toUTF8(mFileNames[i]),
getter_AddRefs(file));
}
if (!file) {
// this is no "file://", try as local file
nsCOMPtr<nsILocalFile> localFile;
NS_NewLocalFile(mFileNames[i], PR_FALSE, getter_AddRefs(localFile));
// Wish there was a better way to downcast an already_AddRefed
file = dont_AddRef(static_cast<nsIFile*>(localFile.forget().get()));
}
if (file) {
aFiles.AppendObject(file);
}
}
return mFiles;
}
nsresult
@ -1318,16 +1338,10 @@ nsHTMLInputElement::UpdateFileList()
if (mFileList) {
mFileList->Clear();
nsIDocument* doc = GetOwnerDoc();
nsCOMArray<nsIFile> files;
GetFileArray(files);
const nsCOMArray<nsIDOMFile>& files = GetFiles();
for (PRUint32 i = 0; i < (PRUint32)files.Count(); ++i) {
nsRefPtr<nsDOMFile> domFile = new nsDOMFile(files[i], doc);
if (domFile) {
if (!mFileList->Append(domFile)) {
return NS_ERROR_FAILURE;
}
if (!mFileList->Append(files[i])) {
return NS_ERROR_FAILURE;
}
}
}
@ -1819,7 +1833,7 @@ nsHTMLInputElement::Click()
nsEventStatus status = nsEventStatus_eIgnore;
SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_TRUE);
if (mType == NS_FORM_INPUT_FILE){
if (mType == NS_FORM_INPUT_FILE){
FireAsyncClickHandler();
}
nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), context,
@ -2561,7 +2575,7 @@ nsHTMLInputElement::ParseAttribute(PRInt32 aNamespaceID,
// This call isn't strictly needed any more since we'll never
// confuse values and filenames. However it's there for backwards
// compat.
ClearFileNames();
ClearFiles();
}
HandleTypeChange(newType);
@ -2882,7 +2896,7 @@ nsHTMLInputElement::SetDefaultValueAsValue()
case NS_FORM_INPUT_FILE:
{
// Resetting it to blank should not perform security check
ClearFileNames();
ClearFiles();
break;
}
// Value is the same as defaultValue for hidden inputs
@ -3007,8 +3021,7 @@ nsHTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
if (mType == NS_FORM_INPUT_FILE) {
// Submit files
nsCOMArray<nsIFile> files;
GetFileArray(files);
const nsCOMArray<nsIDOMFile>& files = GetFiles();
for (PRUint32 i = 0; i < (PRUint32)files.Count(); ++i) {
aFormSubmission->AddNameFilePair(name, files[i]);
@ -3100,13 +3113,13 @@ nsHTMLInputElement::SaveState()
}
case NS_FORM_INPUT_FILE:
{
if (!mFileNames.IsEmpty()) {
if (mFiles.Count()) {
inputState = new nsHTMLInputElementState();
if (!inputState) {
return NS_ERROR_OUT_OF_MEMORY;
}
inputState->SetFilenames(mFileNames);
inputState->SetFiles(mFiles);
}
break;
}
@ -3253,7 +3266,8 @@ nsHTMLInputElement::RestoreState(nsPresState* aState)
}
case NS_FORM_INPUT_FILE:
{
SetFileNames(inputState->GetFilenames());
const nsCOMArray<nsIDOMFile>& files = inputState->GetFiles();
SetFiles(files);
break;
}
}
@ -3662,8 +3676,7 @@ nsHTMLInputElement::IsValueMissing()
}
case NS_FORM_INPUT_FILE:
{
nsCOMArray<nsIFile> files;
GetFileArray(files);
const nsCOMArray<nsIDOMFile>& files = GetFiles();
return !files.Count();
}
default:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -43,7 +43,13 @@
// Change the data for each of the form fields, and reload.
$("text").value = "text value";
$("checkbox").checked = true;
$("file").value = "file value";
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
file.append("294258_test.file");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
filePath = file.path;
$("file").value = filePath;
$("textarea").value = "textarea value";
$("radio1").checked = true;
$("select").selectedIndex = 2;
@ -56,7 +62,7 @@
// Verify that none of the form data has changed.
is($("text").value, "text value", "Text value changed");
is($("checkbox").checked, true, "Checkbox value changed");
is($("file").value, "file value", "File value changed");
is($("file").value, filePath, "File value changed");
is($("textarea").value, "textarea value", "Textarea value changed");
is($("radio1").checked, true, "Radio value changed");
is($("select").selectedIndex, 2, "Select value changed");

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

@ -18,6 +18,11 @@ var ctx1;
var ctx2;
var counter = 0;
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsILocalFile);
filePath = file.path;
function printpreview() {
gWbp = window.frames[1].QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebBrowserPrint);
@ -155,7 +160,7 @@ var emptyFormElements =
var formElements =
["<input type='text' value='text'>",
"<input type='password' value='password'>",
"<input type='file' value='file'>",
"<input type='file' value='" + filePath + "'>",
"<input type='button' value='button'>",
"<input type='submit' value='submit button'>",
"<input type='reset' value='reset button'>",

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

@ -65,7 +65,7 @@
#include "nsINodeInfo.h"
#include "nsIDOMEventTarget.h"
#include "nsILocalFile.h"
#include "nsIFileControlElement.h"
#include "nsHTMLInputElement.h"
#include "nsNodeInfoManager.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
@ -90,6 +90,7 @@
#include "nsHTMLInputElement.h"
#include "nsICapturePicker.h"
#include "nsIFileURL.h"
#include "nsDOMFile.h"
#define SYNC_TEXT 0x1
#define SYNC_BUTTON 0x2
@ -235,20 +236,21 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("text"), PR_FALSE);
nsCOMPtr<nsIDOMHTMLInputElement> textControl = do_QueryInterface(mTextContent);
if (textControl) {
nsCOMPtr<nsIFileControlElement> fileControl = do_QueryInterface(mContent);
if (fileControl) {
// Initialize value when we create the content in case the value was set
// before we got here
nsAutoString value;
fileControl->GetDisplayFileName(value);
textControl->SetValue(value);
}
nsHTMLInputElement* inputElement =
nsHTMLInputElement::FromContent(mContent);
NS_ASSERTION(inputElement, "Why is our content not a <input>?");
textControl->SetTabIndex(-1);
textControl->SetReadOnly(PR_TRUE);
}
// Initialize value when we create the content in case the value was set
// before we got here
nsAutoString value;
inputElement->GetDisplayFileName(value);
nsCOMPtr<nsIDOMHTMLInputElement> textControl = do_QueryInterface(mTextContent);
NS_ASSERTION(textControl, "Why is the <input> we created not a <input>?");
textControl->SetValue(value);
textControl->SetTabIndex(-1);
textControl->SetReadOnly(PR_TRUE);
if (!aElements.AppendElement(mTextContent))
return NS_ERROR_OUT_OF_MEMORY;
@ -398,9 +400,11 @@ nsFileControlFrame::CaptureMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
// Get parent nsIDOMWindowInternal object.
nsIContent* content = mFrame->GetContent();
nsCOMPtr<nsIDOMHTMLInputElement> inputElem = do_QueryInterface(content);
nsCOMPtr<nsIFileControlElement> fileControl = do_QueryInterface(content);
if (!content || !inputElem || !fileControl)
if (!content)
return NS_ERROR_FAILURE;
nsHTMLInputElement* inputElement = nsHTMLInputElement::FromContent(content);
if (!inputElement)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocument> doc = content->GetDocument();
@ -443,21 +447,13 @@ nsFileControlFrame::CaptureMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
rv = capturePicker->GetUri(getter_AddRefs(uri));
nsCOMPtr<nsIDOMFile> domFile;
rv = capturePicker->GetFile(getter_AddRefs(domFile));
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsString> newFileNames;
if (uri) {
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
if (!fileURL)
return NS_ERROR_UNEXPECTED;
nsCAutoString spec;
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
newFileNames.AppendElement(NS_ConvertUTF8toUTF16(spec));
nsCOMArray<nsIDOMFile> newFiles;
if (domFile) {
newFiles.AppendObject(domFile);
} else {
return NS_ERROR_FAILURE;
}
@ -465,13 +461,13 @@ nsFileControlFrame::CaptureMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
// XXXkhuey we really should have a better UI story than the tired old
// uneditable text box with the file name inside.
// Set new selected files
if (!newFileNames.IsEmpty()) {
if (newFiles.Count()) {
// Tell mTextFrame that this update of the value is a user initiated
// change. Otherwise it'll think that the value is being set by a script
// and not fire onchange when it should.
PRBool oldState = mFrame->mTextFrame->GetFireChangeEventState();
mFrame->mTextFrame->SetFireChangeEventState(PR_TRUE);
fileControl->SetFileNames(newFileNames);
inputElement->SetFiles(newFiles);
mFrame->mTextFrame->SetFireChangeEventState(oldState);
// May need to fire an onchange here
@ -491,12 +487,9 @@ nsFileControlFrame::BrowseMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
if (!ShouldProcessMouseClick(aMouseEvent))
return NS_OK;
nsIContent* content = mFrame->GetContent();
if (content->IsHTML() && content->Tag() == nsGkAtoms::input) {
nsHTMLInputElement* input = static_cast<nsHTMLInputElement*>(content);
return input->FireAsyncClickHandler();
}
return NS_OK;
nsHTMLInputElement* input =
nsHTMLInputElement::FromContent(mFrame->GetContent());
return input ? input->FireAsyncClickHandler() : NS_OK;
}
nscoord
@ -643,10 +636,11 @@ nsFileControlFrame::GetFormProperty(nsIAtom* aName, nsAString& aValue) const
aValue.Truncate(); // initialize out param
if (nsGkAtoms::value == aName) {
nsCOMPtr<nsIFileControlElement> fileControl =
do_QueryInterface(mContent);
if (fileControl) {
fileControl->GetDisplayFileName(aValue);
nsHTMLInputElement* inputElement =
nsHTMLInputElement::FromContent(mContent);
if (inputElement) {
inputElement->GetDisplayFileName(aValue);
}
}
return NS_OK;

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

@ -39,7 +39,7 @@
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsIURI;
interface nsIDOMFile;
[scriptable, uuid(a4e2b2de-5712-4f80-aabb-7de3a747f227)]
interface nsICapturePicker : nsISupports
@ -88,7 +88,7 @@ interface nsICapturePicker : nsISupports
* Get the captured image/video/audio. This may be a data URI, file URI,
* or a moz-filedata reference URI.
*/
readonly attribute nsIURI uri;
readonly attribute nsIDOMFile file;
// The MIME type of the captured content. Cannot be set after calling show()
attribute AString type;