diff options
Diffstat (limited to 'dom/html')
-rw-r--r-- | dom/html/HTMLInputElement.cpp | 185 | ||||
-rw-r--r-- | dom/html/HTMLInputElement.h | 66 | ||||
-rw-r--r-- | dom/html/test/forms/mochitest.ini | 2 | ||||
-rw-r--r-- | dom/html/test/forms/test_input_date_key_events.html | 8 | ||||
-rw-r--r-- | dom/html/test/forms/test_input_datetime_input_change_events.html | 88 |
5 files changed, 306 insertions, 43 deletions
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index e8a4af454..62f194493 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -543,9 +543,8 @@ GetDOMFileOrDirectoryPath(const OwningFileOrDirectory& aData, bool HTMLInputElement::ValueAsDateEnabled(JSContext* cx, JSObject* obj) { - return Preferences::GetBool("dom.experimental_forms", false) || - Preferences::GetBool("dom.forms.datepicker", false) || - Preferences::GetBool("dom.forms.datetime", false); + return IsExperimentalFormsEnabled() || IsDatePickerEnabled() || + IsInputDateTimeEnabled(); } NS_IMETHODIMP @@ -628,7 +627,7 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult) RefPtr<DispatchChangeEventCallback> dispatchChangeEventCallback = new DispatchChangeEventCallback(mInput); - if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) && + if (IsWebkitDirPickerEnabled() && mInput->HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) { ErrorResult error; GetFilesHelper* helper = mInput->GetOrCreateGetFilesHelper(true, error); @@ -827,7 +826,7 @@ HTMLInputElement::IsPopupBlocked() const nsresult HTMLInputElement::InitDatePicker() { - if (!Preferences::GetBool("dom.forms.datepicker", false)) { + if (!IsDatePickerEnabled()) { return NS_OK; } @@ -2516,10 +2515,8 @@ bool HTMLInputElement::IsExperimentalMobileType(uint8_t aType) { return (aType == NS_FORM_INPUT_DATE && - !Preferences::GetBool("dom.forms.datetime", false) && - !Preferences::GetBool("dom.forms.datepicker", false)) || - (aType == NS_FORM_INPUT_TIME && - !Preferences::GetBool("dom.forms.datetime", false)); + !IsInputDateTimeEnabled() && !IsDatePickerEnabled()) || + (aType == NS_FORM_INPUT_TIME && !IsInputDateTimeEnabled()); } bool @@ -3025,8 +3022,8 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const nsXPIDLString value; if (mFilesOrDirectories.IsEmpty()) { - if ((Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs()) || - (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) && + if ((IsDirPickerEnabled() && Allowdirs()) || + (IsWebkitDirPickerEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) { nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES, "NoDirSelected", value); @@ -3055,7 +3052,7 @@ HTMLInputElement::SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& a { ClearGetFilesHelpers(); - if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) { + if (IsWebkitFileSystemEnabled()) { HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this); mEntries.Clear(); } @@ -3074,7 +3071,7 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles, mFilesOrDirectories.Clear(); ClearGetFilesHelpers(); - if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) { + if (IsWebkitFileSystemEnabled()) { HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this); mEntries.Clear(); } @@ -3097,14 +3094,14 @@ HTMLInputElement::MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirect { SetFilesOrDirectories(aFilesOrDirectories, true); - if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) { + if (IsWebkitFileSystemEnabled()) { UpdateEntries(aFilesOrDirectories); } RefPtr<DispatchChangeEventCallback> dispatchChangeEventCallback = new DispatchChangeEventCallback(this); - if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) && + if (IsWebkitDirPickerEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) { ErrorResult rv; GetFilesHelper* helper = GetOrCreateGetFilesHelper(true /* recursionFlag */, @@ -3182,8 +3179,8 @@ HTMLInputElement::GetFiles() return nullptr; } - if (Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs() && - (!Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) || + if (IsDirPickerEnabled() && Allowdirs() && + (!IsWebkitDirPickerEnabled() || !HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) { return nullptr; } @@ -4366,8 +4363,8 @@ HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor) do_QueryInterface(aVisitor.mEvent->mOriginalTarget); if (target && target->FindFirstNonChromeOnlyAccessContent() == this && - ((Preferences::GetBool("dom.input.dirpicker", false) && Allowdirs()) || - (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) && + ((IsDirPickerEnabled() && Allowdirs()) || + (IsWebkitDirPickerEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)))) { type = FILE_PICKER_DIRECTORY; } @@ -5735,20 +5732,133 @@ HTMLInputElement::ParseTime(const nsAString& aValue, uint32_t* aResult) return true; } -static bool -IsDateTimeEnabled(int32_t aNewType) +/* static */ bool +HTMLInputElement::IsDateTimeTypeSupported(uint8_t aDateTimeInputType) +{ + return (aDateTimeInputType == NS_FORM_INPUT_DATE && + (IsInputDateTimeEnabled() || IsExperimentalFormsEnabled() || + IsDatePickerEnabled())) || + (aDateTimeInputType == NS_FORM_INPUT_TIME && + (IsInputDateTimeEnabled() || IsExperimentalFormsEnabled())) || + ((aDateTimeInputType == NS_FORM_INPUT_MONTH || + aDateTimeInputType == NS_FORM_INPUT_WEEK || + aDateTimeInputType == NS_FORM_INPUT_DATETIME_LOCAL) && + IsInputDateTimeEnabled()); +} + +/* static */ bool +HTMLInputElement::IsWebkitDirPickerEnabled() +{ + static bool sWebkitDirPickerEnabled = false; + static bool sWebkitDirPickerPrefCached = false; + if (!sWebkitDirPickerPrefCached) { + sWebkitDirPickerPrefCached = true; + Preferences::AddBoolVarCache(&sWebkitDirPickerEnabled, + "dom.webkitBlink.dirPicker.enabled", + false); + } + + return sWebkitDirPickerEnabled; +} + +/* static */ bool +HTMLInputElement::IsWebkitFileSystemEnabled() +{ + static bool sWebkitFileSystemEnabled = false; + static bool sWebkitFileSystemPrefCached = false; + if (!sWebkitFileSystemPrefCached) { + sWebkitFileSystemPrefCached = true; + Preferences::AddBoolVarCache(&sWebkitFileSystemEnabled, + "dom.webkitBlink.filesystem.enabled", + false); + } + + return sWebkitFileSystemEnabled; +} + +/* static */ bool +HTMLInputElement::IsDirPickerEnabled() +{ + static bool sDirPickerEnabled = false; + static bool sDirPickerPrefCached = false; + if (!sDirPickerPrefCached) { + sDirPickerPrefCached = true; + Preferences::AddBoolVarCache(&sDirPickerEnabled, "dom.input.dirpicker", + false); + } + + return sDirPickerEnabled; +} + +/* static */ bool +HTMLInputElement::IsDatePickerEnabled() +{ + static bool sDatePickerEnabled = false; + static bool sDatePickerPrefCached = false; + if (!sDatePickerPrefCached) { + sDatePickerPrefCached = true; + Preferences::AddBoolVarCache(&sDatePickerEnabled, "dom.forms.datepicker", + false); + } + + return sDatePickerEnabled; +} + +/* static */ bool +HTMLInputElement::IsExperimentalFormsEnabled() { - return (aNewType == NS_FORM_INPUT_DATE && - (Preferences::GetBool("dom.forms.datetime", false) || - Preferences::GetBool("dom.experimental_forms", false) || - Preferences::GetBool("dom.forms.datepicker", false))) || - (aNewType == NS_FORM_INPUT_TIME && - (Preferences::GetBool("dom.forms.datetime", false) || - Preferences::GetBool("dom.experimental_forms", false))) || - ((aNewType == NS_FORM_INPUT_MONTH || - aNewType == NS_FORM_INPUT_WEEK || - aNewType == NS_FORM_INPUT_DATETIME_LOCAL) && - Preferences::GetBool("dom.forms.datetime", false)); + static bool sExperimentalFormsEnabled = false; + static bool sExperimentalFormsPrefCached = false; + if (!sExperimentalFormsPrefCached) { + sExperimentalFormsPrefCached = true; + Preferences::AddBoolVarCache(&sExperimentalFormsEnabled, + "dom.experimental_forms", + false); + } + + return sExperimentalFormsEnabled; +} + +/* static */ bool +HTMLInputElement::IsInputDateTimeEnabled() +{ + static bool sDateTimeEnabled = false; + static bool sDateTimePrefCached = false; + if (!sDateTimePrefCached) { + sDateTimePrefCached = true; + Preferences::AddBoolVarCache(&sDateTimeEnabled, "dom.forms.datetime", + false); + } + + return sDateTimeEnabled; +} + +/* static */ bool +HTMLInputElement::IsInputNumberEnabled() +{ + static bool sInputNumberEnabled = false; + static bool sInputNumberPrefCached = false; + if (!sInputNumberPrefCached) { + sInputNumberPrefCached = true; + Preferences::AddBoolVarCache(&sInputNumberEnabled, "dom.forms.number", + false); + } + + return sInputNumberEnabled; +} + +/* static */ bool +HTMLInputElement::IsInputColorEnabled() +{ + static bool sInputColorEnabled = false; + static bool sInputColorPrefCached = false; + if (!sInputColorPrefCached) { + sInputColorPrefCached = true; + Preferences::AddBoolVarCache(&sInputColorEnabled, "dom.forms.color", + false); + } + + return sInputColorEnabled; } bool @@ -5766,12 +5876,11 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID, if (success) { newType = aResult.GetEnumValue(); if ((IsExperimentalMobileType(newType) && - !Preferences::GetBool("dom.experimental_forms", false)) || - (newType == NS_FORM_INPUT_NUMBER && - !Preferences::GetBool("dom.forms.number", false)) || - (newType == NS_FORM_INPUT_COLOR && - !Preferences::GetBool("dom.forms.color", false)) || - (IsDateTimeInputType(newType) && !IsDateTimeEnabled(newType))) { + !IsExperimentalFormsEnabled()) || + (newType == NS_FORM_INPUT_NUMBER && !IsInputNumberEnabled()) || + (newType == NS_FORM_INPUT_COLOR && !IsInputColorEnabled()) || + (IsDateTimeInputType(newType) && + !IsDateTimeTypeSupported(newType))) { newType = kInputDefaultType->value; aResult.SetTo(newType, &aValue); } diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 9ca876aee..9baaffb63 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -1632,9 +1632,73 @@ private: return IsSingleLineTextControl(false, aType) || aType == NS_FORM_INPUT_RANGE || aType == NS_FORM_INPUT_NUMBER || - aType == NS_FORM_INPUT_TIME; + aType == NS_FORM_INPUT_TIME || + aType == NS_FORM_INPUT_DATE; } + /** + * Checks if aDateTimeInputType should be supported based on "dom.forms.datetime", + * "dom.forms.datepicker" and "dom.experimental_forms". + */ + static bool + IsDateTimeTypeSupported(uint8_t aDateTimeInputType); + + /** + * Checks preference "dom.webkitBlink.dirPicker.enabled" to determine if + * webkitdirectory should be supported. + */ + static bool + IsWebkitDirPickerEnabled(); + + /** + * Checks preference "dom.webkitBlink.filesystem.enabled" to determine if + * webkitEntries should be supported. + */ + static bool + IsWebkitFileSystemEnabled(); + + /** + * Checks preference "dom.input.dirpicker" to determine if file and directory + * entries API should be supported. + */ + static bool + IsDirPickerEnabled(); + + /** + * Checks preference "dom.forms.datepicker" to determine if date picker should + * be supported. + */ + static bool + IsDatePickerEnabled(); + + /** + * Checks preference "dom.experimental_forms" to determine if experimental + * implementation of input element should be enabled. + */ + static bool + IsExperimentalFormsEnabled(); + + /** + * Checks preference "dom.forms.datetime" to determine if input date/time + * related types should be supported. + */ + static bool + IsInputDateTimeEnabled(); + + /** + * Checks preference "dom.forms.number" to determine if input type=number + * should be supported. + */ + static bool + IsInputNumberEnabled(); + + /** + * Checks preference "dom.forms.color" to determine if date/time related + * types should be supported. + */ + static bool + IsInputColorEnabled(); + struct nsFilePickerFilter { nsFilePickerFilter() : mFilterMask(0) {} diff --git a/dom/html/test/forms/mochitest.ini b/dom/html/test/forms/mochitest.ini index 6fceefd98..199e4baf8 100644 --- a/dom/html/test/forms/mochitest.ini +++ b/dom/html/test/forms/mochitest.ini @@ -32,6 +32,8 @@ skip-if = android_version == '18' # Android, bug 1147974 skip-if = android_version == '18' # Android, bug 1147974 [test_input_date_key_events.html] skip-if = os == "android" +[test_input_datetime_input_change_events.html] +skip-if = os == "android" [test_input_datetime_focus_blur.html] skip-if = os == "android" [test_input_datetime_focus_blur_events.html] diff --git a/dom/html/test/forms/test_input_date_key_events.html b/dom/html/test/forms/test_input_date_key_events.html index cd974e505..f502d6a4d 100644 --- a/dom/html/test/forms/test_input_date_key_events.html +++ b/dom/html/test/forms/test_input_date_key_events.html @@ -184,16 +184,16 @@ var testData = [ expectedVal: "2016-01-31" }, { - // Home key on year field sets it to the minimum year, which is 0001. + // Home key should have no effect on year field. keys: ["VK_TAB", "VK_TAB", "VK_HOME"], initialVal: "2016-01-01", - expectedVal: "0001-01-01" + expectedVal: "2016-01-01" }, { - // End key on year field sets it to the maximum year, which is 275760. + // End key should have no effect on year field. keys: ["VK_TAB", "VK_TAB", "VK_END"], initialVal: "2016-01-01", - expectedVal: "275760-01-01" + expectedVal: "2016-01-01" }, ]; diff --git a/dom/html/test/forms/test_input_datetime_input_change_events.html b/dom/html/test/forms/test_input_datetime_input_change_events.html new file mode 100644 index 000000000..e636995d3 --- /dev/null +++ b/dom/html/test/forms/test_input_datetime_input_change_events.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1370858 +--> +<head> +<title>Test for Bug 1370858</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1370858">Mozilla Bug 722599</a> +<p id="display"></p> +<div id="content"> +<input type="time" id="input_time" onchange="++changeEvents[0]" + oninput="++inputEvents[0]"> +<input type="date" id="input_date" onchange="++changeEvents[1]" + oninput="++inputEvents[1]"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** + * Test for Bug 1370858. + * Test that change and input events are (not) fired for date/time inputs. + **/ + +var inputTypes = ["time", "date"]; +var changeEvents = [0, 0]; +var inputEvents = [0, 0]; +var values = ["10:30", "2017-06-08"]; +var expectedValues = [["09:30", "01:30"], ["2017-05-08", "2017-01-08"]]; + +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(function() { + test(); + SimpleTest.finish(); +}); + +function test() { + for (var i = 0; i < inputTypes.length; i++) { + var input = document.getElementById("input_" + inputTypes[i]); + var inputRect = input.getBoundingClientRect(); + + // Points over the input's reset button + var resetButton_X = inputRect.width - 15; + var resetButton_Y = inputRect.height / 2; + + is(changeEvents[i], 0, "Number of change events should be 0 at start."); + is(inputEvents[i], 0, "Number of input events should be 0 at start."); + + // Test that change and input events are not dispatched setting .value by + // script. + input.value = values[i]; + is(input.value, values[i], "Check that value was set correctly (0)."); + is(changeEvents[i], 0, "Change event should not have dispatched (0)."); + is(inputEvents[i], 0, "Input event should not have dispatched (0)."); + + // Test that change and input events are fired when changing the value using + // up/down keys. + input.focus(); + synthesizeKey("VK_DOWN", {}); + is(input.value, expectedValues[i][0], "Check that value was set correctly (1)."); + is(changeEvents[i], 1, "Change event should be dispatched (1)."); + is(inputEvents[i], 1, "Input event should ne dispatched (1)."); + + // Test that change and input events are fired when changing the value with + // the keyboard. + synthesizeKey("0", {}); + synthesizeKey("1", {}); + is(input.value, expectedValues[i][1], "Check that value was set correctly (2)."); + is(changeEvents[i], 2, "Change event should be dispatched (2)."); + is(inputEvents[i], 2, "Input event should be dispatched (2)."); + + // Test that change and input events are fired when clearing the value using + // the reset button. + synthesizeMouse(input, resetButton_X, resetButton_Y, {}); + is(input.value, "", "Check that value was set correctly (3)."); + is(changeEvents[i], 3, "Change event should be dispatched (3)."); + is(inputEvents[i], 3, "Input event should be dispatched (3)."); + } +} + +</script> +</pre> +</body> +</html> |