зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1149671 - Use alt/na/shift to step 0.1/1/10 at a time. r=pbrosset
--HG-- extra : rebase_source : 8905a064e9fef03301f4fb9efed6839c368e85d9
This commit is contained in:
Родитель
3108b22c58
Коммит
f7d08d3712
|
@ -27,6 +27,9 @@ support-files =
|
|||
[browser_filter-editor-05.js]
|
||||
[browser_filter-editor-06.js]
|
||||
[browser_filter-editor-07.js]
|
||||
[browser_filter-editor-08.js]
|
||||
[browser_filter-editor-09.js]
|
||||
[browser_filter-editor-10.js]
|
||||
[browser_flame-graph-01.js]
|
||||
[browser_flame-graph-02.js]
|
||||
[browser_flame-graph-03a.js]
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests the Filter Editor Widget inputs increase/decrease value using
|
||||
// arrow keys, applying multiplier using alt/shift on number-type filters
|
||||
|
||||
const TEST_URI = "chrome://browser/content/devtools/filter-frame.xhtml";
|
||||
const {CSSFilterEditorWidget} = require("devtools/shared/widgets/FilterWidget");
|
||||
|
||||
const FAST_VALUE_MULTIPLIER = 10;
|
||||
const SLOW_VALUE_MULTIPLIER = 0.1;
|
||||
const DEFAULT_VALUE_MULTIPLIER = 1;
|
||||
|
||||
add_task(function*() {
|
||||
yield promiseTab("about:blank");
|
||||
let [host, win, doc] = yield createHost("bottom", TEST_URI);
|
||||
|
||||
const container = doc.querySelector("#container");
|
||||
const initialValue = "blur(2px)";
|
||||
let widget = new CSSFilterEditorWidget(container, initialValue);
|
||||
|
||||
let value = 2;
|
||||
|
||||
triggerKey = triggerKey.bind(widget);
|
||||
|
||||
info("Test simple arrow keys");
|
||||
triggerKey(40);
|
||||
|
||||
value -= DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should decrease value using down arrow");
|
||||
|
||||
triggerKey(38);
|
||||
|
||||
value += DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should decrease value using down arrow");
|
||||
|
||||
info("Test shift key multiplier");
|
||||
triggerKey(38, "shiftKey");
|
||||
|
||||
value += FAST_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should increase value by fast multiplier using up arrow");
|
||||
|
||||
triggerKey(40, "shiftKey");
|
||||
|
||||
value -= FAST_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should decrease value by fast multiplier using down arrow");
|
||||
|
||||
info("Test alt key multiplier");
|
||||
triggerKey(38, "altKey");
|
||||
|
||||
value += SLOW_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should increase value by slow multiplier using up arrow");
|
||||
|
||||
triggerKey(40, "altKey");
|
||||
|
||||
value -= SLOW_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), `${value}px`,
|
||||
"Should decrease value by slow multiplier using down arrow");
|
||||
|
||||
triggerKey = null;
|
||||
});
|
||||
|
||||
// Triggers the specified keyCode and modifier key on
|
||||
// first filter's input
|
||||
function triggerKey(key, modifier) {
|
||||
const filter = this.el.querySelector(".filters").children[0];
|
||||
const input = filter.querySelector("input");
|
||||
|
||||
this._keyDown({
|
||||
target: input,
|
||||
keyCode: key,
|
||||
[modifier]: true,
|
||||
preventDefault: function() {}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests the Filter Editor Widget inputs increase/decrease value when cursor is
|
||||
// on a number using arrow keys, applying multiplier using alt/shift on strings
|
||||
|
||||
const TEST_URI = "chrome://browser/content/devtools/filter-frame.xhtml";
|
||||
const {CSSFilterEditorWidget} = require("devtools/shared/widgets/FilterWidget");
|
||||
|
||||
const FAST_VALUE_MULTIPLIER = 10;
|
||||
const SLOW_VALUE_MULTIPLIER = 0.1;
|
||||
const DEFAULT_VALUE_MULTIPLIER = 1;
|
||||
|
||||
add_task(function*() {
|
||||
yield promiseTab("about:blank");
|
||||
let [host, win, doc] = yield createHost("bottom", TEST_URI);
|
||||
|
||||
const container = doc.querySelector("#container");
|
||||
const initialValue = "drop-shadow(rgb(0, 0, 0) 1px 1px 0px)";
|
||||
let widget = new CSSFilterEditorWidget(container, initialValue);
|
||||
widget.el.querySelector("input").setSelectionRange(13, 13);
|
||||
|
||||
let value = 1;
|
||||
|
||||
triggerKey = triggerKey.bind(widget);
|
||||
|
||||
info("Test simple arrow keys");
|
||||
triggerKey(40);
|
||||
|
||||
value -= DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease value using down arrow");
|
||||
|
||||
triggerKey(38);
|
||||
|
||||
value += DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease value using down arrow");
|
||||
|
||||
info("Test shift key multiplier");
|
||||
triggerKey(38, "shiftKey");
|
||||
|
||||
value += FAST_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should increase value by fast multiplier using up arrow");
|
||||
|
||||
triggerKey(40, "shiftKey");
|
||||
|
||||
value -= FAST_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease value by fast multiplier using down arrow");
|
||||
|
||||
info("Test alt key multiplier");
|
||||
triggerKey(38, "altKey");
|
||||
|
||||
value += SLOW_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should increase value by slow multiplier using up arrow");
|
||||
|
||||
triggerKey(40, "altKey");
|
||||
|
||||
value -= SLOW_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease value by slow multiplier using down arrow");
|
||||
|
||||
triggerKey(40, "shiftKey");
|
||||
|
||||
value -= FAST_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease to negative");
|
||||
|
||||
triggerKey(40);
|
||||
|
||||
value -= DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease negative numbers correctly");
|
||||
|
||||
triggerKey(38);
|
||||
|
||||
value += DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should increase negative values correctly");
|
||||
|
||||
triggerKey(40, "altKey");
|
||||
triggerKey(40, "altKey");
|
||||
|
||||
value -= SLOW_VALUE_MULTIPLIER * 2;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should decrease float numbers correctly");
|
||||
|
||||
triggerKey(38, "altKey");
|
||||
|
||||
value += SLOW_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should increase float numbers correctly");
|
||||
|
||||
triggerKey = null;
|
||||
});
|
||||
|
||||
// Triggers the specified keyCode and modifier key on
|
||||
// first filter's input
|
||||
function triggerKey(key, modifier) {
|
||||
const filter = this.el.querySelector(".filters").children[0];
|
||||
const input = filter.querySelector("input");
|
||||
|
||||
this._keyDown({
|
||||
target: input,
|
||||
keyCode: key,
|
||||
[modifier]: true,
|
||||
preventDefault: function() {}
|
||||
});
|
||||
}
|
||||
|
||||
function val(value) {
|
||||
let v = value.toFixed(1);
|
||||
|
||||
if (v.indexOf(".0") > -1) {
|
||||
v = v.slice(0, -2);
|
||||
}
|
||||
return `rgb(0, 0, 0) ${v}px 1px 0px`;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests the Filter Editor Widget inputs increase/decrease value when cursor is
|
||||
// on a number using arrow keys if cursor is behind/mid/after the number strings
|
||||
|
||||
const TEST_URI = "chrome://browser/content/devtools/filter-frame.xhtml";
|
||||
const {CSSFilterEditorWidget} = require("devtools/shared/widgets/FilterWidget");
|
||||
|
||||
const FAST_VALUE_MULTIPLIER = 10;
|
||||
const SLOW_VALUE_MULTIPLIER = 0.1;
|
||||
const DEFAULT_VALUE_MULTIPLIER = 1;
|
||||
|
||||
add_task(function*() {
|
||||
yield promiseTab("about:blank");
|
||||
let [host, win, doc] = yield createHost("bottom", TEST_URI);
|
||||
|
||||
const container = doc.querySelector("#container");
|
||||
const initialValue = "drop-shadow(rgb(0, 0, 0) 10px 1px 0px)";
|
||||
let widget = new CSSFilterEditorWidget(container, initialValue);
|
||||
const input = widget.el.querySelector("input");
|
||||
|
||||
let value = 10;
|
||||
|
||||
triggerKey = triggerKey.bind(widget);
|
||||
|
||||
info("Test increment/decrement of string-type numbers without selection");
|
||||
|
||||
input.setSelectionRange(14, 14);
|
||||
triggerKey(40);
|
||||
|
||||
value -= DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should work with cursor in the middle of number");
|
||||
|
||||
input.setSelectionRange(13, 13);
|
||||
triggerKey(38);
|
||||
|
||||
value += DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should work with cursor before the number");
|
||||
|
||||
input.setSelectionRange(15, 15);
|
||||
triggerKey(40);
|
||||
|
||||
value -= DEFAULT_VALUE_MULTIPLIER;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should work with cursor after the number");
|
||||
|
||||
info("Test increment/decrement of string-type numbers with a selection");
|
||||
|
||||
input.setSelectionRange(13, 15);
|
||||
triggerKey(38);
|
||||
input.setSelectionRange(13, 18);
|
||||
triggerKey(38);
|
||||
|
||||
value += DEFAULT_VALUE_MULTIPLIER * 2;
|
||||
is(widget.getValueAt(0), val(value),
|
||||
"Should work if a there is a selection, starting with the number");
|
||||
|
||||
triggerKey = null;
|
||||
});
|
||||
|
||||
// Triggers the specified keyCode and modifier key on
|
||||
// first filter's input
|
||||
function triggerKey(key, modifier) {
|
||||
const filter = this.el.querySelector(".filters").children[0];
|
||||
const input = filter.querySelector("input");
|
||||
|
||||
this._keyDown({
|
||||
target: input,
|
||||
keyCode: key,
|
||||
[modifier]: true,
|
||||
preventDefault: function() {}
|
||||
});
|
||||
}
|
||||
|
||||
function val(value) {
|
||||
let v = value.toFixed(1);
|
||||
|
||||
if (v.indexOf(".0") > -1) {
|
||||
v = v.slice(0, -2);
|
||||
}
|
||||
return `rgb(0, 0, 0) ${v}px 1px 0px`;
|
||||
}
|
|
@ -113,6 +113,7 @@ function CSSFilterEditorWidget(el, value = "") {
|
|||
this._mouseMove = this._mouseMove.bind(this);
|
||||
this._mouseUp = this._mouseUp.bind(this);
|
||||
this._mouseDown = this._mouseDown.bind(this);
|
||||
this._keyDown = this._keyDown.bind(this);
|
||||
this._input = this._input.bind(this);
|
||||
|
||||
this._initMarkup();
|
||||
|
@ -195,6 +196,7 @@ CSSFilterEditorWidget.prototype = {
|
|||
this.addButton.addEventListener("click", this._addButtonClick);
|
||||
this.list.addEventListener("click", this._removeButtonClick);
|
||||
this.list.addEventListener("mousedown", this._mouseDown);
|
||||
this.list.addEventListener("keydown", this._keyDown);
|
||||
|
||||
// These events are event delegators for
|
||||
// drag-drop re-ordering and label-dragging
|
||||
|
@ -205,9 +207,77 @@ CSSFilterEditorWidget.prototype = {
|
|||
this.list.addEventListener("input", this._input);
|
||||
},
|
||||
|
||||
_getFilterElementIndex: function(el) {
|
||||
return [...this.list.children].indexOf(el);
|
||||
},
|
||||
|
||||
_keyDown: function(e) {
|
||||
if (e.target.tagName.toLowerCase() !== "input" ||
|
||||
(e.keyCode !== 40 && e.keyCode !== 38)) {
|
||||
return;
|
||||
}
|
||||
let input = e.target;
|
||||
|
||||
const direction = e.keyCode === 40 ? -1 : 1;
|
||||
|
||||
let multiplier = DEFAULT_VALUE_MULTIPLIER;
|
||||
if (e.altKey) {
|
||||
multiplier = SLOW_VALUE_MULTIPLIER;
|
||||
} else if (e.shiftKey) {
|
||||
multiplier = FAST_VALUE_MULTIPLIER;
|
||||
}
|
||||
|
||||
const filterEl = e.target.closest(".filter");
|
||||
const index = this._getFilterElementIndex(filterEl);
|
||||
const filter = this.filters[index];
|
||||
|
||||
// Filters that have units are number-type filters. For them,
|
||||
// the value can be incremented/decremented simply.
|
||||
// For other types of filters (e.g. drop-shadow) we need to check
|
||||
// if the keypress happened close to a number first.
|
||||
if (filter.unit) {
|
||||
let startValue = parseFloat(e.target.value);
|
||||
let value = startValue + direction * multiplier;
|
||||
|
||||
const [min, max] = this._definition(filter.name).range;
|
||||
value = value < min ? min :
|
||||
value > max ? max : value;
|
||||
|
||||
input.value = fixFloat(value);
|
||||
|
||||
this.updateValueAt(index, value);
|
||||
} else {
|
||||
let selectionStart = input.selectionStart;
|
||||
let num = getNeighbourNumber(input.value, selectionStart);
|
||||
if (!num) {
|
||||
return;
|
||||
}
|
||||
|
||||
let {start, end, value} = num;
|
||||
|
||||
let split = input.value.split("");
|
||||
let computed = fixFloat(value + direction * multiplier),
|
||||
dotIndex = computed.indexOf(".0");
|
||||
if (dotIndex > -1) {
|
||||
computed = computed.slice(0, -2);
|
||||
|
||||
selectionStart = selectionStart > start + dotIndex ?
|
||||
start + dotIndex :
|
||||
selectionStart;
|
||||
}
|
||||
split.splice(start, end - start, computed);
|
||||
|
||||
value = split.join("");
|
||||
input.value = value;
|
||||
this.updateValueAt(index, value);
|
||||
input.setSelectionRange(selectionStart, selectionStart);
|
||||
}
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
_input: function(e) {
|
||||
let filterEl = e.target.closest(".filter"),
|
||||
index = [...this.list.children].indexOf(filterEl),
|
||||
index = this._getFilterElementIndex(filterEl),
|
||||
filter = this.filters[index],
|
||||
def = this._definition(filter.name);
|
||||
|
||||
|
@ -231,7 +301,7 @@ CSSFilterEditorWidget.prototype = {
|
|||
} else if (e.target.classList.contains("devtools-draglabel")) {
|
||||
let label = e.target,
|
||||
input = filterEl.querySelector("input"),
|
||||
index = [...this.list.children].indexOf(filterEl);
|
||||
index = this._getFilterElementIndex(filterEl);
|
||||
|
||||
this._dragging = {
|
||||
index, label, input,
|
||||
|
@ -273,7 +343,7 @@ CSSFilterEditorWidget.prototype = {
|
|||
}
|
||||
|
||||
let filterEl = e.target.closest(".filter");
|
||||
let index = [...this.list.children].indexOf(filterEl);
|
||||
let index = this._getFilterElementIndex(filterEl);
|
||||
this.removeAt(index);
|
||||
},
|
||||
|
||||
|
@ -622,6 +692,7 @@ CSSFilterEditorWidget.prototype = {
|
|||
this.addButton.removeEventListener("click", this._addButtonClick);
|
||||
this.list.removeEventListener("click", this._removeButtonClick);
|
||||
this.list.removeEventListener("mousedown", this._mouseDown);
|
||||
this.list.removeEventListener("keydown", this._keyDown);
|
||||
|
||||
// These events are used for drag drop re-ordering
|
||||
this.win.removeEventListener("mousemove", this._mouseMove);
|
||||
|
@ -718,3 +789,40 @@ function tokenizeComputedFilter(css) {
|
|||
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds neighbour number characters of an index in a string
|
||||
* the numbers may be floats (containing dots)
|
||||
* It's assumed that the value given to this function is a valid number
|
||||
*
|
||||
* @param {String} string
|
||||
* The string containing numbers
|
||||
* @param {Number} index
|
||||
* The index to look for neighbours for
|
||||
* @return {Object}
|
||||
* returns null if no number is found
|
||||
* value: The number found
|
||||
* start: The number's starting index
|
||||
* end: The number's ending index
|
||||
*/
|
||||
function getNeighbourNumber(string, index) {
|
||||
if (!/\d/.test(string)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let left = /-?[0-9.]*$/.exec(string.slice(0, index)),
|
||||
right = /-?[0-9.]*/.exec(string.slice(index));
|
||||
|
||||
left = left ? left[0] : "";
|
||||
right = right ? right[0] : "";
|
||||
|
||||
if (!right && !left) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
value: fixFloat(left + right, true),
|
||||
start: index - left.length,
|
||||
end: index + right.length
|
||||
};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче