Bug 1267414 - Convert color picker, cubic bezier and filter widgets to HTML Tooltip. r=jdescottes

--HG--
rename : devtools/client/themes/spectrum.css => devtools/client/shared/widgets/spectrum.css
This commit is contained in:
Alexandre Poirot 2016-07-11 01:26:02 -07:00
Родитель 0f4f5e6448
Коммит c660dc1021
50 изменённых файлов: 382 добавлений и 506 удалений

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

@ -47,7 +47,7 @@ add_task(function* () {
value: "rgb(0, 255, 0)"
});
let spectrum = yield cPicker.spectrum;
let spectrum = cPicker.spectrum;
let onHidden = cPicker.tooltip.once("hidden");
// Validating the color change ends up updating the rule view twice
let onRuleViewChanged = waitForNEvents(view, "ruleview-changed", 2);

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

@ -52,7 +52,7 @@ function* basicTest(view, name, result) {
value: "rgb(0, 255, 0)"
});
let spectrum = yield cPicker.spectrum;
let spectrum = cPicker.spectrum;
let onHidden = cPicker.tooltip.once("hidden");
// Validating the color change ends up updating the rule view twice
let onRuleViewChanged = waitForNEvents(view, "ruleview-changed", 2);

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

@ -44,7 +44,7 @@ function* testImageTooltipAfterColorChange(swatch, url, ruleView) {
value: 'url("chrome://global/skin/icons/warning-64.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 0, 102) 400px)'
});
let spectrum = yield picker.spectrum;
let spectrum = picker.spectrum;
let onHidden = picker.tooltip.once("hidden");
let onModifications = ruleView.once("ruleview-changed");
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);

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

@ -42,7 +42,7 @@ function* testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
value: "rgb(0, 0, 0)"
});
let spectrum = yield picker.spectrum;
let spectrum = picker.spectrum;
let onModifications = waitForNEvents(ruleView, "ruleview-changed", 2);
let onHidden = picker.tooltip.once("hidden");

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

@ -45,7 +45,7 @@ function* testPressingEnterCommitsChanges(swatch, ruleView) {
"The text of the border css property was updated");
let onModified = ruleView.once("ruleview-changed");
let spectrum = yield cPicker.spectrum;
let spectrum = cPicker.spectrum;
let onHidden = cPicker.tooltip.once("hidden");
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
yield onHidden;

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

