зеркало из https://github.com/mozilla/gecko-dev.git
Bug 275453 - Finish <upload> implementation. r=allan, r=aaronr. Not part of default build.
This commit is contained in:
Родитель
e01ea0902e
Коммит
2f5b9ff526
|
@ -97,6 +97,7 @@ REQUIRES = \
|
|||
intl \
|
||||
pref \
|
||||
htmlparser \
|
||||
exthandler \
|
||||
$(NULL)
|
||||
|
||||
# XForms IDLs
|
||||
|
@ -123,6 +124,8 @@ XPIDLSRCS = \
|
|||
nsIXFormsItemElement.idl \
|
||||
nsIXFormsLabelElement.idl \
|
||||
nsIXFormsItemSetUIElement.idl \
|
||||
nsIXFormsUploadElement.idl \
|
||||
nsIXFormsUploadUIElement.idl \
|
||||
$(NULL)
|
||||
|
||||
# XForms source files
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* ***** 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 XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Javier Pedemonte <jhpedemonte@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 "nsISupports.idl"
|
||||
|
||||
|
||||
/**
|
||||
* Interface implemented by the XTF part of the upload element to allow
|
||||
* communication from XBL code.
|
||||
*/
|
||||
[scriptable, uuid(6dc00fd0-674c-41b3-8b0b-ba6c02aa769a)]
|
||||
interface nsIXFormsUploadElement : nsISupports
|
||||
{
|
||||
/**
|
||||
* Display file picker dialog so user can select a file.
|
||||
*/
|
||||
void pickFile();
|
||||
|
||||
/**
|
||||
* Unset file from \<upload\> and instance data.
|
||||
*/
|
||||
void clearFile();
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
/* ***** 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 XForms support.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Javier Pedemonte <jhpedemonte@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 "nsISupports.idl"
|
||||
|
||||
|
||||
/**
|
||||
* Interface implemented by the XBL part of the upload element.
|
||||
*/
|
||||
[scriptable, uuid(82c82c46-f111-416c-a3e6-ce9a0864d00f)]
|
||||
interface nsIXFormsUploadUIElement : nsISupports
|
||||
{
|
||||
/**
|
||||
* Set text value of \<upload\>'s text field.
|
||||
*/
|
||||
void setFieldText(in AString value);
|
||||
};
|
|
@ -315,17 +315,6 @@ nsXFormsControlStubBase::ResetHelpAndHint(PRBool aInitialize)
|
|||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXFormsControlStubBase::GetReadOnlyState()
|
||||
{
|
||||
PRBool res = PR_FALSE;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mElement));
|
||||
if (content && (content->IntrinsicState() & NS_EVENT_STATE_MOZ_READONLY)) {
|
||||
res = PR_TRUE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXFormsControlStubBase::GetRelevantState()
|
||||
{
|
||||
|
|
|
@ -178,9 +178,6 @@ protected:
|
|||
*/
|
||||
PRInt32 mBindAttrsCount;
|
||||
|
||||
/** Returns the read only state of the control (ie. mBoundNode) */
|
||||
PRBool GetReadOnlyState();
|
||||
|
||||
/** Returns the relevant state of the control */
|
||||
PRBool GetRelevantState();
|
||||
|
||||
|
|
|
@ -1289,8 +1289,8 @@ nsXFormsSubmissionElement::CopyChildren(nsIDOMNode *source, nsIDOMNode *dest,
|
|||
nsCOMPtr<nsIContent> content = do_QueryInterface(currentNode);
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsILocalFile *file =
|
||||
NS_STATIC_CAST(nsILocalFile *,
|
||||
nsIFile *file =
|
||||
NS_STATIC_CAST(nsIFile *,
|
||||
content->GetProperty(nsXFormsAtoms::uploadFileProperty));
|
||||
// NOTE: this value may be null if a file hasn't been selected.
|
||||
|
||||
|
@ -1655,8 +1655,8 @@ nsXFormsSubmissionElement::AppendMultipartFormData(nsIDOMNode *data,
|
|||
nsCOMPtr<nsIContent> content = do_QueryInterface(data);
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsILocalFile *file =
|
||||
NS_STATIC_CAST(nsILocalFile *,
|
||||
nsIFile *file =
|
||||
NS_STATIC_CAST(nsIFile *,
|
||||
content->GetProperty(nsXFormsAtoms::uploadFileProperty));
|
||||
|
||||
nsAutoString leafName;
|
||||
|
|
|
@ -36,26 +36,142 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIXTFXMLVisualWrapper.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsXFormsControlStub.h"
|
||||
#include "nsISchema.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsXFormsAtoms.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIXFormsUploadElement.h"
|
||||
#include "nsIXFormsUploadUIElement.h"
|
||||
#include "nsXFormsUtils.h"
|
||||
#include "nsIModelElementPrivate.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMXPathExpression.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXFormsDelegateStub.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "plbase64.h"
|
||||
#include "nsIFilePicker.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMAbstractView.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsAutoBuffer.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#define NS_HTMLFORM_BUNDLE_URL \
|
||||
"chrome://global/locale/layout/HtmlForm.properties"
|
||||
|
||||
|
||||
enum nsBoundType {
|
||||
TYPE_DEFAULT,
|
||||
TYPE_ANYURI,
|
||||
TYPE_BASE64,
|
||||
TYPE_HEX
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the \<upload\> element.
|
||||
*/
|
||||
class nsXFormsUploadElement : public nsXFormsDelegateStub,
|
||||
public nsIXFormsUploadElement
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIXFORMSUPLOADELEMENT
|
||||
|
||||
NS_IMETHOD Refresh();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns the type of the node to which this element is bound.
|
||||
*/
|
||||
nsBoundType GetBoundType();
|
||||
|
||||
/**
|
||||
* Sets file path/contents into instance data. If aFile is nsnull,
|
||||
* this clears the data.
|
||||
*/
|
||||
nsresult SetFile(nsILocalFile *aFile);
|
||||
|
||||
/**
|
||||
* Sets "filename" & "mediatype" in the instance data, using the given file.
|
||||
* If aFile == nsnull, then this function clears the values in the
|
||||
* instance data.
|
||||
*/
|
||||
nsresult HandleChildElements(nsILocalFile *aFile, PRBool *aChanged);
|
||||
|
||||
/**
|
||||
* Read the contents of the file and encode in Base64 or Hex. |aResult| must
|
||||
* be freed by nsMemory::Free().
|
||||
*/
|
||||
nsresult EncodeFileContents(nsIFile *aFile, nsBoundType aType,
|
||||
PRUnichar **aResult);
|
||||
|
||||
void BinaryToHex(const char *aBuffer, PRUint32 aCount,
|
||||
PRUnichar **aHexString);
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsUploadElement,
|
||||
nsXFormsDelegateStub,
|
||||
nsIXFormsUploadElement)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::Refresh()
|
||||
{
|
||||
// This is called when the 'bind', 'ref' or 'model' attribute has changed.
|
||||
// So we need to make sure that the element is still bound to a node of
|
||||
// type 'anyURI', 'base64Binary', or 'hexBinary'.
|
||||
|
||||
nsresult rv = nsXFormsDelegateStub::Refresh();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mBoundNode)
|
||||
return NS_OK;
|
||||
|
||||
// If it is not bound to 'anyURI', 'base64Binary', or 'hexBinary', then
|
||||
// mark as not relevant.
|
||||
// XXX Bug 313313 - the 'relevant' state should be handled in XBL constructor.
|
||||
nsCOMPtr<nsIXTFElementWrapper> xtfWrap(do_QueryInterface(mElement));
|
||||
NS_ENSURE_STATE(xtfWrap);
|
||||
if (GetBoundType() == TYPE_DEFAULT) {
|
||||
xtfWrap->SetIntrinsicState(NS_EVENT_STATE_DISABLED);
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("uploadBoundTypeError"),
|
||||
mElement);
|
||||
} else {
|
||||
xtfWrap->SetIntrinsicState(NS_EVENT_STATE_ENABLED);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBoundType
|
||||
nsXFormsUploadElement::GetBoundType()
|
||||
{
|
||||
nsBoundType result = TYPE_DEFAULT;
|
||||
|
||||
// get type bound to node
|
||||
nsAutoString type, prefix, nsuri;
|
||||
nsresult rv = nsXFormsUtils::ParseTypeFromNode(mBoundNode, type, prefix);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// get the namespace url from the prefix
|
||||
nsCOMPtr<nsIDOM3Node> domNode3 = do_QueryInterface(mElement, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = domNode3->LookupNamespaceURI(prefix, nsuri);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && nsuri.EqualsLiteral(NS_NAMESPACE_XML_SCHEMA)) {
|
||||
if (type.EqualsLiteral("anyURI")) {
|
||||
result = TYPE_ANYURI;
|
||||
} else if (type.EqualsLiteral("base64Binary")) {
|
||||
result = TYPE_BASE64;
|
||||
} else if (type.EqualsLiteral("hexBinary")) {
|
||||
result = TYPE_HEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseObject(void *aObject,
|
||||
|
@ -66,215 +182,153 @@ ReleaseObject(void *aObject,
|
|||
NS_STATIC_CAST(nsISupports *, aPropertyValue)->Release();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the \<upload\> element.
|
||||
*/
|
||||
class nsXFormsUploadElement : public nsIDOMFocusListener,
|
||||
public nsXFormsControlStub
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIXTFXMLVisual overrides
|
||||
NS_IMETHOD OnCreated(nsIXTFXMLVisualWrapper *aWrapper);
|
||||
|
||||
// nsIXTFVisual overrides
|
||||
NS_IMETHOD GetVisualContent(nsIDOMElement **aElement);
|
||||
NS_IMETHOD GetInsertionPoint(nsIDOMElement **aPoint);
|
||||
|
||||
// nsIXTFElement overrides
|
||||
NS_IMETHOD OnDestroyed();
|
||||
NS_IMETHOD AttributeSet(nsIAtom *aName, const nsAString &aValue);
|
||||
NS_IMETHOD AttributeRemoved(nsIAtom *aName);
|
||||
|
||||
// nsIXFormsControl
|
||||
NS_IMETHOD Refresh();
|
||||
NS_IMETHOD TryFocus(PRBool* aOK);
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
|
||||
// nsIDOMFocusListener
|
||||
NS_IMETHOD Focus(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD Blur(nsIDOMEvent *aEvent);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDOMElement> mLabel;
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> mInput;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsUploadElement,
|
||||
nsXFormsControlStub,
|
||||
nsIDOMFocusListener,
|
||||
nsIDOMEventListener)
|
||||
|
||||
// nsIXTFXMLVisual
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper)
|
||||
nsXFormsUploadElement::PickFile()
|
||||
{
|
||||
nsresult rv = nsXFormsControlStub::OnCreated(aWrapper);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Our anonymous content structure will look like this:
|
||||
//
|
||||
// <label> (mLabel)
|
||||
// <span/> (insertion point)
|
||||
// <input/> (mInput)
|
||||
// </label>
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
|
||||
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
|
||||
NS_LITERAL_STRING("label"),
|
||||
getter_AddRefs(mLabel));
|
||||
NS_ENSURE_STATE(mLabel);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
nsCOMPtr<nsIDOMNode> childReturn;
|
||||
|
||||
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
|
||||
NS_LITERAL_STRING("span"),
|
||||
getter_AddRefs(element));
|
||||
NS_ENSURE_STATE(element);
|
||||
|
||||
mLabel->AppendChild(element, getter_AddRefs(childReturn));
|
||||
|
||||
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
|
||||
NS_LITERAL_STRING("input"),
|
||||
getter_AddRefs(element));
|
||||
mInput = do_QueryInterface(element);
|
||||
NS_ENSURE_STATE(mInput);
|
||||
|
||||
mInput->SetType(NS_LITERAL_STRING("file"));
|
||||
|
||||
mLabel->AppendChild(mInput, getter_AddRefs(childReturn));
|
||||
|
||||
// We can't use xtf handleDefault here because editor stops blur events from
|
||||
// bubbling, and we can't use a system event group handler because blur
|
||||
// events don't go to the system event group (bug 263240). So, just install
|
||||
// a bubbling listener in the normal event group. This works out because
|
||||
// content can't get at the anonymous content to install an event handler,
|
||||
// and the event doesn't bubble up.
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(mInput);
|
||||
NS_ASSERTION(targ, "input must be an event target!");
|
||||
|
||||
targ->AddEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::AttributeSet(nsIAtom *aName, const nsAString &aValue)
|
||||
{
|
||||
if (aName == nsXFormsAtoms::accesskey) {
|
||||
// accesskey
|
||||
mInput->SetAttribute(NS_LITERAL_STRING("accesskey"), aValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::AttributeRemoved(nsIAtom *aName)
|
||||
{
|
||||
if (aName == nsXFormsAtoms::accesskey) {
|
||||
// accesskey
|
||||
mInput->RemoveAttribute(NS_LITERAL_STRING("accesskey"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIXTFVisual
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::GetVisualContent(nsIDOMElement **aElement)
|
||||
{
|
||||
NS_ADDREF(*aElement = mLabel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::GetInsertionPoint(nsIDOMElement **aPoint)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
mLabel->GetFirstChild(getter_AddRefs(childNode));
|
||||
return CallQueryInterface(childNode, aPoint);
|
||||
}
|
||||
|
||||
// nsIXTFElement
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::OnDestroyed()
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(mInput);
|
||||
if (NS_LIKELY(targ != nsnull)) {
|
||||
targ->RemoveEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE);
|
||||
}
|
||||
|
||||
return nsXFormsControlStub::OnDestroyed();
|
||||
}
|
||||
|
||||
// nsIDOMEventListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::HandleEvent(nsIDOMEvent *aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::Focus(nsIDOMEvent *aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::Blur(nsIDOMEvent *aEvent)
|
||||
{
|
||||
if (!mInput || !mBoundNode || !mModel ||
|
||||
!nsXFormsUtils::EventHandlingAllowed(aEvent, mElement))
|
||||
if (!mElement)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString value;
|
||||
mInput->GetValue(value);
|
||||
nsresult rv;
|
||||
|
||||
// store the file as a property on the selected content node. the submission
|
||||
// code will read this value.
|
||||
// get localized file picker title text
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(NS_HTMLFORM_BUNDLE_URL,
|
||||
getter_AddRefs(bundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXPIDLString filepickerTitle;
|
||||
rv = bundle->GetStringFromName(NS_LITERAL_STRING("FileUpload").get(),
|
||||
getter_Copies(filepickerTitle));
|
||||
if (NS_FAILED(rv)) {
|
||||
// fall back to English text
|
||||
filepickerTitle.AssignASCII("File Upload");
|
||||
}
|
||||
|
||||
// get nsIDOMWindowInternal
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMDocumentView> dview = do_QueryInterface(doc);
|
||||
NS_ENSURE_STATE(dview);
|
||||
nsCOMPtr<nsIDOMAbstractView> aview;
|
||||
dview->GetDefaultView(getter_AddRefs(aview));
|
||||
nsCOMPtr<nsIDOMWindowInternal> internal = do_QueryInterface(aview);
|
||||
NS_ENSURE_STATE(internal);
|
||||
|
||||
// init filepicker
|
||||
nsCOMPtr<nsIFilePicker> filePicker =
|
||||
do_CreateInstance("@mozilla.org/filepicker;1");
|
||||
if (!filePicker)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = filePicker->Init(internal, filepickerTitle, nsIFilePicker::modeOpen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// set filter "All Files"
|
||||
// XXX implement "@mediatype" file filters
|
||||
filePicker->AppendFilters(nsIFilePicker::filterAll);
|
||||
|
||||
// open dialog
|
||||
PRInt16 mode;
|
||||
rv = filePicker->Show(&mode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mode == nsIFilePicker::returnCancel)
|
||||
return NS_OK;
|
||||
|
||||
// file was selected
|
||||
nsCOMPtr<nsILocalFile> localFile;
|
||||
rv = filePicker->GetFile(getter_AddRefs(localFile));
|
||||
if (localFile) {
|
||||
// set path value in \<upload\>'s text field.
|
||||
nsCOMPtr<nsIXFormsUploadUIElement> uiUpload = do_QueryInterface(mElement);
|
||||
if (uiUpload) {
|
||||
nsCAutoString spec;
|
||||
NS_GetURLSpecFromFile(localFile, spec);
|
||||
uiUpload->SetFieldText(NS_ConvertUTF8toUTF16(spec));
|
||||
}
|
||||
|
||||
// set file into instance data
|
||||
return SetFile(localFile);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::ClearFile()
|
||||
{
|
||||
// clear path value in \<upload\>'s text field.
|
||||
nsCOMPtr<nsIXFormsUploadUIElement> uiUpload = do_QueryInterface(mElement);
|
||||
if (uiUpload) {
|
||||
uiUpload->SetFieldText(EmptyString());
|
||||
}
|
||||
|
||||
// clear file from instance data
|
||||
return SetFile(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsUploadElement::SetFile(nsILocalFile *aFile)
|
||||
{
|
||||
if (!mBoundNode || !mModel)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mBoundNode);
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsILocalFile *file = nsnull;
|
||||
nsCAutoString spec;
|
||||
|
||||
// We need to special case an empty value. If the input field is blank,
|
||||
// then I assume that the intention is that all bound nodes will become
|
||||
// (or stay) empty and that there shouldn't be any file kept in the property.
|
||||
if (!value.IsEmpty()) {
|
||||
NS_NewLocalFile(value, PR_FALSE, &file);
|
||||
NS_ENSURE_STATE(file);
|
||||
NS_GetURLSpecFromFile(file, spec);
|
||||
content->SetProperty(nsXFormsAtoms::uploadFileProperty, file,
|
||||
ReleaseObject);
|
||||
} else {
|
||||
PRBool dataChanged = PR_FALSE;
|
||||
if (!aFile) {
|
||||
// clear instance data
|
||||
content->DeleteProperty(nsXFormsAtoms::uploadFileProperty);
|
||||
rv = mModel->SetNodeValue(mBoundNode, EmptyString(), &dataChanged);
|
||||
} else {
|
||||
// set file into instance data
|
||||
|
||||
nsBoundType type = GetBoundType();
|
||||
if (type == TYPE_ANYURI) {
|
||||
// set fully qualified path as value in instance data node
|
||||
nsCAutoString spec;
|
||||
NS_GetURLSpecFromFile(aFile, spec);
|
||||
rv = mModel->SetNodeValue(mBoundNode, NS_ConvertUTF8toUTF16(spec),
|
||||
&dataChanged);
|
||||
} else if (type == TYPE_BASE64 || type == TYPE_HEX) {
|
||||
// encode file contents in base64/hex and set into instance data node
|
||||
PRUnichar *fileData;
|
||||
rv = EncodeFileContents(aFile, type, &fileData);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mModel->SetNodeValue(mBoundNode, nsDependentString(fileData),
|
||||
&dataChanged);
|
||||
nsMemory::Free(fileData);
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX need to handle derived types
|
||||
|
||||
// Set nsIFile object as property on instance data node, so submission
|
||||
// code can use it.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsIFile *fileCopy = nsnull;
|
||||
rv = aFile->Clone(&fileCopy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = content->SetProperty(nsXFormsAtoms::uploadFileProperty, fileCopy,
|
||||
ReleaseObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update the instance data node. this value is never used by the submission
|
||||
// code. instead, it exists so that the instance data will appear to be in-
|
||||
// sync with what is actually submitted.
|
||||
|
||||
PRBool changed;
|
||||
nsresult rv = mModel->SetNodeValue(mBoundNode, NS_ConvertUTF8toUTF16(spec),
|
||||
&changed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (changed) {
|
||||
|
||||
// Handle <filename> and <mediatype> children
|
||||
PRBool childrenChanged;
|
||||
rv = HandleChildElements(aFile, &childrenChanged);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (dataChanged || childrenChanged) {
|
||||
nsCOMPtr<nsIDOMNode> model = do_QueryInterface(mModel);
|
||||
|
||||
if (model) {
|
||||
rv = nsXFormsUtils::DispatchEvent(model, eEvent_Recalculate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -284,42 +338,199 @@ nsXFormsUploadElement::Blur(nsIDOMEvent *aEvent)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIXFormsControl
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::Refresh()
|
||||
nsresult
|
||||
nsXFormsUploadElement::HandleChildElements(nsILocalFile *aFile,
|
||||
PRBool *aChanged)
|
||||
{
|
||||
if (!mInput || !mBoundNode)
|
||||
if (!aChanged) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aChanged = PR_FALSE;
|
||||
|
||||
// return immediately if we have no children
|
||||
PRBool hasNodes;
|
||||
mElement->HasChildNodes(&hasNodes);
|
||||
if (!hasNodes)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mBoundNode);
|
||||
NS_ENSURE_STATE(content);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsILocalFile *file =
|
||||
NS_STATIC_CAST(nsILocalFile *,
|
||||
content->GetProperty(nsXFormsAtoms::uploadFileProperty));
|
||||
// look for the \<filename\> & \<mediatype\> elements in the
|
||||
// \<upload\> children
|
||||
nsCOMPtr<nsIDOMNode> filenameNode, mediatypeNode;
|
||||
nsCOMPtr<nsIDOMNode> child, temp;
|
||||
mElement->GetFirstChild(getter_AddRefs(child));
|
||||
while (child && (!filenameNode || !mediatypeNode)) {
|
||||
if (!filenameNode &&
|
||||
nsXFormsUtils::IsXFormsElement(child,
|
||||
NS_LITERAL_STRING("filename")))
|
||||
{
|
||||
filenameNode = child;
|
||||
}
|
||||
|
||||
// get the text value for the control
|
||||
nsAutoString value;
|
||||
if (file)
|
||||
file->GetPath(value);
|
||||
if (!mediatypeNode &&
|
||||
nsXFormsUtils::IsXFormsElement(child,
|
||||
NS_LITERAL_STRING("mediatype")))
|
||||
{
|
||||
mediatypeNode = child;
|
||||
}
|
||||
|
||||
mInput->SetValue(value);
|
||||
mInput->SetReadOnly(GetReadOnlyState());
|
||||
temp.swap(child);
|
||||
temp->GetNextSibling(getter_AddRefs(child));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// handle "filename"
|
||||
PRBool filenameChanged = PR_FALSE;
|
||||
if (filenameNode) {
|
||||
nsCOMPtr<nsIDOMElement> filenameElem = do_QueryInterface(filenameNode);
|
||||
if (aFile) {
|
||||
nsAutoString filename;
|
||||
rv = aFile->GetLeafName(filename);
|
||||
if (!filename.IsEmpty()) {
|
||||
rv = nsXFormsUtils::SetSingleNodeBindingValue(filenameElem, filename,
|
||||
&filenameChanged);
|
||||
}
|
||||
} else {
|
||||
rv = nsXFormsUtils::SetSingleNodeBindingValue(filenameElem, EmptyString(),
|
||||
&filenameChanged);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// handle "mediatype"
|
||||
PRBool mediatypechanged = PR_FALSE;
|
||||
if (mediatypeNode) {
|
||||
nsCOMPtr<nsIDOMElement> mediatypeElem = do_QueryInterface(mediatypeNode);
|
||||
if (aFile) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService =
|
||||
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString contentType;
|
||||
rv = mimeService->GetTypeFromFile(aFile, contentType);
|
||||
if (NS_FAILED(rv)) {
|
||||
contentType.AssignLiteral("application/octet-stream");
|
||||
}
|
||||
rv = nsXFormsUtils::SetSingleNodeBindingValue(mediatypeElem,
|
||||
NS_ConvertUTF8toUTF16(contentType), &mediatypechanged);
|
||||
}
|
||||
} else {
|
||||
rv = nsXFormsUtils::SetSingleNodeBindingValue(mediatypeElem,
|
||||
EmptyString(), &mediatypechanged);
|
||||
}
|
||||
}
|
||||
|
||||
*aChanged = filenameChanged || mediatypechanged;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsUploadElement::TryFocus(PRBool* aOK)
|
||||
typedef nsAutoBuffer<char, 256> nsAutoCharBuffer;
|
||||
|
||||
static void
|
||||
ReportEncodingMemoryError(nsIDOMElement* aElement, nsIFile *aFile,
|
||||
PRUint32 aFailedSize)
|
||||
{
|
||||
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mInput);
|
||||
return NS_OK;
|
||||
nsAutoString filename;
|
||||
if (NS_FAILED(aFile->GetLeafName(filename))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString size;
|
||||
size.AppendInt((PRInt64)aFailedSize);
|
||||
const PRUnichar *strings[] = { filename.get(), size.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("encodingMemoryError"),
|
||||
strings, 2, aElement, aElement);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsUploadElement::EncodeFileContents(nsIFile *aFile, nsBoundType aType,
|
||||
PRUnichar **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// get file contents
|
||||
nsCOMPtr<nsIInputStream> fileStream;
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), aFile,
|
||||
PR_RDONLY, -1 /* no mode bits */,
|
||||
nsIFileInputStream::CLOSE_ON_EOF);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 size;
|
||||
rv = fileStream->Available(&size);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCharBuffer fileData;
|
||||
if (!fileData.EnsureElemCapacity(size + 1)) {
|
||||
ReportEncodingMemoryError(mElement, aFile, size + 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
PRUint32 bytesRead;
|
||||
rv = fileStream->Read(fileData.get(), size, &bytesRead);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && bytesRead == size,
|
||||
"fileStream->Read failed");
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (aType == TYPE_BASE64) {
|
||||
// encode file contents
|
||||
*aResult = nsnull;
|
||||
char *buffer = PL_Base64Encode(fileData.get(), bytesRead, nsnull);
|
||||
if (buffer) {
|
||||
*aResult = ToNewUnicode(nsDependentCString(buffer));
|
||||
PR_Free(buffer);
|
||||
}
|
||||
if (!*aResult) {
|
||||
PRUint32 failedSize = buffer ? strlen(buffer) * sizeof(PRUnichar)
|
||||
: ((bytesRead + 2) / 3) * 4 + 1;
|
||||
ReportEncodingMemoryError(mElement, aFile, failedSize);
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (aType == TYPE_HEX) {
|
||||
// create buffer for hex encoded data
|
||||
PRUint32 length = bytesRead * 2 + 1;
|
||||
PRUnichar *fileDataHex =
|
||||
NS_STATIC_CAST(PRUnichar*, nsMemory::Alloc(length * sizeof(PRUnichar)));
|
||||
if (!fileDataHex) {
|
||||
ReportEncodingMemoryError(mElement, aFile, length * sizeof(PRUnichar));
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
} else {
|
||||
// encode file contents
|
||||
BinaryToHex(fileData.get(), bytesRead, &fileDataHex);
|
||||
fileDataHex[bytesRead * 2] = 0;
|
||||
*aResult = fileDataHex;
|
||||
}
|
||||
} else {
|
||||
NS_ERROR("Unknown encoding type for <upload> element");
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static inline PRUnichar
|
||||
ToHexChar(PRInt16 aValue)
|
||||
{
|
||||
if (aValue < 10)
|
||||
return (PRUnichar) aValue + '0';
|
||||
else
|
||||
return (PRUnichar) aValue - 10 + 'A';
|
||||
}
|
||||
|
||||
void
|
||||
nsXFormsUploadElement::BinaryToHex(const char *aBuffer, PRUint32 aCount,
|
||||
PRUnichar **aHexString)
|
||||
{
|
||||
for (PRUint32 index = 0; index < aCount; index++) {
|
||||
(*aHexString)[index * 2] = ToHexChar((aBuffer[index] >> 4) & 0xf);
|
||||
(*aHexString)[index * 2 + 1] = ToHexChar(aBuffer[index] & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_NewXFormsUploadElement(nsIXTFElement **aResult)
|
||||
{
|
||||
|
|
|
@ -754,11 +754,10 @@ nsXFormsUtils::SetNodeValue(nsIDOMNode* aDataNode, const nsString& aNodeValue)
|
|||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// @todo Use this consistently, or delete? (XXX)
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::GetSingleNodeBindingValue(nsIDOMElement* aElement,
|
||||
nsString& aValue)
|
||||
nsXFormsUtils::GetSingleNodeBinding(nsIDOMElement* aElement,
|
||||
nsIDOMNode** aNode,
|
||||
nsIModelElementPrivate** aModel)
|
||||
{
|
||||
if (!aElement)
|
||||
return PR_FALSE;
|
||||
|
@ -781,10 +780,44 @@ nsXFormsUtils::GetSingleNodeBindingValue(nsIDOMElement* aElement,
|
|||
if (!singleNode)
|
||||
return PR_FALSE;
|
||||
|
||||
nsXFormsUtils::GetNodeValue(singleNode, aValue);
|
||||
singleNode.swap(*aNode);
|
||||
if (aModel)
|
||||
model.swap(*aModel); // transfers ref
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///
|
||||
/// @todo Use this consistently, or delete? (XXX)
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::GetSingleNodeBindingValue(nsIDOMElement* aElement,
|
||||
nsString& aValue)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
if (GetSingleNodeBinding(aElement, getter_AddRefs(node), nsnull)) {
|
||||
nsXFormsUtils::GetNodeValue(node, aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::SetSingleNodeBindingValue(nsIDOMElement *aElement,
|
||||
const nsAString &aValue,
|
||||
PRBool *aChanged)
|
||||
{
|
||||
*aChanged = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
if (GetSingleNodeBinding(aElement, getter_AddRefs(node),
|
||||
getter_AddRefs(model)))
|
||||
{
|
||||
nsresult rv = model->SetNodeValue(node, aValue, aChanged);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsXFormsUtils::DispatchEvent(nsIDOMNode* aTarget, nsXFormsEvent aEvent,
|
||||
PRBool *aDefaultActionEnabled)
|
||||
|
|
|
@ -252,6 +252,15 @@ public:
|
|||
static NS_HIDDEN_(void) SetNodeValue(nsIDOMNode *aDataNode,
|
||||
const nsString &aNodeValue);
|
||||
|
||||
/**
|
||||
* Convenience method for doing XPath evaluations to get bound node
|
||||
* for an element. Also returns the associated model if aModel != null.
|
||||
* Returns PR_TRUE if the evaluation succeeds.
|
||||
*/
|
||||
static NS_HIDDEN_(PRBool)
|
||||
GetSingleNodeBinding(nsIDOMElement* aElement, nsIDOMNode** aNode,
|
||||
nsIModelElementPrivate** aModel);
|
||||
|
||||
/**
|
||||
* Convenience method for doing XPath evaluations to get string value
|
||||
* for an element.
|
||||
|
@ -260,6 +269,14 @@ public:
|
|||
static NS_HIDDEN_(PRBool)
|
||||
GetSingleNodeBindingValue(nsIDOMElement* aElement, nsString& aValue);
|
||||
|
||||
/**
|
||||
* Convenience method for doing XPath evaluations to set string value
|
||||
* for an element.
|
||||
* Returns PR_TRUE if the evaluation succeeds.
|
||||
*/
|
||||
static NS_HIDDEN_(PRBool)
|
||||
SetSingleNodeBindingValue(nsIDOMElement *aElement, const nsAString &aValue,
|
||||
PRBool *aChanged);
|
||||
/**
|
||||
* Dispatch an XForms event. aDefaultActionEnabled is returned indicating
|
||||
* if the default action of the dispatched event was enabled.
|
||||
|
|
|
@ -255,4 +255,19 @@ select html|div.select-choice-content {
|
|||
padding-left: 10px;
|
||||
}
|
||||
|
||||
upload {
|
||||
-moz-binding: url('chrome://xforms/content/xforms.xml#xformswidget-upload-disabled');
|
||||
}
|
||||
|
||||
upload[mozType|type="http://www.w3.org/2001/XMLSchema#anyURI"] {
|
||||
-moz-binding: url('chrome://xforms/content/xforms.xml#xformswidget-upload');
|
||||
}
|
||||
|
||||
upload[mozType|type="http://www.w3.org/2001/XMLSchema#base64Binary"] {
|
||||
-moz-binding: url('chrome://xforms/content/xforms.xml#xformswidget-upload');
|
||||
}
|
||||
|
||||
upload[mozType|type="http://www.w3.org/2001/XMLSchema#hexBinary"] {
|
||||
-moz-binding: url('chrome://xforms/content/xforms.xml#xformswidget-upload');
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % xformsDTD SYSTEM "chrome://xforms/locale/xforms.dtd">
|
||||
%xformsDTD;
|
||||
]>
|
||||
|
||||
<bindings id="xformsBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -443,4 +448,111 @@
|
|||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<!-- UPLOAD: <DEFAULT> -->
|
||||
<binding id="xformswidget-upload"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
|
||||
<content>
|
||||
<children includes="label"/>
|
||||
<html:input anonid="upload_text_control"
|
||||
readonly="true"
|
||||
xbl:inherits="accesskey"/>
|
||||
<html:button anonid="upload_browse_button"
|
||||
type="button"
|
||||
onclick="this.parentNode.uploadElem.pickFile();"
|
||||
onkeypress="if (event.keyCode == event.DOM_VK_RETURN) this.parentNode.dispatchDOMActivate();"
|
||||
xbl:inherits="accesskey"> &xforms.upload.browsetext; </html:button>
|
||||
<html:button anonid="upload_clear_button"
|
||||
type="button"
|
||||
onclick="this.parentNode.uploadElem.clearFile();"
|
||||
onkeypress="if (event.keyCode == event.DOM_VK_RETURN) this.parentNode.dispatchDOMActivate();"
|
||||
xbl:inherits="accesskey"> &xforms.upload.cleartext; </html:button>
|
||||
<children/>
|
||||
</content>
|
||||
|
||||
<implementation implements="nsIXFormsUIWidget, nsIXFormsUploadUIElement">
|
||||
<destructor>
|
||||
this._uploadElem = null;
|
||||
this._textControl = null;
|
||||
this._browseButton = null;
|
||||
this._clearButton = null;
|
||||
</destructor>
|
||||
|
||||
<field name="_uploadElem">null</field>
|
||||
|
||||
<property name="uploadElem" readonly="true">
|
||||
<getter>
|
||||
if (!this._uploadElem) {
|
||||
this._uploadElem =
|
||||
this.QueryInterface(Components.interfaces.nsIXFormsUploadElement);
|
||||
}
|
||||
return this._uploadElem;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<field name="_textControl">null</field>
|
||||
|
||||
<property name="textControl" readonly="true">
|
||||
<getter>
|
||||
if (!this._textControl) {
|
||||
this._textControl =
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"upload_text_control");
|
||||
}
|
||||
return this._textControl;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<field name="_browseButton">null</field>
|
||||
|
||||
<property name="browseButton" readonly="true">
|
||||
<getter>
|
||||
if (!this._browseButton) {
|
||||
this._browseButton =
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"upload_browse_button");
|
||||
}
|
||||
return this._browseButton;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<field name="_clearButton">null</field>
|
||||
|
||||
<property name="clearButton" readonly="true">
|
||||
<getter>
|
||||
if (!this._clearButton) {
|
||||
this._clearButton =
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"upload_clear_button");
|
||||
}
|
||||
return this._clearButton;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<method name="setFieldText">
|
||||
<parameter name="aString"/>
|
||||
<body>
|
||||
this.textControl.value = aString;
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<!-- UPLOAD: DISABLED -->
|
||||
<binding id="xformswidget-upload-disabled"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
|
||||
<content>
|
||||
<children includes="label"/>
|
||||
<html:input readonly="true"
|
||||
xbl:inherits="accesskey"/>
|
||||
<html:button type="button"
|
||||
disabled="true"
|
||||
xbl:inherits="accesskey"> &xforms.upload.browsetext; </html:button>
|
||||
<html:button type="button"
|
||||
disabled="true"
|
||||
xbl:inherits="accesskey"> &xforms.upload.cleartext; </html:button>
|
||||
<children/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
|
|
|
@ -43,3 +43,6 @@
|
|||
<!ENTITY xforms.bindingdialog.title "XForms Error">
|
||||
<!ENTITY xforms.bindingdialog.description1 "The form on this page contains an error and will not work properly">
|
||||
<!ENTITY xforms.bindingdialog.description2 "See the JavaScript Console for details">
|
||||
|
||||
<!ENTITY xforms.upload.browsetext "Browse...">
|
||||
<!ENTITY xforms.upload.cleartext "Clear">
|
||||
|
|
|
@ -58,6 +58,8 @@ labelLink2Error = XForms Error (19): Failed to load Label element from exte
|
|||
invalidSeparator = XForms Error (20): Submission separator may only be either "&" or ";", but found "%S".
|
||||
instanceBindError = XForms Error (21): Submission failed trying to replace instance document '%S'. Instance document doesn't exist in same model as submission element.
|
||||
instanceInstanceLoad = XForms Error (22): Instance document not allowed to load external instance: %S
|
||||
encodingMemoryError = XForms Error (23): Not enough available memory to encode file %S, size = %S.
|
||||
uploadBoundTypeError = XForms Error (24): Upload element not bound to valid datatype. Must be bound to datatype 'xsd:anyURI', 'xsd:base64Binary', or 'xsd:hexBinary'.
|
||||
|
||||
# Warning Messages:
|
||||
warnSOAP = XForms Warning (1): You are using the SOAP post feature, which is an experimental feature! Beware that the functionality might change, and forms may stop working at any time.
|
||||
|
@ -65,4 +67,3 @@ warnSOAP = XForms Warning (1): You are using the SOAP post feature,
|
|||
# XForms Permission Messages:
|
||||
xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access
|
||||
xformsXDPermissionDialogIntro = You can specify which web sites containing XForms may submit data to other domains. Type the exact address of the site you want to allow and then press Allow.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче