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:
Mahdi Dibaiee 2015-04-21 02:30:00 -04:00
Родитель 3108b22c58
Коммит f7d08d3712
5 изменённых файлов: 406 добавлений и 3 удалений

Просмотреть файл

@ -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
};
}