@ -17,7 +17,7 @@ add_task(function* () {
.querySelector(".ruleview-colorswatch");
let picker = yield openColorPickerForSwatch(cSwatch, view);
let spectrum = yield picker.spectrum;
let spectrum = picker.spectrum;
let change = spectrum.once("changed");
info("Pressing mouse down over color picker.");

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

@ -35,7 +35,7 @@ function* testPressingEscapeRevertsChanges(view) {
is(propEditor.valueSpan.textContent, "#000",
"The text of the background-color css property was updated");
let spectrum = yield cPicker.spectrum;
let spectrum = cPicker.spectrum;
info("Pressing ESCAPE to close the tooltip");
let onHidden = cPicker.tooltip.once("hidden");
@ -76,7 +76,7 @@ function* testPressingEscapeRevertsChangesAndDisables(view) {
is(textProp.editor.enable.style.visibility, "hidden",
"property enable checkbox is hidden.");
let spectrum = yield cPicker.spectrum;
let spectrum = cPicker.spectrum;
info("Pressing ESCAPE to close the tooltip");
let onHidden = cPicker.tooltip.once("hidden");

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

@ -64,6 +64,6 @@ add_task(function* () {
ok(!inplaceEditor(propEditor.valueSpan),
"The inplace editor wasn't shown as a result of the color swatch click");
let spectrum = yield colorPicker.spectrum;
let spectrum = colorPicker.spectrum;
is(spectrum.rgb, "200,170,140,0.5", "The correct color picker was shown");
});

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

@ -61,7 +61,7 @@ add_task(function* () {
let dropper = yield openEyedropper(view, swatch);
let tooltip = view.tooltips.colorPicker.tooltip;
ok(tooltip.isHidden(),
ok(!tooltip.isVisible(),
"color picker tooltip is closed after opening eyedropper");
yield testESC(swatch, dropper);
@ -134,8 +134,7 @@ function openEyedropper(view, swatch) {
let tooltip = view.tooltips.colorPicker.tooltip;
tooltip.once("shown", () => {
let tooltipDoc = tooltip.content.contentDocument;
let dropperButton = tooltipDoc.querySelector("#eyedropper-button");
let dropperButton = tooltip.doc.querySelector("#eyedropper-button");
tooltip.once("eyedropper-opened", (event, dropper) => {
deferred.resolve(dropper);

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

@ -28,6 +28,5 @@ add_task(function* () {
ok(!inplaceEditor(swatch.parentNode),
"The inplace editor wasn't shown as a result of the filter swatch click");
yield filterTooltip.widget;
yield hideTooltipAndWaitForRuleViewChanged(filterTooltip, view);
});

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

@ -25,7 +25,7 @@ add_task(function* () {
info("Get the cssfilter widget instance");
let filterTooltip = view.tooltips.filterEditor;
let widget = yield filterTooltip.widget;
let widget = filterTooltip.widget;
info("Set a new value in the cssfilter widget");
onRuleViewChanged = view.once("ruleview-changed");

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

@ -38,7 +38,6 @@ function* testPressingEscapeRevertsChanges(view) {
function* testPressingEscapeRevertsChangesAndDisables(view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let swatch = propEditor.valueSpan.querySelector(".ruleview-filterswatch");
info("Disabling filter property");
let onRuleViewChanged = view.once("ruleview-changed");
@ -56,6 +55,7 @@ function* testPressingEscapeRevertsChangesAndDisables(view) {
let newValue = yield getRulePropertyValue("filter");
is(newValue, "", "filter should have been unset.");
let swatch = propEditor.valueSpan.querySelector(".ruleview-filterswatch");
yield clickOnFilterSwatch(swatch, view);
ok(!propEditor.element.classList.contains("ruleview-overridden"),
@ -103,9 +103,8 @@ function* setValueInFilterWidget(value, view) {
info("Setting the CSS filter value in the tooltip");
let filterTooltip = view.tooltips.filterEditor;
let widget = yield filterTooltip.widget;
let onRuleViewChanged = view.once("ruleview-changed");
widget.setCssValue(value);
filterTooltip.widget.setCssValue(value);
yield onRuleViewChanged;
}
@ -113,8 +112,7 @@ function* pressEscapeToCloseTooltip(view) {
info("Pressing ESCAPE to close the tooltip");
let filterTooltip = view.tooltips.filterEditor;
let widget = yield filterTooltip.widget;
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.sendKey("ESCAPE", widget.styleWindow);
EventUtils.sendKey("ESCAPE", filterTooltip.widget.styleWindow);
yield onRuleViewChanged;
}

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

@ -358,9 +358,14 @@ function getRuleViewSelectorHighlighterIcon(view, selectorText) {
*/
var simulateColorPickerChange = Task.async(function* (ruleView, colorPicker,
newRgba, expectedChange) {
let onComputedStyleChanged;
if (expectedChange) {
let {selector, name, value} = expectedChange;
onComputedStyleChanged = waitForComputedStyleProperty(selector, null, name, value);
}
let onRuleViewChanged = ruleView.once("ruleview-changed");
info("Getting the spectrum colorpicker object");
let spectrum = yield colorPicker.spectrum;
let spectrum = colorPicker.spectrum;
info("Setting the new color");
spectrum.rgb = newRgba;
info("Applying the change");
@ -371,8 +376,7 @@ var simulateColorPickerChange = Task.async(function* (ruleView, colorPicker,
if (expectedChange) {
info("Waiting for the style to be applied on the page");
let {selector, name, value} = expectedChange;
yield waitForComputedStyleProperty(selector, null, name, value);
yield onComputedStyleChanged;
}
});

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

@ -261,10 +261,10 @@ exports.TooltipsOverlay = TooltipsOverlay;
TooltipsOverlay.prototype = {
get isEditing() {
return this.colorPicker.tooltip.isShown() ||
return this.colorPicker.tooltip.isVisible() ||
this.colorPicker.eyedropperOpen ||
this.cubicBezier.tooltip.isShown() ||
this.filterEditor.tooltip.isShown();
this.cubicBezier.tooltip.isVisible() ||
this.filterEditor.tooltip.isVisible();
},
/**
@ -290,11 +290,12 @@ TooltipsOverlay.prototype = {
if (this.isRuleView) {
// Color picker tooltip
this.colorPicker = new SwatchColorPickerTooltip(panelDoc);
let { toolbox } = this.view.inspector;
this.colorPicker = new SwatchColorPickerTooltip(toolbox);
// Cubic bezier tooltip
this.cubicBezier = new SwatchCubicBezierTooltip(panelDoc);
this.cubicBezier = new SwatchCubicBezierTooltip(toolbox);
// Filter editor tooltip
this.filterEditor = new SwatchFilterTooltip(panelDoc);
this.filterEditor = new SwatchFilterTooltip(toolbox);
}
this._isStarted = true;
@ -381,12 +382,12 @@ TooltipsOverlay.prototype = {
return false;
}
if (this.isRuleView && this.colorPicker.tooltip.isShown()) {
if (this.isRuleView && this.colorPicker.tooltip.isVisible()) {
this.colorPicker.revert();
this.colorPicker.hide();
}
if (this.isRuleView && this.cubicBezier.tooltip.isShown()) {
if (this.isRuleView && this.cubicBezier.tooltip.isVisible()) {
this.cubicBezier.revert();
this.cubicBezier.hide();
}
@ -395,7 +396,7 @@ TooltipsOverlay.prototype = {
this.cssDocs.hide();
}
if (this.isRuleView && this.filterEditor.tooltip.isShown()) {
if (this.isRuleView && this.filterEditor.tooltip.isVisible()) {
this.filterEditor.revert();
this.filterEdtior.hide();
}

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

@ -34,7 +34,6 @@ skip-if = e10s # Bug 1111546 (e10s)
[browser_styleinspector_tooltip-multiple-background-images.js]
[browser_styleinspector_tooltip-shorthand-fontfamily.js]
[browser_styleinspector_tooltip-size.js]
skip-if = e10s || os == 'linux' # Bug 1111546 (e10s), bug 1093431 (linux)
[browser_styleinspector_transform-highlighter-01.js]
[browser_styleinspector_transform-highlighter-02.js]
[browser_styleinspector_transform-highlighter-03.js]

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

@ -70,12 +70,13 @@ function* testPickerDimension(ruleView) {
// The colorpicker spectrum's iframe has a fixed width height, so let's
// make sure the tooltip is at least as big as that
let w = cPicker.tooltip.panel.querySelector("iframe").width;
let h = cPicker.tooltip.panel.querySelector("iframe").height;
let panelRect = cPicker.tooltip.panel.getBoundingClientRect();
let spectrumRect = cPicker.spectrum.element.getBoundingClientRect();
let panelRect = cPicker.tooltip.container.getBoundingClientRect();
ok(panelRect.width >= w, "The panel is wide enough to show the picker");
ok(panelRect.height >= h, "The panel is high enough to show the picker");
ok(panelRect.width >= spectrumRect.width,
"The panel is wide enough to show the picker");
ok(panelRect.height >= spectrumRect.height,
"The panel is high enough to show the picker");
let onHidden = cPicker.tooltip.once("hidden");
let onRuleViewChanged = ruleView.once("ruleview-changed");

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

@ -127,13 +127,11 @@ devtools.jar:
content/framework/connect/connect.css (framework/connect/connect.css)
content/framework/connect/connect.js (framework/connect/connect.js)
content/shared/widgets/graphs-frame.xhtml (shared/widgets/graphs-frame.xhtml)
content/shared/widgets/spectrum-frame.xhtml (shared/widgets/spectrum-frame.xhtml)
content/shared/widgets/cubic-bezier-frame.xhtml (shared/widgets/cubic-bezier-frame.xhtml)
content/shared/widgets/cubic-bezier.css (shared/widgets/cubic-bezier.css)
content/shared/widgets/mdn-docs-frame.xhtml (shared/widgets/mdn-docs-frame.xhtml)
content/shared/widgets/mdn-docs.css (shared/widgets/mdn-docs.css)
content/shared/widgets/filter-frame.xhtml (shared/widgets/filter-frame.xhtml)
content/shared/widgets/filter-widget.css (shared/widgets/filter-widget.css)
content/shared/widgets/spectrum.css (shared/widgets/spectrum.css)
content/eyedropper/eyedropper.xul (eyedropper/eyedropper.xul)
content/eyedropper/crosshairs.css (eyedropper/crosshairs.css)
content/eyedropper/nocursor.css (eyedropper/nocursor.css)
@ -195,7 +193,6 @@ devtools.jar:
skin/images/breadcrumbs-scrollbutton.png (themes/images/breadcrumbs-scrollbutton.png)
skin/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
skin/animationinspector.css (themes/animationinspector.css)
skin/spectrum.css (themes/spectrum.css)
skin/eyedropper.css (themes/eyedropper.css)
skin/canvasdebugger.css (themes/canvasdebugger.css)
skin/debugger.css (themes/debugger.css)

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

@ -1,24 +0,0 @@
<!-- 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/. -->
<!-- LOCALIZATION NOTE : FILE These strings are used in the CSS Filter Editor Widget
- which can be found in a tooltip that appears in the Rule View when clicking
- on a filter swatch displayed next to CSS declarations like 'filter: blur(2px)'. -->
<!-- LOCALIZATION NOTE (filterListSelectPlaceholder): This string is used as
- a preview option in the list of possible filters <select> -->
<!ENTITY filterListSelectPlaceholder "Select a Filter">
<!-- LOCALIZATION NOTE (addNewFilterButton): This string is displayed on a button used to add new filters -->
<!ENTITY addNewFilterButton "Add">
<!-- LOCALIZATION NOTE (newPresetPlaceholder): This string is used as
- a placeholder in the list of presets which is used to save a new preset -->
<!ENTITY newPresetPlaceholder "Preset Name">
<!-- LOCALIZATION NOTE (savePresetButton): This string is displayed on a button used to save a new preset -->
<!ENTITY savePresetButton "Save">
<!-- LOCALIZATION NOTE(presetsToggleButton): This string is used in a button which toggles the presets list -->
<!ENTITY presetsToggleButton "Presets">

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

@ -37,3 +37,25 @@ dragHandleTooltipText=Drag up or down to re-order filter
# filters' labels which can be dragged left/right to increase/decrease
# the filter's value (like photoshop)
labelDragTooltipText=Drag left or right to decrease or increase the value
# LOCALIZATION NOTE (filterListSelectPlaceholder):
# This string is used as a preview option in the list of possible filters
# <select>
filterListSelectPlaceholder=Select a Filter
# LOCALIZATION NOTE (addNewFilterButton):
# This string is displayed on a button used to add new filters
addNewFilterButton=Add
# LOCALIZATION NOTE (newPresetPlaceholder):
# This string is used as a placeholder in the list of presets which is used to
# save a new preset
newPresetPlaceholder=Preset Name
# LOCALIZATION NOTE (savePresetButton):
# This string is displayed on a button used to save a new preset
savePresetButton=Save
# LOCALIZATION NOTE(presetsToggleButton):
# This string is used in a button which toggles the presets list
presetsToggleButton=Presets

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

@ -6,16 +6,16 @@
// Tests that the CubicBezierWidget generates content in a given parent node
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const TEST_URI = `data:text/html,<div id="cubic-bezier-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
info("Checking that the graph markup is created in the parent");
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierWidget(container);
ok(container.querySelector(".display-wrap"),
@ -27,9 +27,7 @@ add_task(function* () {
is(buttons.length, 2,
"The 2 control points have been added");
is(buttons[0].className, "control-point");
is(buttons[0].id, "P1");
is(buttons[1].className, "control-point");
is(buttons[1].id, "P2");
ok(container.querySelector("canvas"), "The curve canvas has been added");
info("Destroying the widget");
@ -37,5 +35,4 @@ add_task(function* () {
is(container.children.length, 0, "All nodes have been removed");
host.destroy();
gBrowser.removeCurrentTab();
});

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

@ -6,21 +6,26 @@
// Tests the CubicBezierWidget events
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {PREDEFINED} = require("devtools/client/shared/widgets/CubicBezierPresets");
// In this test we have to use a slightly more complete HTML tree, with <body>
// in order to remove its margin and prevent shifted positions
const TEST_URI = `data:text/html,
<html><body>
<div id="cubic-bezier-container"/>
</body></html>`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
// Required or widget will be clipped inside of 'bottom'
// host by -14. Setting `fixed` zeroes this which is needed for
// calculating offsets. Occurs in test env only.
doc.body.setAttribute("style", "position: fixed");
doc.body.setAttribute("style", "position: fixed; margin: 0;");
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierWidget(container, PREDEFINED.linear);
let rect = w.curve.getBoundingClientRect();
@ -34,7 +39,6 @@ add_task(function* () {
w.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
function* pointsCanBeDragged(widget, win, doc, offsets) {

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

@ -6,16 +6,16 @@
// Tests that coordinates can be changed programatically in the CubicBezierWidget
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {PREDEFINED} = require("devtools/client/shared/widgets/CubicBezierPresets");
const TEST_URI = `data:text/html,<div id="cubic-bezier-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierWidget(container, PREDEFINED.linear);
yield coordinatesCanBeChangedByProvidingAnArray(w);
@ -23,7 +23,6 @@ add_task(function* () {
w.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
function* coordinatesCanBeChangedByProvidingAnArray(widget) {

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

@ -6,16 +6,16 @@
// Tests that the CubicBezierPresetWidget generates markup.
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierPresetWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {PRESETS} = require("devtools/client/shared/widgets/CubicBezierPresets");
const TEST_URI = `data:text/html,<div id="cubic-bezier-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierPresetWidget(container);
info("Checking that the presets are created in the parent");
@ -47,5 +47,4 @@ add_task(function* () {
w.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});

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

@ -6,17 +6,17 @@
// Tests that the CubicBezierPresetWidget cycles menus
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierPresetWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {PREDEFINED, PRESETS, DEFAULT_PRESET_CATEGORY} =
require("devtools/client/shared/widgets/CubicBezierPresets");
const TEST_URI = `data:text/html,<div id="cubic-bezier-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierPresetWidget(container);
info("Checking that preset is selected if coordinates are known");
@ -45,5 +45,4 @@ add_task(function* () {
w.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});

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

@ -7,16 +7,16 @@
// Tests the integration between CubicBezierWidget and CubicBezierPresets
const TEST_URI = "chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const {CubicBezierWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {PRESETS} = require("devtools/client/shared/widgets/CubicBezierPresets");
const TEST_URI = `data:text/html,<div id="cubic-bezier-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
let container = doc.querySelector("#container");
let container = doc.querySelector("#cubic-bezier-container");
let w = new CubicBezierWidget(container,
PRESETS["ease-in"]["ease-in-sine"]);
w.presets.refreshMenu(PRESETS["ease-in"]["ease-in-sine"]);
@ -29,7 +29,6 @@ add_task(function* () {
w.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
function* adjustingBezierUpdatesPreset(widget, win, doc, rect) {

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

@ -5,11 +5,12 @@
// Tests that the Filter Editor Widget parses filter values correctly (setCssValue)
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const DOMUtils =
Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
const TEST_URI = `data:text/html,<div id="filter-container" />`;
// Verify that the given string consists of a valid CSS URL token.
// Return true on success, false on error.
function verifyURL(string) {
@ -24,10 +25,9 @@ function verifyURL(string) {
}
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
info("Test parsing of a valid CSS Filter value");

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

@ -5,15 +5,15 @@
// Tests that the Filter Editor Widget renders filters correctly
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/filterwidget.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const TEST_DATA = [
@ -68,7 +68,7 @@ add_task(function* () {
}
];
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
info("Test rendering of different types");

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

@ -5,17 +5,16 @@
// Tests the Filter Editor Widget add, removeAt, updateAt, getValueAt methods
const BASE_URI = "chrome://devtools/content/shared/widgets/";
const TEST_URI = BASE_URI + "filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const GRAYSCALE_MAX = 100;
const INVERT_MIN = 0;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
info("Test add method");

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

@ -5,15 +5,15 @@
// Tests the Filter Editor Widget's drag-drop re-ordering
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const LIST_ITEM_HEIGHT = 32;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
const initialValue = "blur(2px) contrast(200%) brightness(200%)";
let widget = new CSSFilterEditorWidget(container, initialValue);

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

@ -7,7 +7,6 @@ requestLongerTimeout(2);
// Tests the Filter Editor Widget's label-dragging
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const FAST_VALUE_MULTIPLIER = 10;
@ -17,11 +16,12 @@ const DEFAULT_VALUE_MULTIPLIER = 1;
const GRAYSCALE_MAX = 100,
GRAYSCALE_MIN = 0;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "grayscale(0%) url(test.svg)");
const filters = widget.el.querySelector("#filters");

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

@ -5,19 +5,18 @@
// Tests the Filter Editor Widget's add button
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/filterwidget.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
const select = widget.el.querySelector("select"),

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

@ -5,19 +5,18 @@
// Tests the Filter Editor Widget's remove button
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/filterwidget.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "blur(2px) contrast(200%)");
info("Test removing filters with remove button");

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

@ -6,18 +6,18 @@
// 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://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const FAST_VALUE_MULTIPLIER = 10;
const SLOW_VALUE_MULTIPLIER = 0.1;
const DEFAULT_VALUE_MULTIPLIER = 1;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
const initialValue = "blur(2px)";
let widget = new CSSFilterEditorWidget(container, initialValue);

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

@ -6,18 +6,18 @@
// 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://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const FAST_VALUE_MULTIPLIER = 10;
const SLOW_VALUE_MULTIPLIER = 0.1;
const DEFAULT_VALUE_MULTIPLIER = 1;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
const initialValue = "drop-shadow(rgb(0, 0, 0) 1px 1px 0px)";
let widget = new CSSFilterEditorWidget(container, initialValue);
widget.el.querySelector("#filters input").setSelectionRange(13, 13);

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

@ -6,18 +6,18 @@
// 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://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const FAST_VALUE_MULTIPLIER = 10;
const SLOW_VALUE_MULTIPLIER = 0.1;
const DEFAULT_VALUE_MULTIPLIER = 1;
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
yield addTab("about:blank");
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
const initialValue = "drop-shadow(rgb(0, 0, 0) 10px 1px 0px)";
let widget = new CSSFilterEditorWidget(container, initialValue);
const input = widget.el.querySelector("#filters input");

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

@ -5,15 +5,14 @@
// Tests saving presets
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
add_task(function* () {
yield addTab("about:blank");
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
// First render
yield widget.once("render");

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

@ -5,15 +5,14 @@
// Tests loading presets
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
add_task(function* () {
yield addTab("about:blank");
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
// First render
yield widget.once("render");

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

@ -5,15 +5,14 @@
// Tests deleting presets
const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
add_task(function* () {
yield addTab("about:blank");
const TEST_URI = `data:text/html,<div id="filter-container" />`;
add_task(function* () {
let [host, win, doc] = yield createHost("bottom", TEST_URI);
const container = doc.querySelector("#container");
const container = doc.querySelector("#filter-container");
let widget = new CSSFilterEditorWidget(container, "none");
// First render
yield widget.once("render");

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

@ -4,44 +4,42 @@
// Tests that the spectrum color picker works correctly
const TEST_URI = "chrome://devtools/content/shared/widgets/spectrum-frame.xhtml";
const {Spectrum} = require("devtools/client/shared/widgets/Spectrum");
add_task(function* () {
yield addTab("about:blank");
yield performTest();
gBrowser.removeCurrentTab();
});
const TEST_URI = `data:text/html,
<link rel="stylesheet" href="chrome://devtools/content/shared/widgets/spectrum.css" type="text/css"/>
<div id="spectrum-container" />`;
function* performTest() {
add_task(function* () {
let [host, win, doc] = yield createHost("bottom", TEST_URI);
yield testCreateAndDestroyShouldAppendAndRemoveElements(doc);
yield testPassingAColorAtInitShouldSetThatColor(doc);
yield testSettingAndGettingANewColor(doc);
yield testChangingColorShouldEmitEvents(doc);
yield testSettingColorShoudUpdateTheUI(doc);
let container = doc.getElementById("spectrum-container");
yield testCreateAndDestroyShouldAppendAndRemoveElements(container);
yield testPassingAColorAtInitShouldSetThatColor(container);
yield testSettingAndGettingANewColor(container);
yield testChangingColorShouldEmitEvents(container);
yield testSettingColorShoudUpdateTheUI(container);
host.destroy();
}
});
function testCreateAndDestroyShouldAppendAndRemoveElements(doc) {
let containerElement = doc.querySelector("#spectrum");
ok(containerElement, "We have the root node to append spectrum to");
is(containerElement.childElementCount, 0, "Root node is empty");
function testCreateAndDestroyShouldAppendAndRemoveElements(container) {
ok(container, "We have the root node to append spectrum to");
is(container.childElementCount, 0, "Root node is empty");
let s = new Spectrum(containerElement, [255, 126, 255, 1]);
let s = new Spectrum(container, [255, 126, 255, 1]);
s.show();
ok(containerElement.childElementCount > 0, "Spectrum has appended elements");
ok(container.childElementCount > 0, "Spectrum has appended elements");
s.destroy();
is(containerElement.childElementCount, 0, "Destroying spectrum removed all nodes");
is(container.childElementCount, 0, "Destroying spectrum removed all nodes");
}
function testPassingAColorAtInitShouldSetThatColor(doc) {
function testPassingAColorAtInitShouldSetThatColor(container) {
let initRgba = [255, 126, 255, 1];
let s = new Spectrum(doc.querySelector("#spectrum"), initRgba);
let s = new Spectrum(container, initRgba);
s.show();
let setRgba = s.rgb;
@ -54,8 +52,8 @@ function testPassingAColorAtInitShouldSetThatColor(doc) {
s.destroy();
}
function testSettingAndGettingANewColor(doc) {
let s = new Spectrum(doc.querySelector("#spectrum"), [0, 0, 0, 1]);
function testSettingAndGettingANewColor(container) {
let s = new Spectrum(container, [0, 0, 0, 1]);
s.show();
let colorToSet = [255, 255, 255, 1];
@ -70,9 +68,9 @@ function testSettingAndGettingANewColor(doc) {
s.destroy();
}
function testChangingColorShouldEmitEvents(doc) {
function testChangingColorShouldEmitEvents(container) {
return new Promise(resolve => {
let s = new Spectrum(doc.querySelector("#spectrum"), [255, 255, 255, 1]);
let s = new Spectrum(container, [255, 255, 255, 1]);
s.show();
s.once("changed", (event, rgba, color) => {
@ -92,8 +90,8 @@ function testChangingColorShouldEmitEvents(doc) {
});
}
function testSettingColorShoudUpdateTheUI(doc) {
let s = new Spectrum(doc.querySelector("#spectrum"), [255, 255, 255, 1]);
function testSettingColorShoudUpdateTheUI(container) {
let s = new Spectrum(container, [255, 255, 255, 1]);
s.show();
let dragHelperOriginalPos = [s.dragHelper.style.top, s.dragHelper.style.left];
let alphaHelperOriginalPos = s.alphaSliderHelper.style.left;

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

@ -32,6 +32,7 @@ const {
DEFAULT_PRESET_CATEGORY
} = require("devtools/client/shared/widgets/CubicBezierPresets");
const {getCSSLexer} = require("devtools/shared/css-lexer");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
/**
* CubicBezier data structure helper
@ -253,26 +254,24 @@ CubicBezierWidget.prototype = {
_initMarkup: function () {
let doc = this.parent.ownerDocument;
let wrap = doc.createElement("div");
let wrap = doc.createElementNS(XHTML_NS, "div");
wrap.className = "display-wrap";
let plane = doc.createElement("div");
let plane = doc.createElementNS(XHTML_NS, "div");
plane.className = "coordinate-plane";
let p1 = doc.createElement("button");
let p1 = doc.createElementNS(XHTML_NS, "button");
p1.className = "control-point";
p1.id = "P1";
plane.appendChild(p1);
let p2 = doc.createElement("button");
let p2 = doc.createElementNS(XHTML_NS, "button");
p2.className = "control-point";
p2.id = "P2";
plane.appendChild(p2);
let curve = doc.createElement("canvas");
let curve = doc.createElementNS(XHTML_NS, "canvas");
curve.setAttribute("width", 150);
curve.setAttribute("height", 370);
curve.id = "curve";
curve.className = "curve";
plane.appendChild(curve);
wrap.appendChild(plane);
@ -280,14 +279,14 @@ CubicBezierWidget.prototype = {
this.parent.appendChild(wrap);
return {
p1: p1,
p2: p2,
curve: curve
p1,
p2,
curve
};
},
_removeMarkup: function () {
this.parent.ownerDocument.querySelector(".display-wrap").remove();
this.parent.querySelector(".display-wrap").remove();
},
_initEvents: function () {
@ -519,13 +518,13 @@ CubicBezierPresetWidget.prototype = {
_initMarkup: function () {
let doc = this.parent.ownerDocument;
let presetPane = doc.createElement("div");
let presetPane = doc.createElementNS(XHTML_NS, "div");
presetPane.className = "preset-pane";
let categoryList = doc.createElement("div");
let categoryList = doc.createElementNS(XHTML_NS, "div");
categoryList.id = "preset-categories";
let presetContainer = doc.createElement("div");
let presetContainer = doc.createElementNS(XHTML_NS, "div");
presetContainer.id = "preset-container";
Object.keys(PRESETS).forEach(categoryLabel => {
@ -554,7 +553,7 @@ CubicBezierPresetWidget.prototype = {
_createCategory: function (categoryLabel) {
let doc = this.parent.ownerDocument;
let category = doc.createElement("div");
let category = doc.createElementNS(XHTML_NS, "div");
category.id = categoryLabel;
category.classList.add("category");
@ -572,7 +571,7 @@ CubicBezierPresetWidget.prototype = {
_createPresetList: function (categoryLabel) {
let doc = this.parent.ownerDocument;
let presetList = doc.createElement("div");
let presetList = doc.createElementNS(XHTML_NS, "div");
presetList.id = "preset-category-" + categoryLabel;
presetList.classList.add("preset-list");
@ -587,12 +586,12 @@ CubicBezierPresetWidget.prototype = {
_createPreset: function (categoryLabel, presetLabel) {
let doc = this.parent.ownerDocument;
let preset = doc.createElement("div");
let preset = doc.createElementNS(XHTML_NS, "div");
preset.classList.add("preset");
preset.id = presetLabel;
preset.coordinates = PRESETS[categoryLabel][presetLabel];
// Create preset preview
let curve = doc.createElement("canvas");
let curve = doc.createElementNS(XHTML_NS, "canvas");
let bezier = new CubicBezier(preset.coordinates);
curve.setAttribute("height", 50);
curve.setAttribute("width", 50);
@ -604,7 +603,7 @@ CubicBezierPresetWidget.prototype = {
preset.appendChild(curve);
// Create preset label
let presetLabelElem = doc.createElement("p");
let presetLabelElem = doc.createElementNS(XHTML_NS, "p");
let presetDisplayLabel = this._normalizePresetLabel(categoryLabel,
presetLabel);
presetLabelElem.textContent = presetDisplayLabel;
@ -734,14 +733,14 @@ TimingFunctionPreviewWidget.prototype = {
_initMarkup: function () {
let doc = this.parent.ownerDocument;
let container = doc.createElement("div");
let container = doc.createElementNS(XHTML_NS, "div");
container.className = "timing-function-preview";
this.dot = doc.createElement("div");
this.dot = doc.createElementNS(XHTML_NS, "div");
this.dot.className = "dot";
container.appendChild(this.dot);
let scale = doc.createElement("div");
let scale = doc.createElementNS(XHTML_NS, "div");
scale.className = "scale";
container.appendChild(scale);
@ -780,12 +779,17 @@ TimingFunctionPreviewWidget.prototype = {
* Re-start the preview animation from the beginning
*/
restartAnimation: function () {
// Reset the animation duration in case it was changed
this.dot.style.animationDuration = (this.PREVIEW_DURATION * 2) + "ms";
// Just toggling the class won't do it unless there's a sync reflow
this.dot.classList.remove("animate");
this.dot.classList.add("animate");
this.dot.animate([
{ left: "-7px", offset: 0 },
{ left: "143px", offset: 0.25 },
{ left: "143px", offset: 0.5 },
{ left: "-7px", offset: 0.75 },
{ left: "-7px", offset: 1 }
], {
duration: (this.PREVIEW_DURATION * 2),
fill: "forwards"
});
// Restart it again after a while
this.autoRestartAnimation = setTimeout(this.restartAnimation.bind(this),

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

@ -11,6 +11,7 @@
const EventEmitter = require("devtools/shared/event-emitter");
const { Cc, Ci } = require("chrome");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/filterwidget.properties";
@ -151,6 +152,34 @@ exports.CSSFilterEditorWidget = CSSFilterEditorWidget;
CSSFilterEditorWidget.prototype = {
_initMarkup: function () {
let filterListSelectPlaceholder =
L10N.getStr("filterListSelectPlaceholder");
let addNewFilterButton = L10N.getStr("addNewFilterButton");
let presetsToggleButton = L10N.getStr("presetsToggleButton");
let newPresetPlaceholder = L10N.getStr("newPresetPlaceholder");
let savePresetButton = L10N.getStr("savePresetButton");
this.el.innerHTML = `
<div class="filters-list">
<div id="filters"></div>
<div class="footer">
<select value="">
<option value="">${filterListSelectPlaceholder}</option>
</select>
<button id="add-filter" class="add">${addNewFilterButton}</button>
<button id="toggle-presets">${presetsToggleButton}</button>
</div>
</div>
<div class="presets-list">
<div id="presets"></div>
<div class="footer">
<input value="" class="devtools-textinput"
placeholder="${newPresetPlaceholder}"></input>
<button class="add">${savePresetButton}</button>
</div>
</div>
`;
this.filtersList = this.el.querySelector("#filters");
this.presetsList = this.el.querySelector("#presets");
this.togglePresets = this.el.querySelector("#toggle-presets");
@ -183,7 +212,7 @@ CSSFilterEditorWidget.prototype = {
_populateFilterSelect: function () {
let select = this.filterSelect;
filterList.forEach(filter => {
let option = this.doc.createElement("option");
let option = this.doc.createElementNS(XHTML_NS, "option");
option.innerHTML = option.value = filter.name;
select.appendChild(option);
});
@ -193,31 +222,31 @@ CSSFilterEditorWidget.prototype = {
* Creates a template for filter elements which is cloned and used in render
*/
_buildFilterItemMarkup: function () {
let base = this.doc.createElement("div");
let base = this.doc.createElementNS(XHTML_NS, "div");
base.className = "filter";
let name = this.doc.createElement("div");
let name = this.doc.createElementNS(XHTML_NS, "div");
name.className = "filter-name";
let value = this.doc.createElement("div");
let value = this.doc.createElementNS(XHTML_NS, "div");
value.className = "filter-value";
let drag = this.doc.createElement("i");
let drag = this.doc.createElementNS(XHTML_NS, "i");
drag.title = L10N.getStr("dragHandleTooltipText");
let label = this.doc.createElement("label");
let label = this.doc.createElementNS(XHTML_NS, "label");
name.appendChild(drag);
name.appendChild(label);
let unitPreview = this.doc.createElement("span");
let input = this.doc.createElement("input");
let unitPreview = this.doc.createElementNS(XHTML_NS, "span");
let input = this.doc.createElementNS(XHTML_NS, "input");
input.classList.add("devtools-textinput");
value.appendChild(input);
value.appendChild(unitPreview);
let removeButton = this.doc.createElement("button");
let removeButton = this.doc.createElementNS(XHTML_NS, "button");
removeButton.className = "remove-button";
base.appendChild(name);
@ -228,16 +257,16 @@ CSSFilterEditorWidget.prototype = {
},
_buildPresetItemMarkup: function () {
let base = this.doc.createElement("div");
let base = this.doc.createElementNS(XHTML_NS, "div");
base.classList.add("preset");
let name = this.doc.createElement("label");
let name = this.doc.createElementNS(XHTML_NS, "label");
base.appendChild(name);
let value = this.doc.createElement("span");
let value = this.doc.createElementNS(XHTML_NS, "span");
base.appendChild(value);
let removeButton = this.doc.createElement("button");
let removeButton = this.doc.createElementNS(XHTML_NS, "button");
removeButton.classList.add("remove-button");
base.appendChild(removeButton);
@ -659,6 +688,11 @@ CSSFilterEditorWidget.prototype = {
renderPresets: function () {
this.getPresets().then(presets => {
// getPresets is async and the widget may be destroyed in between.
if (!this.presetsList) {
return;
}
if (!presets || !presets.length) {
this.presetsList.innerHTML = `<p>${L10N.getStr("emptyPresetList")}</p>`;
this.emit("render");

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

@ -5,6 +5,7 @@
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
/**
* Spectrum creates a color picker widget in any container you give it.
@ -32,7 +33,7 @@ const EventEmitter = require("devtools/shared/event-emitter");
function Spectrum(parentEl, rgb) {
EventEmitter.decorate(this);
this.element = parentEl.ownerDocument.createElement("div");
this.element = parentEl.ownerDocument.createElementNS(XHTML_NS, "div");
this.parentEl = parentEl;
this.element.className = "spectrum-container";
@ -131,21 +132,6 @@ Spectrum.rgbToHsv = function (r, g, b, a) {
return [h, s, v, a];
};
Spectrum.getOffset = function (el) {
let curleft = 0, curtop = 0;
if (el.offsetParent) {
while (el) {
curleft += el.offsetLeft;
curtop += el.offsetTop;
el = el.offsetParent;
}
}
return {
left: curleft,
top: curtop
};
};
Spectrum.draggable = function (element, onmove, onstart, onstop) {
onmove = onmove || function () {};
onstart = onstart || function () {};
@ -188,7 +174,7 @@ Spectrum.draggable = function (element, onmove, onstart, onstop) {
maxHeight = element.offsetHeight;
maxWidth = element.offsetWidth;
offset = Spectrum.getOffset(element);
offset = element.getBoundingClientRect();
move(e);

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

@ -19,6 +19,8 @@ const {Eyedropper} = require("devtools/client/eyedropper/eyedropper");
const {gDevTools} = require("devtools/client/framework/devtools");
const Services = require("Services");
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
@ -31,11 +33,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
"resource://devtools/client/shared/widgets/VariablesViewController.jsm");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const SPECTRUM_FRAME = "chrome://devtools/content/shared/widgets/spectrum-frame.xhtml";
const CUBIC_BEZIER_FRAME =
"chrome://devtools/content/shared/widgets/cubic-bezier-frame.xhtml";
const MDN_DOCS_FRAME = "chrome://devtools/content/shared/widgets/mdn-docs-frame.xhtml";
const FILTER_FRAME = "chrome://devtools/content/shared/widgets/filter-frame.xhtml";
const ESCAPE_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE;
const RETURN_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_RETURN;
const POPUP_EVENTS = ["shown", "hidden", "showing", "hiding"];
@ -557,99 +555,6 @@ Tooltip.prototype = {
return def.promise;
},
/**
* Fill the tooltip with a new instance of the spectrum color picker widget
* initialized with the given color, and return a promise that resolves to
* the instance of spectrum
*/
setColorPickerContent: function (color) {
let dimensions = {width: "210", height: "216"};
let panel = this.panel;
return this.setIFrameContent(dimensions, SPECTRUM_FRAME).then(onLoaded);
function onLoaded(iframe) {
let win = iframe.contentWindow.wrappedJSObject;
let def = defer();
let container = win.document.getElementById("spectrum");
let spectrum = new Spectrum(container, color);
function finalizeSpectrum() {
spectrum.show();
def.resolve(spectrum);
}
// Finalize spectrum's init when the tooltip becomes visible
if (panel.state == "open") {
finalizeSpectrum();
} else {
panel.addEventListener("popupshown", function shown() {
panel.removeEventListener("popupshown", shown, true);
finalizeSpectrum();
}, true);
}
return def.promise;
}
},
/**
* Fill the tooltip with a new instance of the cubic-bezier widget
* initialized with the given value, and return a promise that resolves to
* the instance of the widget
*/
setCubicBezierContent: function (bezier) {
let dimensions = {width: "500", height: "360"};
let panel = this.panel;
return this.setIFrameContent(dimensions, CUBIC_BEZIER_FRAME).then(onLoaded);
function onLoaded(iframe) {
let win = iframe.contentWindow.wrappedJSObject;
let def = defer();
let container = win.document.getElementById("container");
let widget = new CubicBezierWidget(container, bezier);
// Resolve to the widget instance whenever the popup becomes visible
if (panel.state == "open") {
def.resolve(widget);
} else {
panel.addEventListener("popupshown", function shown() {
panel.removeEventListener("popupshown", shown, true);
def.resolve(widget);
}, true);
}
return def.promise;
}
},
/**
* Fill the tooltip with a new instance of the CSSFilterEditorWidget
* widget initialized with the given filter value, and return a promise
* that resolves to the instance of the widget when ready.
*/
setFilterContent: function (filter) {
let dimensions = {width: "500", height: "200"};
let panel = this.panel;
return this.setIFrameContent(dimensions, FILTER_FRAME).then(onLoaded);
function onLoaded(iframe) {
let win = iframe.contentWindow.wrappedJSObject;
let def = defer();
let container = win.document.getElementById("container");
let widget = new CSSFilterEditorWidget(container, filter);
// Resolve to the widget instance whenever the popup becomes visible
if (panel.state === "open") {
def.resolve(widget);
} else {
panel.addEventListener("popupshown", function shown() {
panel.removeEventListener("popupshown", shown, true);
def.resolve(widget);
}, true);
}
return def.promise;
}
},
/**
* Set the content of this tooltip to the MDN docs widget.
*
@ -681,29 +586,44 @@ Tooltip.prototype = {
* Base class for all (color, gradient, ...)-swatch based value editors inside
* tooltips
*
* @param {XULDocument} doc
* @param {Toolbox} toolbox
* The devtools toolbox, needed to get the devtools main window.
*/
function SwatchBasedEditorTooltip(doc) {
function SwatchBasedEditorTooltip(toolbox, stylesheet) {
// Creating a tooltip instance
// This one will consume outside clicks as it makes more sense to let the user
// close the tooltip by clicking out
// It will also close on <escape> and <enter>
this.tooltip = new Tooltip(doc, {
consumeOutsideClick: true,
closeOnKeys: [ESCAPE_KEYCODE, RETURN_KEYCODE],
noAutoFocus: false
this.tooltip = new HTMLTooltip(toolbox, {
type: "arrow",
consumeOutsideClicks: true,
useXulWrapper: true,
stylesheet
});
// By default, swatch-based editor tooltips revert value change on <esc> and
// commit value change on <enter>
this._onTooltipKeypress = (event, code) => {
if (code === ESCAPE_KEYCODE) {
this.revert();
} else if (code === RETURN_KEYCODE) {
this.commit();
this.shortcuts = new KeyShortcuts({
window: this.tooltip.topWindow
});
this.shortcuts.on("Escape", (name, event) => {
if (!this.tooltip.isVisible()) {
return;
}
};
this.tooltip.on("keypress", this._onTooltipKeypress);
this.revert();
this.hide();
event.stopPropagation();
event.preventDefault();
});
this.shortcuts.on("Return", (name, event) => {
if (!this.tooltip.isVisible()) {
return;
}
this.commit();
this.hide();
event.stopPropagation();
event.preventDefault();
});
// All target swatches are kept in a map, indexed by swatch DOM elements
this.swatches = new Map();
@ -722,18 +642,14 @@ SwatchBasedEditorTooltip.prototype = {
this.tooltip.show(this.activeSwatch, "topcenter bottomleft");
// When the tooltip is closed by clicking outside the panel we want to
// commit any changes. Because the "hidden" event destroys the tooltip we
// need to do this before the tooltip is destroyed (in the "hiding"
// event).
this.tooltip.once("hiding", () => {
// commit any changes.
this.tooltip.once("hidden", () => {
if (!this._reverted && !this.eyedropperOpen) {
this.commit();
}
this._reverted = false;
});
// Once the tooltip is hidden we need to clean up any remaining objects.
this.tooltip.once("hidden", () => {
// Once the tooltip is hidden we need to clean up any remaining objects.
if (!this.eyedropperOpen) {
this.activeSwatch = null;
}
@ -825,7 +741,7 @@ SwatchBasedEditorTooltip.prototype = {
if (this.activeSwatch) {
this._reverted = true;
let swatch = this.swatches.get(this.activeSwatch);
this.tooltip.once("hiding", () => {
this.tooltip.once("hidden", () => {
swatch.callbacks.onRevert();
});
}
@ -846,6 +762,7 @@ SwatchBasedEditorTooltip.prototype = {
this.activeSwatch = null;
this.tooltip.off("keypress", this._onTooltipKeypress);
this.tooltip.destroy();
this.shortcuts.destroy();
}
};
@ -856,14 +773,16 @@ SwatchBasedEditorTooltip.prototype = {
* It just wraps a standard Tooltip and sets its content with an instance of a
* color picker.
*
* @param {XULDocument} doc
* @param {Toolbox} toolbox
* The devtools toolbox, needed to get the devtools main window.
*/
function SwatchColorPickerTooltip(doc) {
SwatchBasedEditorTooltip.call(this, doc);
function SwatchColorPickerTooltip(toolbox) {
let stylesheet = "chrome://devtools/content/shared/widgets/spectrum.css";
SwatchBasedEditorTooltip.call(this, toolbox, stylesheet);
// Creating a spectrum instance. this.spectrum will always be a promise that
// resolves to the spectrum instance
this.spectrum = this.tooltip.setColorPickerContent([0, 0, 0, 1]);
this.spectrum = this.setColorPickerContent([0, 0, 0, 1]);
this._onSpectrumColorChange = this._onSpectrumColorChange.bind(this);
this._openEyeDropper = this._openEyeDropper.bind(this);
}
@ -872,6 +791,36 @@ module.exports.SwatchColorPickerTooltip = SwatchColorPickerTooltip;
SwatchColorPickerTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the spectrum color picker widget
* initialized with the given color, and return the instance of spectrum
*/
setColorPickerContent: function (color) {
let { doc } = this.tooltip;
let container = doc.createElementNS(XHTML_NS, "div");
container.id = "spectrum-tooltip";
let spectrumNode = doc.createElementNS(XHTML_NS, "div");
spectrumNode.id = "spectrum";
container.appendChild(spectrumNode);
let eyedropper = doc.createElementNS(XHTML_NS, "button");
eyedropper.id = "eyedropper-button";
eyedropper.className = "devtools-button";
container.appendChild(eyedropper);
this.tooltip.setContent(container, { width: 210, height: 216 });
let spectrum = new Spectrum(spectrumNode, color);
// Wait for the tooltip to be shown before calling spectrum.show
// as it expect to be visible in order to compute DOM element sizes.
this.tooltip.once("shown", () => {
spectrum.show();
});
return spectrum;
},
/**
* Overriding the SwatchBasedEditorTooltip.show function to set spectrum's
* color.
@ -884,16 +833,13 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
this.currentSwatchColor = this.activeSwatch.nextSibling;
this._originalColor = this.currentSwatchColor.textContent;
let color = this.activeSwatch.style.backgroundColor;
this.spectrum.then(spectrum => {
spectrum.off("changed", this._onSpectrumColorChange);
spectrum.rgb = this._colorToRgba(color);
spectrum.on("changed", this._onSpectrumColorChange);
spectrum.updateUI();
});
this.spectrum.off("changed", this._onSpectrumColorChange);
this.spectrum.rgb = this._colorToRgba(color);
this.spectrum.on("changed", this._onSpectrumColorChange);
this.spectrum.updateUI();
}
let tooltipDoc = this.tooltip.content.contentDocument;
let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
let eyeButton = this.tooltip.doc.querySelector("#eyedropper-button");
eyeButton.addEventListener("click", this._openEyeDropper);
},
@ -967,10 +913,8 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
destroy: function () {
SwatchBasedEditorTooltip.prototype.destroy.call(this);
this.currentSwatchColor = null;
this.spectrum.then(spectrum => {
spectrum.off("changed", this._onSpectrumColorChange);
spectrum.destroy();
});
this.spectrum.off("changed", this._onSpectrumColorChange);
this.spectrum.destroy();
}
});
@ -981,14 +925,16 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
* It just wraps a standard Tooltip and sets its content with an instance of a
* CubicBezierWidget.
*
* @param {XULDocument} doc
* @param {Toolbox} toolbox
* The devtools toolbox, needed to get the devtools main window.
*/
function SwatchCubicBezierTooltip(doc) {
SwatchBasedEditorTooltip.call(this, doc);
function SwatchCubicBezierTooltip(toolbox) {
let stylesheet = "chrome://devtools/content/shared/widgets/cubic-bezier.css";
SwatchBasedEditorTooltip.call(this, toolbox, stylesheet);
// Creating a cubic-bezier instance.
// this.widget will always be a promise that resolves to the widget instance
this.widget = this.tooltip.setCubicBezierContent([0, 0, 1, 1]);
this.widget = this.setCubicBezierContent([0, 0, 1, 1]);
this._onUpdate = this._onUpdate.bind(this);
}
@ -996,6 +942,31 @@ module.exports.SwatchCubicBezierTooltip = SwatchCubicBezierTooltip;
SwatchCubicBezierTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the cubic-bezier widget
* initialized with the given value, and return a promise that resolves to
* the instance of the widget
*/
setCubicBezierContent: function (bezier) {
let { doc } = this.tooltip;
let container = doc.createElementNS(XHTML_NS, "div");
container.className = "cubic-bezier-container";
this.tooltip.setContent(container, { width: 510, height: 370 });
let def = defer();
// Wait for the tooltip to be shown before calling instanciating the widget
// as it expect its DOM elements to be visible.
this.tooltip.once("shown", () => {
let widget = new CubicBezierWidget(container, bezier);
def.resolve(widget);
});
return def.promise;
},
/**
* Overriding the SwatchBasedEditorTooltip.show function to set the cubic
* bezier curve in the widget
@ -1079,14 +1050,15 @@ CssDocsTooltip.prototype = {
* It just wraps a standard Tooltip and sets its content with an instance of a
* CSSFilterEditorWidget.
*
* @param {XULDocument} doc
* @param {Toolbox} toolbox
* The devtools toolbox, needed to get the devtools main window.
*/
function SwatchFilterTooltip(doc) {
SwatchBasedEditorTooltip.call(this, doc);
function SwatchFilterTooltip(toolbox) {
let stylesheet = "chrome://devtools/content/shared/widgets/filter-widget.css";
SwatchBasedEditorTooltip.call(this, toolbox, stylesheet);
// Creating a filter editor instance.
// this.widget will always be a promise that resolves to the widget instance
this.widget = this.tooltip.setFilterContent("none");
this.widget = this.setFilterContent("none");
this._onUpdate = this._onUpdate.bind(this);
}
@ -1094,18 +1066,32 @@ exports.SwatchFilterTooltip = SwatchFilterTooltip;
SwatchFilterTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the CSSFilterEditorWidget
* widget initialized with the given filter value, and return a promise
* that resolves to the instance of the widget when ready.
*/
setFilterContent: function (filter) {
let { doc } = this.tooltip;
let container = doc.createElementNS(XHTML_NS, "div");
container.id = "filter-container";
this.tooltip.setContent(container, { width: 510, height: 200 });
return new CSSFilterEditorWidget(container, filter);
},
show: function () {
// Call the parent class' show function
SwatchBasedEditorTooltip.prototype.show.call(this);
// Then set the filter value and listen to changes to preview them
if (this.activeSwatch) {
this.currentFilterValue = this.activeSwatch.nextSibling;
this.widget.then(widget => {
widget.off("updated", this._onUpdate);
widget.on("updated", this._onUpdate);
widget.setCssValue(this.currentFilterValue.textContent);
widget.render();
});
this.widget.off("updated", this._onUpdate);
this.widget.on("updated", this._onUpdate);
this.widget.setCssValue(this.currentFilterValue.textContent);
this.widget.render();
}
},
@ -1128,10 +1114,8 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
destroy: function () {
SwatchBasedEditorTooltip.prototype.destroy.call(this);
this.currentFilterValue = null;
this.widget.then(widget => {
widget.off("updated", this._onUpdate);
widget.destroy();
});
this.widget.off("updated", this._onUpdate);
this.widget.destroy();
},
/**

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

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://devtools/content/shared/widgets/cubic-bezier.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"/>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
width: 500px;
height: 370px;
}
</style>
</head>
<body role="application">
<div id="container"></div>
</body>
</html>

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

@ -5,12 +5,13 @@
/* Based on Lea Verou www.cubic-bezier.com
See https://github.com/LeaVerou/cubic-bezier */
#container {
.cubic-bezier-container {
display: flex;
width: 500px;
height: 370px;
flex-direction: row-reverse;
overflow: hidden;
padding: 5px;
}
.display-wrap {
@ -64,13 +65,13 @@
-moz-user-select: none;
}
canvas#curve {
canvas.curve {
background: linear-gradient(-45deg, transparent 49.7%, rgba(0,0,0,.2) 49.7%, rgba(0,0,0,.2) 50.3%, transparent 50.3%) center no-repeat;
background-size: 100% 100%;
background-position: 0 0;
}
.theme-dark canvas#curve {
.theme-dark canvas.curve {
background: linear-gradient(-45deg, transparent 49.7%, #eee 49.7%, #eee 50.3%, transparent 50.3%) center no-repeat;
}
@ -109,30 +110,6 @@ canvas#curve {
background: #4C9ED9;
}
.timing-function-preview .dot.animate {
animation-duration: 2.5s;
animation-fill-mode: forwards;
animation-name: timing-function-preview;
}
@keyframes timing-function-preview {
0% {
left: -7px;
}
33% {
left: 143px;
}
50% {
left: 143px;
}
83% {
left: -7px;
}
100% {
left: -7px;
}
}
/* Preset Widget */
.preset-pane {

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

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % filterwidgetDTD SYSTEM "chrome://devtools/locale/filterwidget.dtd" >
%filterwidgetDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://devtools/content/shared/widgets/filter-widget.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"></script>
</head>
<body>
<div id="container">
<div class="filters-list">
<div id="filters"></div>
<div class="footer">
<select value="">
<option value="">&filterListSelectPlaceholder;</option>
</select>
<button id="add-filter" class="add">&addNewFilterButton;</button>
<button id="toggle-presets">&presetsToggleButton;</button>
</div>
</div>
<div class="presets-list">
<div id="presets"></div>
<div class="footer">
<input value="" class="devtools-textinput"
placeholder="&newPresetPlaceholder;"></input>
<button class="add">&savePresetButton;</button>
</div>
</div>
</div>
</body>
</html>

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

@ -2,23 +2,18 @@
* 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/. */
html, body {
height: 100%;
margin: 0;
overflow: hidden;
font: message-box;
color: var(--theme-body-color);
}
/* Main container: Displays the filters and presets in 2 columns */
#container {
#filter-container {
height: 100%;
display: flex;
position: relative;
padding: 5px;
/* when opened in a xul:panel, a gray color is applied to text */
color: var(--theme-body-color);
}
#container.dragging {
#filter-container.dragging {
-moz-user-select: none;
}
@ -49,13 +44,13 @@ html, body {
margin-top: 4px;
}
#container:not(.show-presets) .presets-list {
#filter-container:not(.show-presets) .presets-list {
width: 0;
border-left: none;
padding-left: 0;
}
#container.show-presets .filters-list {
#filter-container.show-presets .filters-list {
width: 300px;
}
@ -211,14 +206,14 @@ input {
display: none !important;
}
#container .dragging {
#filter-container .dragging {
position: relative;
z-index: 10;
cursor: grab;
}
/* message shown when there's no filter specified */
#container p {
#filter-container p {
text-align: center;
line-height: 20px;
}

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

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://devtools/skin/spectrum.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"/>
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body role="application">
<div id="spectrum"></div>
<button id="eyedropper-button" class="devtools-button"></button>
</body>
</html>

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

@ -3,7 +3,6 @@
* 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/. */
/* Tooltip widget (see devtools/client/shared/widgets/Tooltip.js) */
.devtools-tooltip .panel-arrowcontent {