--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -107,22 +107,25 @@
#include "mozilla/Preferences.h"
#include "mozilla/MathAlgorithms.h"
#include "nsIIDNService.h"
#include <limits>
#include "nsIColorPicker.h"
+#include "nsIDatePicker.h"
#include "nsIStringEnumerator.h"
#include "HTMLSplitOnSpacesTokenizer.h"
#include "nsIController.h"
#include "nsIMIMEInfo.h"
#include "nsFrameSelection.h"
+#include "nsIConsoleService.h"
+
// input type=date
#include "js/Date.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
// XXX align=left, hspace, vspace, border? other nav4 attrs
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
@@ -933,16 +936,23 @@ GetDOMFileOrDirectoryPath(const OwningFi
} else {
MOZ_ASSERT(aData.IsDirectory());
aData.GetAsDirectory()->GetFullRealPath(aPath);
}
}
} // namespace
+/* static */
+bool
+HTMLInputElement::ValueAsDateEnabled(JSContext* cx, JSObject* obj)
+{
+ return Preferences::GetBool("dom.experimental_forms", false) ||
+ Preferences::GetBool("dom.forms.datepicker", false);
+}
NS_IMETHODIMP
HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
{
mInput->PickerClosed();
if (aResult == nsIFilePicker::returnCancel) {
return NS_OK;
@@ -1136,16 +1146,69 @@ nsColorPickerShownCallback::Done(const n
false);
}
return rv;
}
NS_IMPL_ISUPPORTS(nsColorPickerShownCallback, nsIColorPickerShownCallback)
+class DatePickerShownCallback final : public nsIDatePickerShownCallback
+{
+ ~DatePickerShownCallback() {}
+public:
+ DatePickerShownCallback(HTMLInputElement* aInput,
+ nsIDatePicker* aDatePicker)
+ : mInput(aInput)
+ , mDatePicker(aDatePicker)
+ {}
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Done(const nsAString& aDate) override;
+ NS_IMETHOD Cancel() override;
+
+private:
+ RefPtr<HTMLInputElement> mInput;
+ nsCOMPtr<nsIDatePicker> mDatePicker;
+};
+
+NS_IMETHODIMP
+DatePickerShownCallback::Cancel()
+{
+ mInput->PickerClosed();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DatePickerShownCallback::Done(const nsAString& aDate)
+{
+ nsAutoString oldValue;
+
+ mInput->PickerClosed();
+ mInput->GetValue(oldValue);
+
+ if(!oldValue.Equals(aDate)){
+ mInput->SetValue(aDate);
+ nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
+ static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
+ NS_LITERAL_STRING("input"), true,
+ false);
+ return nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
+ static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
+ NS_LITERAL_STRING("change"), true,
+ false);
+ }
+
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(DatePickerShownCallback, nsIDatePickerShownCallback)
+
+
bool
HTMLInputElement::IsPopupBlocked() const
{
nsCOMPtr<nsPIDOMWindowOuter> win = OwnerDoc()->GetWindow();
MOZ_ASSERT(win, "window should not be null");
if (!win) {
return true;
}
@@ -1161,16 +1224,66 @@ HTMLInputElement::IsPopupBlocked() const
}
uint32_t permission;
pm->TestPermission(OwnerDoc()->NodePrincipal(), &permission);
return permission == nsIPopupWindowManager::DENY_POPUP;
}
nsresult
+HTMLInputElement::InitDatePicker()
+{
+ if (!Preferences::GetBool("dom.forms.datepicker", false)) {
+ return NS_OK;
+ }
+
+ if (mPickerRunning) {
+ NS_WARNING("Just one nsIDatePicker is allowed");
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIDocument> doc = OwnerDoc();
+
+ nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
+ if (!win) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (IsPopupBlocked()) {
+ win->FirePopupBlockedEvent(doc, nullptr, EmptyString(), EmptyString());
+ return NS_OK;
+ }
+
+ // Get Loc title
+ nsXPIDLString title;
+ nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "DatePicker", title);
+
+ nsresult rv;
+ nsCOMPtr<nsIDatePicker> datePicker = do_CreateInstance("@mozilla.org/datepicker;1", &rv);
+ if (!datePicker) {
+ return rv;
+ }
+
+ nsAutoString initialValue;
+ GetValueInternal(initialValue);
+ rv = datePicker->Init(win, title, initialValue);
+
+ nsCOMPtr<nsIDatePickerShownCallback> callback =
+ new DatePickerShownCallback(this, datePicker);
+
+ rv = datePicker->Open(callback);
+ if (NS_SUCCEEDED(rv)) {
+ mPickerRunning = true;
+ }
+
+ return rv;
+}
+
+nsresult
HTMLInputElement::InitColorPicker()
{
if (mPickerRunning) {
NS_WARNING("Just one nsIColorPicker is allowed");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc = OwnerDoc();
@@ -2015,17 +2128,18 @@ NS_IMETHODIMP
HTMLInputElement::GetValue(nsAString& aValue)
{
nsresult rv = GetValueInternal(aValue);
if (NS_FAILED(rv)) {
return rv;
}
// Don't return non-sanitized value for types that are experimental on mobile.
- if (IsExperimentalMobileType(mType)) {
+ // or date types
+ if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
SanitizeValue(aValue);
}
return NS_OK;
}
nsresult
HTMLInputElement::GetValueInternal(nsAString& aValue) const
@@ -2649,16 +2763,25 @@ HTMLInputElement::ApplyStep(int32_t aSte
if (NS_SUCCEEDED(rv) && nextStep.isFinite()) {
SetValue(nextStep);
}
return rv;
}
+/* static */
+bool
+HTMLInputElement::IsExperimentalMobileType(uint8_t aType)
+{
+ return aType == NS_FORM_INPUT_TIME ||
+ (aType == NS_FORM_INPUT_DATE &&
+ !Preferences::GetBool("dom.forms.datepicker", false));
+}
+
NS_IMETHODIMP
HTMLInputElement::StepDown(int32_t n, uint8_t optional_argc)
{
return ApplyStep(optional_argc ? -n : -1);
}
NS_IMETHODIMP
HTMLInputElement::StepUp(int32_t n, uint8_t optional_argc)
@@ -2838,17 +2961,17 @@ HTMLInputElement::MozSetDirectory(const
SetFilesOrDirectories(array, true);
}
bool
HTMLInputElement::MozIsTextField(bool aExcludePassword)
{
// TODO: temporary until bug 773205 is fixed.
- if (IsExperimentalMobileType(mType)) {
+ if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
return false;
}
return IsSingleLineTextControl(aExcludePassword);
}
HTMLInputElement*
HTMLInputElement::GetOwnerNumberControl()
@@ -3870,17 +3993,17 @@ HTMLInputElement::PreHandleEvent(EventCh
GetValue(mFocusedValue);
}
// Fire onchange (if necessary), before we do the blur, bug 357684.
if (aVisitor.mEvent->mMessage == eBlur) {
// Experimental mobile types rely on the system UI to prevent users to not
// set invalid values but we have to be extra-careful. Especially if the
// option has been enabled on desktop.
- if (IsExperimentalMobileType(mType)) {
+ if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
nsAutoString aValue;
GetValueInternal(aValue);
nsresult rv =
SetValueInternal(aValue, nsTextEditorState::eSetValue_Internal);
NS_ENSURE_SUCCESS(rv, rv);
}
FireChangeEventIfNeeded();
}
@@ -4286,16 +4409,20 @@ HTMLInputElement::MaybeInitPickers(Event
"be reached");
type = FILE_PICKER_DIRECTORY;
}
return InitFilePicker(type);
}
if (mType == NS_FORM_INPUT_COLOR) {
return InitColorPicker();
}
+ if (mType == NS_FORM_INPUT_DATE) {
+ return InitDatePicker();
+ }
+
return NS_OK;
}
nsresult
HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
{
if (!aVisitor.mPresContext) {
// Hack alert! In order to open file picker even in case the element isn't
@@ -4567,17 +4694,18 @@ HTMLInputElement::PostHandleEvent(EventC
* (c) if there is more than one text input and no submit buttons, do
* not submit, period.
*/
if (aVisitor.mEvent->mMessage == eKeyPress &&
keyEvent->mKeyCode == NS_VK_RETURN &&
(IsSingleLineTextControl(false, mType) ||
mType == NS_FORM_INPUT_NUMBER ||
- IsExperimentalMobileType(mType))) {
+ IsExperimentalMobileType(mType) ||
+ mType == NS_FORM_INPUT_DATE)) {
FireChangeEventIfNeeded();
rv = MaybeSubmitForm(aVisitor.mPresContext);
NS_ENSURE_SUCCESS(rv, rv);
}
if (aVisitor.mEvent->mMessage == eKeyPress &&
mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() &&
!keyEvent->IsControl() && !keyEvent->IsMeta() &&
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -265,16 +265,19 @@ public:
nsGenericHTMLFormElementWithState)
static UploadLastDir* gUploadLastDir;
// create and destroy the static UploadLastDir object for remembering
// which directory was last used on a site-by-site basis
static void InitUploadLastDir();
static void DestroyUploadLastDir();
+ //If the valueAsDate attribute should be enabled in webIDL
+ static bool ValueAsDateEnabled(JSContext* cx, JSObject* obj);
+
void MaybeLoadImage();
void SetSelectionProperties(const nsTextEditorState::SelectionProperties& aProps)
{
MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER);
mSelectionCached = true;
mSelectionProperties = aProps;
}
@@ -1241,20 +1244,17 @@ protected:
*
* @param aStep The value used to be multiplied against the step value.
*/
nsresult ApplyStep(int32_t aStep);
/**
* Returns if the current type is an experimental mobile type.
*/
- static bool IsExperimentalMobileType(uint8_t aType)
- {
- return aType == NS_FORM_INPUT_DATE || aType == NS_FORM_INPUT_TIME;
- }
+ static bool IsExperimentalMobileType(uint8_t aType);
/**
* Flushes the layout frame tree to make sure we have up-to-date frames.
*/
void FlushFrames();
/**
* Returns true if the element should prevent dispatching another DOMActivate.
@@ -1271,16 +1271,17 @@ protected:
nsresult MaybeInitPickers(EventChainPostVisitor& aVisitor);
enum FilePickerType {
FILE_PICKER_FILE,
FILE_PICKER_DIRECTORY
};
nsresult InitFilePicker(FilePickerType aType);
nsresult InitColorPicker();
+ nsresult InitDatePicker();
/**
* Use this function before trying to open a picker.
* It checks if the page is allowed to open a new pop-up.
* If it returns true, you should not create the picker.
*
* @return true if popup should be blocked, false otherwise
*/
--- a/dom/html/test/forms/test_experimental_forms_pref.html
+++ b/dom/html/test/forms/test_experimental_forms_pref.html
@@ -15,29 +15,37 @@ https://bugzilla.mozilla.org/show_bug.cg
<div id="content" style="display: none" >
</div>
<pre id="test">
<script type="application/javascript">
var input = document.createElement("input");
SimpleTest.waitForExplicitFinish();
- SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", false]]}, function() {
+ SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", false], ["dom.forms.datepicker",false]]}, function() {
input.type = "date";
is(input.type, "text", "input type shouldn't be date when the experimental forms are disabled");
is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
- SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms",true]]}, function() {
- // Change the type of input to text and then back to date,
+ SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms",true], ["dom.forms.datepicker",false]]}, function() {
+ // Change the type of input to text and then back to date,
// so that HTMLInputElement::ParseAttribute gets called with the pref enabled.
input.type = "text";
input.type = "date";
is(input.type, "date", "input type should be date when the experimental forms are enabled");
is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
-
- SimpleTest.finish();
+
+ SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms",false], ["dom.forms.datepicker",true]]}, function() {
+ // Change the type of input to text and then back to date,
+ // so that HTMLInputElement::ParseAttribute gets called with the pref enabled.
+ input.type = "text";
+ input.type = "date";
+ is(input.type, "date", "input type should be date when the datepicker is enabled");
+ is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
+
+ SimpleTest.finish();
+ });
});
});
-
</script>
</pre>
</body>
</html>
--- a/dom/html/test/forms/test_valueAsDate_pref.html
+++ b/dom/html/test/forms/test_valueAsDate_pref.html
@@ -6,34 +6,42 @@ https://bugzilla.mozilla.org/show_bug.cg
<head>
<meta charset="utf-8">
<title>Test for Bug 874640</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 874640 **/
- var states = [ 'true', 'false', 'end' ];
- var pref = SpecialPowers.getBoolPref("dom.experimental_forms");
+ var states = [
+ //dom.experimental_forms, dom.forms.datepicker, expectedValueAsDate
+ [ 'true', 'true', 'true' ],
+ [ 'true', 'false', 'true' ],
+ [ 'false', 'true', 'true' ],
+ [ 'false', 'false', 'false' ],
+ 'end'
+ ];
SimpleTest.waitForExplicitFinish();
function runTest(iframe) {
var state = states.shift();
if (state == 'end') {
SimpleTest.finish();
return;
}
- SpecialPowers.pushPrefEnv({"set":[["dom.experimental_forms", state === 'true']]},
+ SpecialPowers.pushPrefEnv({"set":[
+ ["dom.experimental_forms", state[0] === 'true'],
+ ["dom.forms.datepicker", state[1] === 'true']]},
function() {
iframe.src = 'data:text/html,<script>' +
'parent.is("valueAsDate" in document.createElement("input"), ' +
- state + ', "valueAsDate presence state should be ' + state + '");' +
+ state[2] + ', "valueAsDate presence state should be ' + state[2] + '");' +
'<\/script>'
});
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=874640">Mozilla Bug 874640</a>
new file mode 100644
--- /dev/null
+++ b/dom/ipc/DatePickerParent.cpp
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DatePickerParent.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIDocument.h"
+#include "nsIDOMWindow.h"
+#include "mozilla/unused.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/TabParent.h"
+
+using mozilla::Unused;
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS(DatePickerParent::DatePickerShownCallback,
+ nsIDatePickerShownCallback);
+
+NS_IMETHODIMP
+DatePickerParent::DatePickerShownCallback::Cancel()
+{
+ if (mDatePickerParent) {
+ Unused << mDatePickerParent->SendCancel();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DatePickerParent::DatePickerShownCallback::Done(const nsAString& aDate)
+{
+ if (mDatePickerParent) {
+ Unused << mDatePickerParent->Send__delete__(mDatePickerParent,
+ nsString(aDate));
+ }
+ return NS_OK;
+}
+
+void
+DatePickerParent::DatePickerShownCallback::Destroy()
+{
+ mDatePickerParent = nullptr;
+}
+
+bool
+DatePickerParent::CreateDatePicker()
+{
+ mPicker = do_CreateInstance("@mozilla.org/datepicker;1");
+ if (!mPicker) {
+ return false;
+ }
+
+ Element* ownerElement = TabParent::GetFrom(Manager())->GetOwnerElement();
+ if (!ownerElement) {
+ return false;
+ }
+
+ nsCOMPtr<mozIDOMWindowProxy> window = do_QueryInterface(ownerElement->OwnerDoc()->GetWindow());
+ if (!window) {
+ return false;
+ }
+
+ return NS_SUCCEEDED(mPicker->Init(window, mTitle, mInitialDate));
+}
+
+bool
+DatePickerParent::RecvOpen()
+{
+ if (!CreateDatePicker()) {
+ Unused << Send__delete__(this, mInitialDate);
+ return true;
+ }
+
+ mCallback = new DatePickerShownCallback(this);
+
+ mPicker->Open(mCallback);
+ return true;
+};
+
+void
+DatePickerParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+ if (mCallback) {
+ mCallback->Destroy();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/DatePickerParent.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_DatePickerParent_h
+#define mozilla_dom_DatePickerParent_h
+
+#include "mozilla/dom/PDatePickerParent.h"
+#include "nsIDatePicker.h"
+
+namespace mozilla {
+namespace dom {
+
+class DatePickerParent : public PDatePickerParent
+{
+ public:
+ DatePickerParent(const nsString& aTitle,
+ const nsString& aInitialDate)
+ : mTitle(aTitle)
+ , mInitialDate(aInitialDate)
+ {}
+
+ virtual bool RecvOpen() override;
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ class DatePickerShownCallback final
+ : public nsIDatePickerShownCallback
+ {
+ public:
+ explicit DatePickerShownCallback(DatePickerParent* aDatePickerParnet)
+ : mDatePickerParent(aDatePickerParnet)
+ {}
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDATEPICKERSHOWNCALLBACK
+
+ void Destroy();
+
+ private:
+ ~DatePickerShownCallback() {}
+ DatePickerParent* mDatePickerParent;
+ };
+
+ private:
+ virtual ~DatePickerParent() {}
+
+ bool CreateDatePicker();
+
+ RefPtr<DatePickerShownCallback> mCallback;
+ nsCOMPtr<nsIDatePicker> mPicker;
+
+ nsString mTitle;
+ nsString mInitialDate;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_DatePickerParent_h
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -4,16 +4,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBlob;
include protocol PColorPicker;
include protocol PContent;
include protocol PContentBridge;
+include protocol PDatePicker;
include protocol PDocAccessible;
include protocol PDocumentRenderer;
include protocol PFilePicker;
include protocol PIndexedDBPermissionRequest;
include protocol PRenderFrame;
include protocol PPluginWidget;
include protocol PRemotePrintJob;
include DOMTypes;
@@ -106,16 +107,17 @@ union OptionalShmem
Shmem;
};
prio(normal upto urgent) sync protocol PBrowser
{
manager PContent or PContentBridge;
manages PColorPicker;
+ manages PDatePicker;
manages PDocAccessible;
manages PDocumentRenderer;
manages PFilePicker;
manages PIndexedDBPermissionRequest;
manages PRenderFrame;
manages PPluginWidget;
both:
@@ -415,16 +417,22 @@ parent:
async HideTooltip();
/**
* Create an asynchronous color picker on the parent side,
* but don't open it yet.
*/
async PColorPicker(nsString title, nsString initialColor);
+ /**
+ * Create an asynchronous date picker on the parent side,
+ * but don't open it yet.
+ */
+ async PDatePicker(nsString title, nsString initialDate);
+
async PFilePicker(nsString aTitle, int16_t aMode);
/**
* Initiates an asynchronous request for one of the special indexedDB
* permissions for the provided principal.
*
* @param principal
* The principal of the request.
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PDatePicker.ipdl
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PBrowser;
+
+namespace mozilla {
+namespace dom {
+
+protocol PDatePicker
+{
+ manager PBrowser;
+
+parent:
+ async Open();
+
+child:
+ async Cancel();
+
+ async __delete__(nsString color);
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -97,16 +97,17 @@
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/gfx/Matrix.h"
#include "UnitTransforms.h"
#include "ClientLayerManager.h"
#include "LayersLogging.h"
#include "nsIOService.h"
#include "nsDOMClassInfoID.h"
#include "nsColorPickerProxy.h"
+#include "nsDatePickerProxy.h"
#include "nsContentPermissionHelper.h"
#include "nsPresShell.h"
#include "nsIAppsService.h"
#include "nsNetUtil.h"
#include "nsIPermissionManager.h"
#include "nsIURILoader.h"
#include "nsIScriptError.h"
#include "mozilla/EventForwards.h"
@@ -2279,16 +2280,31 @@ TabChild::AllocPColorPickerChild(const n
bool
TabChild::DeallocPColorPickerChild(PColorPickerChild* aColorPicker)
{
nsColorPickerProxy* picker = static_cast<nsColorPickerProxy*>(aColorPicker);
NS_RELEASE(picker);
return true;
}
+PDatePickerChild*
+TabChild::AllocPDatePickerChild(const nsString&, const nsString&)
+{
+ NS_RUNTIMEABORT("unused");
+ return nullptr;
+}
+
+bool
+TabChild::DeallocPDatePickerChild(PDatePickerChild* aDatePicker)
+{
+ nsDatePickerProxy* picker = static_cast<nsDatePickerProxy*>(aDatePicker);
+ NS_RELEASE(picker);
+ return true;
+}
+
PFilePickerChild*
TabChild::AllocPFilePickerChild(const nsString&, const int16_t&)
{
NS_RUNTIMEABORT("unused");
return nullptr;
}
bool
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -448,16 +448,20 @@ public:
virtual PColorPickerChild*
AllocPColorPickerChild(const nsString& aTitle,
const nsString& aInitialColor) override;
virtual bool DeallocPColorPickerChild(PColorPickerChild* aActor) override;
+ virtual PDatePickerChild*
+ AllocPDatePickerChild(const nsString& title, const nsString& initialDate) override;
+ virtual bool DeallocPDatePickerChild(PDatePickerChild* actor) override;
+
virtual PFilePickerChild*
AllocPFilePickerChild(const nsString& aTitle, const int16_t& aMode) override;
virtual bool
DeallocPFilePickerChild(PFilePickerChild* aActor) override;
virtual PIndexedDBPermissionRequestChild*
AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal) override;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -75,16 +75,17 @@
#include "nsPresShell.h"
#include "nsPrintfCString.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "private/pprio.h"
#include "PermissionMessageUtils.h"
#include "StructuredCloneData.h"
#include "ColorPickerParent.h"
+#include "DatePickerParent.h"
#include "FilePickerParent.h"
#include "TabChild.h"
#include "LoadContext.h"
#include "nsNetCID.h"
#include "nsIAuthInformation.h"
#include "nsIAuthPromptCallback.h"
#include "nsAuthInformationHolder.h"
#include "nsICancelable.h"
@@ -2582,16 +2583,30 @@ TabParent::AllocPColorPickerParent(const
bool
TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
{
delete actor;
return true;
}
+PDatePickerParent*
+TabParent::AllocPDatePickerParent(const nsString& aTitle,
+ const nsString& aInitialDate)
+{
+ return new DatePickerParent(aTitle, aInitialDate);
+}
+
+bool
+TabParent::DeallocPDatePickerParent(PDatePickerParent* actor)
+{
+ delete actor;
+ return true;
+}
+
PRenderFrameParent*
TabParent::AllocPRenderFrameParent()
{
MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
uint64_t layersId = 0;
bool success = false;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -374,16 +374,20 @@ public:
virtual PColorPickerParent*
AllocPColorPickerParent(const nsString& aTitle,
const nsString& aInitialColor) override;
virtual bool
DeallocPColorPickerParent(PColorPickerParent* aColorPicker) override;
+ virtual PDatePickerParent*
+ AllocPDatePickerParent(const nsString& aTitle, const nsString& aInitialDate) override;
+ virtual bool DeallocPDatePickerParent(PDatePickerParent* aDatePicker) override;
+
virtual PDocAccessibleParent*
AllocPDocAccessibleParent(PDocAccessibleParent*, const uint64_t&) override;
virtual bool DeallocPDocAccessibleParent(PDocAccessibleParent*) override;
virtual bool
RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
PDocAccessibleParent* aParentDoc,
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -56,16 +56,17 @@ UNIFIED_SOURCES += [
'AppProcessChecker.cpp',
'ColorPickerParent.cpp',
'ContentBridgeChild.cpp',
'ContentBridgeParent.cpp',
'ContentParent.cpp',
'ContentProcess.cpp',
'ContentProcessManager.cpp',
'CrashReporterParent.cpp',
+ 'DatePickerParent.cpp',
'FilePickerParent.cpp',
'nsIContentChild.cpp',
'nsIContentParent.cpp',
'NuwaChild.cpp',
'NuwaParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
@@ -97,16 +98,17 @@ IPDL_SOURCES += [
'PBrowserOrId.ipdlh',
'PColorPicker.ipdl',
'PContent.ipdl',
'PContentBridge.ipdl',
'PContentPermission.ipdlh',
'PContentPermissionRequest.ipdl',
'PCrashReporter.ipdl',
'PCycleCollectWithLogs.ipdl',
+ 'PDatePicker.ipdl',
'PDocumentRenderer.ipdl',
'PFilePicker.ipdl',
'PMemoryReportRequest.ipdl',
'PNuwa.ipdl',
'PPluginWidget.ipdl',
'PProcessHangMonitor.ipdl',
'PScreenManager.ipdl',
'PTabContext.ipdlh',
--- a/dom/locales/en-US/chrome/layout/HtmlForm.properties
+++ b/dom/locales/en-US/chrome/layout/HtmlForm.properties
@@ -25,16 +25,17 @@ NoFileSelected=No file selected.
# LOCALIZATION NOTE (NoFilesSelected): this string is shown on a
# <input type='file' multiple> when there is no file selected yet.
NoFilesSelected=No files selected.
# LOCALIZATION NOTE (XFilesSelected): this string is shown on a
# <input type='file' multiple> when there are more than one selected file.
# %S will be a number greater or equal to 2.
XFilesSelected=%S files selected.
ColorPicker=Choose a color
+DatePicker=Choose a date
# LOCALIZATION NOTE (AndNMoreFiles): Semi-colon list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# This string is shown at the end of the tooltip text for <input type='file'
# multiple> when there are more than 21 files selected (when we will only list
# the first 20, plus an "and X more" line). #1 represents the number of files
# minus 20 and will always be a number equal to or greater than 2. So the
# singular case will never be used.
AndNMoreFiles=and one more;and #1 more
--- a/dom/webidl/HTMLInputElement.webidl
+++ b/dom/webidl/HTMLInputElement.webidl
@@ -83,17 +83,17 @@ interface HTMLInputElement : HTMLElement
[Pure, SetterThrows]
attribute DOMString step;
[Pure, SetterThrows]
attribute DOMString type;
[Pure, SetterThrows]
attribute DOMString defaultValue;
[Pure, TreatNullAs=EmptyString, Throws]
attribute DOMString value;
- [Throws, Pref="dom.experimental_forms"]
+ [Throws, Func="HTMLInputElement::ValueAsDateEnabled"]
attribute Date? valueAsDate;
[Pure, SetterThrows]
attribute unrestricted double valueAsNumber;
attribute unsigned long width;
[Throws]
void stepUp(optional long n = 1);
[Throws]
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -60,16 +60,17 @@ XPIDL_SOURCES += [
'nsIBaseWindow.idl',
'nsIBidiKeyboard.idl',
'nsIClipboard.idl',
'nsIClipboardDragDropHookList.idl',
'nsIClipboardDragDropHooks.idl',
'nsIClipboardHelper.idl',
'nsIClipboardOwner.idl',
'nsIColorPicker.idl',
+ 'nsIDatePicker.idl',
'nsIDisplayInfo.idl',
'nsIDragService.idl',
'nsIDragSession.idl',
'nsIFilePicker.idl',
'nsIFormatConverter.idl',
'nsIGfxInfo.idl',
'nsIGfxInfoDebug.idl',
'nsIIdleService.idl',
@@ -142,16 +143,17 @@ UNIFIED_SOURCES += [
'GfxInfoWebGL.cpp',
'InputData.cpp',
'nsBaseAppShell.cpp',
'nsBaseScreen.cpp',
'nsClipboardHelper.cpp',
'nsClipboardProxy.cpp',
'nsColorPickerProxy.cpp',
'nsContentProcessWidgetFactory.cpp',
+ 'nsDatePickerProxy.cpp',
'nsDragServiceProxy.cpp',
'nsFilePickerProxy.cpp',
'nsHTMLFormatConverter.cpp',
'nsIdleService.cpp',
'nsIWidgetListener.cpp',
'nsPrimitiveHelpers.cpp',
'nsPrintSettingsImpl.cpp',
'nsScreenManagerProxy.cpp',
--- a/widget/nsContentProcessWidgetFactory.cpp
+++ b/widget/nsContentProcessWidgetFactory.cpp
@@ -4,59 +4,65 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ModuleUtils.h"
#include "nsWidgetsCID.h"
#include "nsClipboardProxy.h"
#include "nsColorPickerProxy.h"
+#include "nsDatePickerProxy.h"
#include "nsDragServiceProxy.h"
#include "nsFilePickerProxy.h"
#include "nsScreenManagerProxy.h"
#include "mozilla/widget/PuppetBidiKeyboard.h"
using namespace mozilla;
using namespace mozilla::widget;
#ifndef MOZ_WIDGET_GONK
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPickerProxy)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsDatePickerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragServiceProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePickerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(PuppetBidiKeyboard)
NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
+NS_DEFINE_NAMED_CID(NS_DATEPICKER_CID);
NS_DEFINE_NAMED_CID(NS_DRAGSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
NS_DEFINE_NAMED_CID(PUPPETBIDIKEYBOARD_CID);
NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kNS_COLORPICKER_CID, false, nullptr, nsColorPickerProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
+ { &kNS_DATEPICKER_CID, false, nullptr, nsDatePickerProxyConstructor,
+ Module::CONTENT_PROCESS_ONLY },
{ &kNS_DRAGSERVICE_CID, false, nullptr, nsDragServiceProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kPUPPETBIDIKEYBOARD_CID, false, NULL, PuppetBidiKeyboardConstructor,
mozilla::Module::CONTENT_PROCESS_ONLY },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
{ "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::CONTENT_PROCESS_ONLY },
+ { "@mozilla.org/datepicker;1", &kNS_DATEPICKER_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/widget/bidikeyboard;1", &kPUPPETBIDIKEYBOARD_CID,
Module::CONTENT_PROCESS_ONLY },
{ nullptr }
};
new file mode 100644
--- /dev/null
+++ b/widget/nsDatePickerProxy.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsDatePickerProxy.h"
+
+#include "mozilla/dom/TabChild.h"
+
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS(nsDatePickerProxy, nsIDatePicker)
+
+/* void init (in nsIDOMWindow parent, in AString title, in short mode); */
+NS_IMETHODIMP
+nsDatePickerProxy::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
+ const nsAString& aInitialDate)
+{
+ TabChild* tabChild = TabChild::GetFrom(aParent);
+ if (!tabChild) {
+ return NS_ERROR_FAILURE;
+ }
+
+ tabChild->SendPDatePickerConstructor(this,
+ nsString(aTitle),
+ nsString(aInitialDate));
+ NS_ADDREF_THIS(); //Released in DeallocPDatePickerChild
+ return NS_OK;
+}
+
+/* void open (in nsIDatePickerShownCallback aDatePickerShownCallback); */
+NS_IMETHODIMP
+nsDatePickerProxy::Open(nsIDatePickerShownCallback* aDatePickerShownCallback)
+{
+ NS_ENSURE_STATE(!mCallback);
+ mCallback = aDatePickerShownCallback;
+
+ SendOpen();
+ return NS_OK;
+}
+
+bool
+nsDatePickerProxy::RecvCancel()
+{
+ if (mCallback) {
+ mCallback->Cancel();
+ mCallback = nullptr;
+ }
+ return true;
+}
+
+bool
+nsDatePickerProxy::Recv__delete__(const nsString& aDate)
+{
+ if (mCallback) {
+ mCallback->Done(aDate);
+ mCallback = nullptr;
+ }
+ return true;
+}
new file mode 100644
--- /dev/null
+++ b/widget/nsDatePickerProxy.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsDatePickerProxy_h
+#define nsDatePickerProxy_h
+
+#include "nsIDatePicker.h"
+
+#include "mozilla/dom/PDatePickerChild.h"
+
+class nsDatePickerProxy final : public nsIDatePicker,
+ public mozilla::dom::PDatePickerChild
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDATEPICKER
+
+ nsDatePickerProxy() {}
+
+ virtual bool RecvCancel() override;
+ virtual bool Recv__delete__(const nsString& aDate) override;
+
+private:
+ ~nsDatePickerProxy() {}
+
+ nsCOMPtr<nsIDatePickerShownCallback> mCallback;
+ nsString mTitle;
+ nsString mInitialDate;
+};
+
+#endif // nsDatePickerProxy_h
new file mode 100644
--- /dev/null
+++ b/widget/nsIDatePicker.idl
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface mozIDOMWindowProxy;
+
+[scriptable, uuid(13388a28-1b0b-4218-a31b-588f7a4ec26c)]
+interface nsIDatePickerShownCallback : nsISupports
+{
+ /**
+ * Callback called when the user selects cancel in the date picker
+ * This callback can not be called after done() is called.
+ */
+ void cancel();
+
+ /**
+ * Callback called when the user has finished selecting the date
+ *
+ * @param date The new selected date value following the format "YYYY-MM-DD"
+ */
+ void done(in AString date);
+};
+
+[scriptable, uuid(7becfc64-966b-4d53-87d2-9161f36bd3b3)]
+interface nsIDatePicker : nsISupports
+{
+ /**
+ * Initialize the date picker widget. The date picker will not be shown until
+ * open() is called.
+ * If the initialDate parameter does not follow the format "YYYY-MM-DD" then
+ * the behavior will be unspecified.
+ *
+ * @param parent nsIDOMWindow parent. This dialog will be dependent
+ * on this parent. parent may be null.
+ * @param title The title for the date picker widget.
+ * @param initialDate The date to show when the widget is opened. The
+ * parameter has to follow the format "YYYY-MM-DD"
+ */
+ void init(in mozIDOMWindowProxy parent, in AString title, in AString initialDate);
+
+ /**
+ * Opens the date dialog asynchrounously.
+ * The results are provided via the callback object.
+ */
+ void open(in nsIDatePickerShownCallback callback);
+};
--- a/widget/nsWidgetsCID.h
+++ b/widget/nsWidgetsCID.h
@@ -28,16 +28,21 @@
{ 0xe221df9b, 0x3d66, 0x4045, \
{0x9a, 0x66, 0x57, 0x20, 0x94, 0x9f, 0x8d, 0x10} }
/* 0f872c8c-3ee6-46bd-92a2-69652c6b474e */
#define NS_COLORPICKER_CID \
{ 0x0f872c8c, 0x3ee6, 0x46bd, \
{ 0x92, 0xa2, 0x69, 0x65, 0x2c, 0x6b, 0x47, 0x4e } }
+/* 0ca832f8-978a-4dc7-a57d-adb803925d39 */
+#define NS_DATEPICKER_CID \
+{ 0x0ca832f8, 0x978a, 0x4dc7, \
+ { 0xa5, 0x7d, 0xad, 0xb8, 0x03, 0x92, 0x5d, 0x39 } }
+
/* 2d96b3df-c051-11d1-a827-0040959a28c9 */
#define NS_APPSHELL_CID \
{ 0x2d96b3df, 0xc051, 0x11d1, \
{0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9} }
/* 2d96b3e0-c051-11d1-a827-0040959a28c9 */
#define NS_TOOLKIT_CID \
{ 0x2d96b3e0, 0xc051, 0x11d1, \