author | Timothy Guan-tin Chien <timdream@gmail.com> |
Fri, 17 Feb 2017 17:05:27 +0800 | |
changeset 343874 | aab681ba77bff41401f2eff606b3c79837ea4e21 |
parent 343873 | 1163d72d876f94d5c6932e37af83ff6bfc91be44 |
child 343875 | fb96b7e02bb279f2336869dc7770a69007f70915 |
push id | 31390 |
push user | philringnalda@gmail.com |
push date | Tue, 21 Feb 2017 04:27:05 +0000 |
treeherder | mozilla-central@276bd9ed3dbf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug, smaug |
bugs | 1338961 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -1957,16 +1957,19 @@ GK_ATOM(ondevicelight, "ondevicelight") // Audio channel events GK_ATOM(onmozinterruptbegin, "onmozinterruptbegin") GK_ATOM(onmozinterruptend, "onmozinterruptend") // MediaDevices device change event GK_ATOM(ondevicechange, "ondevicechange") +// HTML element attributes that only exposed to XBL and chrome content +GK_ATOM(mozinputrangeignorepreventdefault, "mozinputrangeignorepreventdefault") + //--------------------------------------------------------------------------- // Special atoms //--------------------------------------------------------------------------- // Node types GK_ATOM(cdataTagName, "#cdata-section") GK_ATOM(commentTagName, "#comment") GK_ATOM(documentNodeName, "#document")
--- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -4919,17 +4919,18 @@ HTMLInputElement::PostHandleEvent(EventC return MaybeInitPickers(aVisitor); } void HTMLInputElement::PostHandleEventForRangeThumb(EventChainPostVisitor& aVisitor) { MOZ_ASSERT(mType == NS_FORM_INPUT_RANGE); - if (nsEventStatus_eConsumeNoDefault == aVisitor.mEventStatus || + if ((nsEventStatus_eConsumeNoDefault == aVisitor.mEventStatus && + !MozInputRangeIgnorePreventDefault()) || !(aVisitor.mEvent->mClass == eMouseEventClass || aVisitor.mEvent->mClass == eTouchEventClass || aVisitor.mEvent->mClass == eKeyboardEventClass)) { return; } nsRangeFrame* rangeFrame = do_QueryFrame(GetPrimaryFrame()); if (!rangeFrame && mIsDraggingRange) {
--- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -777,16 +777,22 @@ public: int32_t InputTextLength(CallerType aCallerType); void MozGetFileNameArray(nsTArray<nsString>& aFileNames, ErrorResult& aRv); void MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv); void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles); void MozSetDirectory(const nsAString& aDirectoryPath, ErrorResult& aRv); + bool MozInputRangeIgnorePreventDefault() const + { + return (IsInChromeDocument() || IsInNativeAnonymousSubtree()) && + GetBoolAttr(nsGkAtoms::mozinputrangeignorepreventdefault); + } + /* * The following functions are called from datetime picker to let input box * know the current state of the picker or to update the input box on changes. */ void GetDateTimeInputBoxValue(DateTimeValue& aValue); void UpdateDateTimeInputBox(const DateTimeValue& aValue); void SetDateTimePickerState(bool aOpen); @@ -1463,17 +1469,17 @@ protected: bool IsPopupBlocked() const; GetFilesHelper* GetOrCreateGetFilesHelper(bool aRecursiveFlag, ErrorResult& aRv); void ClearGetFilesHelpers(); /** - * nsINode::SetMayBeApzAware() will be invoked in this function if necessary + * nsINode::SetMayBeApzAware() will be invoked in this function if necessary * to prevent default action of APZC so that we can increase/decrease the * value of this InputElement when mouse wheel event comes without scrolling * the page. * * SetMayBeApzAware() will set flag MayBeApzAware which is checked by apzc to * decide whether to add this element into its dispatch-to-content region. */ void UpdateApzAwareFlag();
--- a/dom/html/test/forms/chrome.ini +++ b/dom/html/test/forms/chrome.ini @@ -1,5 +1,6 @@ [DEFAULT] support-files = submit_invalid_file.sjs [test_autocompleteinfo.html] [test_submit_invalid_file.html] +[test_input_range_mozinputrangeignorepreventdefault_chrome.html]
--- a/dom/html/test/forms/mochitest.ini +++ b/dom/html/test/forms/mochitest.ini @@ -55,16 +55,17 @@ skip-if = os == "android" skip-if = os == "android" [test_input_number_validation.html] # We don't build ICU for Firefox for Android: skip-if = os == "android" [test_input_number_focus.html] [test_input_range_attr_order.html] [test_input_range_key_events.html] [test_input_range_mouse_and_touch_events.html] +[test_input_range_mozinputrangeignorepreventdefault.html] [test_input_range_rounding.html] [test_input_sanitization.html] [test_input_textarea_set_value_no_scroll.html] [test_input_time_key_events.html] skip-if = os == "android" [test_input_types_pref.html] [test_input_typing_sanitization.html] [test_input_untrusted_key_events.html]
new file mode 100644 --- /dev/null +++ b/dom/html/test/forms/test_input_range_mozinputrangeignorepreventdefault.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1338961 +--> +<head> + <title>Test mouse and touch events for range</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <style> + /* synthesizeMouse and synthesizeFunc uses getBoundingClientRect. We set + * the following properties to avoid fractional values in the rect returned + * by getBoundingClientRect in order to avoid rounding that would occur + * when event coordinates are internally converted to be relative to the + * top-left of the element. (Such rounding would make it difficult to + * predict exactly what value the input should take on for events at + * certain coordinates.) + */ + input { margin: 0 ! important; width: 200px ! important; } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1338961">Mozilla Bug 1338961</a> +<p id="display"></p> +<div id="content"> + <input id="range" type="range" mozinputrangeignorepreventdefault="true"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** + * Test for Bug 1338961 + * This test ensures mozinputrangeignorepreventdefault has no effect in + * content html. + **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(function() { + test(synthesizeMouse, "click", "mousedown", "mousemove", "mouseup"); + test(synthesizeTouch, "tap", "touchstart", "touchmove", "touchend"); + SimpleTest.finish(); +}); + +function flush() { + // Flush style, specifically to flush the 'direction' property so that the + // browser uses the new value for thumb positioning. + var flush = document.body.clientWidth; +} + +const QUARTER_OF_RANGE = "25"; + +function test(synthesizeFunc, clickOrTap, startName, moveName, endName) { + var elem = document.getElementById("range"); + elem.focus(); + flush(); + + var width = parseFloat(window.getComputedStyle(elem).width); + var height = parseFloat(window.getComputedStyle(elem).height); + var borderLeft = parseFloat(window.getComputedStyle(elem).borderLeftWidth); + var borderTop = parseFloat(window.getComputedStyle(elem).borderTopWidth); + var paddingLeft = parseFloat(window.getComputedStyle(elem).paddingLeft); + var paddingTop = parseFloat(window.getComputedStyle(elem).paddingTop); + + // Extrema for mouse/touch events: + var midY = height / 2 + borderTop + paddingTop; + var minX = borderLeft + paddingLeft; + var midX = minX + width / 2; + var maxX = minX + width; + + function preventDefault(e) { + e.preventDefault(); + } + + // Test that preventDefault() works: + elem.value = QUARTER_OF_RANGE; + elem.addEventListener(startName, preventDefault); + synthesizeFunc(elem, midX, midY, {}); + is(elem.value, QUARTER_OF_RANGE, "Test that preventDefault() works"); + elem.removeEventListener(startName, preventDefault); + + // Test that preventDefault() on the parent node works: + elem.value = QUARTER_OF_RANGE; + elem.parentNode.addEventListener(startName, preventDefault); + synthesizeFunc(elem, midX, midY, {}); + is(elem.value, QUARTER_OF_RANGE, "Test that preventDefault() on the parent node works"); + elem.parentNode.removeEventListener(startName, preventDefault); +} + +</script> +</pre> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/dom/html/test/forms/test_input_range_mozinputrangeignorepreventdefault_chrome.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1338961 +--> +<head> + <title>Test mouse and touch events for range</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <style> + /* synthesizeMouse and synthesizeFunc uses getBoundingClientRect. We set + * the following properties to avoid fractional values in the rect returned + * by getBoundingClientRect in order to avoid rounding that would occur + * when event coordinates are internally converted to be relative to the + * top-left of the element. (Such rounding would make it difficult to + * predict exactly what value the input should take on for events at + * certain coordinates.) + */ + input { margin: 0 ! important; width: 200px ! important; } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1338961">Mozilla Bug 1338961</a> +<p id="display"></p> +<div id="content"> + <input id="range" type="range" mozinputrangeignorepreventdefault="true"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** + * Test for Bug 1338961 + * This test ensures mozinputrangeignorepreventdefault has it's desired effect in + * chrome html. + **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(function() { + test(synthesizeMouse, "click", "mousedown", "mousemove", "mouseup"); + test(synthesizeTouch, "tap", "touchstart", "touchmove", "touchend"); + SimpleTest.finish(); +}); + +function flush() { + // Flush style, specifically to flush the 'direction' property so that the + // browser uses the new value for thumb positioning. + var flush = document.body.clientWidth; +} + +const MIDDLE_OF_RANGE = "50"; +const QUARTER_OF_RANGE = "25"; + +function test(synthesizeFunc, clickOrTap, startName, moveName, endName) { + var elem = document.getElementById("range"); + elem.focus(); + flush(); + + var width = parseFloat(window.getComputedStyle(elem).width); + var height = parseFloat(window.getComputedStyle(elem).height); + var borderLeft = parseFloat(window.getComputedStyle(elem).borderLeftWidth); + var borderTop = parseFloat(window.getComputedStyle(elem).borderTopWidth); + var paddingLeft = parseFloat(window.getComputedStyle(elem).paddingLeft); + var paddingTop = parseFloat(window.getComputedStyle(elem).paddingTop); + + // Extrema for mouse/touch events: + var midY = height / 2 + borderTop + paddingTop; + var minX = borderLeft + paddingLeft; + var midX = minX + width / 2; + var maxX = minX + width; + + function preventDefault(e) { + e.preventDefault(); + } + + // Test that preventDefault() is ignored: + elem.value = QUARTER_OF_RANGE; + elem.addEventListener(startName, preventDefault); + synthesizeFunc(elem, midX, midY, {}); + is(elem.value, MIDDLE_OF_RANGE, "Test that preventDefault() is ignored"); + elem.removeEventListener(startName, preventDefault); + + // Test that preventDefault() on the parent node works: + elem.value = QUARTER_OF_RANGE; + elem.parentNode.addEventListener(startName, preventDefault); + synthesizeFunc(elem, midX, midY, {}); + is(elem.value, MIDDLE_OF_RANGE, "Test that preventDefault() on the parent node is ignored"); + elem.parentNode.removeEventListener(startName, preventDefault); +} + +</script> +</pre> +</body> +</html>
--- a/toolkit/content/widgets/videocontrols.xml +++ b/toolkit/content/widgets/videocontrols.xml @@ -155,31 +155,31 @@ tabindex="-1"/> <div anonid="scrubberStack" class="scrubberStack progressContainer" role="none"> <div class="progressBackgroundBar stackItem" role="none"> <div class="progressStack" role="none"> <progress anonid="bufferBar" class="bufferBar" value="0" max="100" tabindex="-1"></progress> <progress anonid="progressBar" class="progressBar" value="0" max="100" tabindex="-1"></progress> </div> </div> - <input type="range" anonid="scrubber" class="scrubber" tabindex="-1"/> + <input type="range" anonid="scrubber" class="scrubber" tabindex="-1" mozinputrangeignorepreventdefault="true" /> </div> <span anonid="positionLabel" class="positionLabel" role="presentation"></span> <span anonid="durationLabel" class="durationLabel" role="presentation"></span> <span anonid="positionDurationBox" class="positionDurationBox" aria-hidden="true"> &positionAndDuration.nameFormat; </span> <div anonid="controlBarSpacer" class="controlBarSpacer" hidden="true" role="none"></div> <button anonid="muteButton" class="muteButton" mutelabel="&muteButton.muteLabel;" unmutelabel="&muteButton.unmuteLabel;" tabindex="-1"/> <div anonid="volumeStack" class="volumeStack progressContainer" role="none"> - <input type="range" anonid="volumeControl" class="volumeControl" min="0" max="100" step="1" tabindex="-1"/> + <input type="range" anonid="volumeControl" class="volumeControl" min="0" max="100" step="1" tabindex="-1" mozinputrangeignorepreventdefault="true" /> </div> <button anonid="closedCaptionButton" class="closedCaptionButton"/> <button anonid="fullscreenButton" class="fullscreenButton" enterfullscreenlabel="&fullscreenButton.enterfullscreenlabel;" exitfullscreenlabel="&fullscreenButton.exitfullscreenlabel;"/> </div> <div anonid="textTrackList" class="textTrackList" hidden="true" offlabel="&closedCaption.off;"></div>