Bug 1262439 - 4 - Use the new eye-dropper highlighter in the color-picker tooltip; r=bgrins
The color-picker tooltip now uses the new eye-dropper highlighter, by
using the pickColorFromPage inspector method instead of the XUL-based
eye-dropper tool.
Telemetry hasn't yet been re-implemented in the new eye-dropper highlighter
so the telemetry-related test code has been removed for now. This will be
added again in a later commit.
MozReview-Commit-ID: enSzSKHac4
--- a/devtools/client/inspector/rules/test/browser_rules_eyedropper.js
+++ b/devtools/client/inspector/rules/test/browser_rules_eyedropper.js
@@ -1,24 +1,15 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
-
"use strict";
-// So we can test collecting telemetry on the eyedropper
-var oldCanRecord = Services.telemetry.canRecordExtended;
-Services.telemetry.canRecordExtended = true;
-registerCleanupFunction(function () {
- Services.telemetry.canRecordExtended = oldCanRecord;
-});
-const EXPECTED_TELEMETRY = {
- "DEVTOOLS_PICKER_EYEDROPPER_OPENED_COUNT": 2,
- "DEVTOOLS_PICKER_EYEDROPPER_OPENED_PER_USER_FLAG": 1
-};
+// Test opening the eyedropper from the color picker. Pressing escape to close it, and
+// clicking the page to select a color.
const TEST_URI = `
<style type="text/css">
body {
background-color: white;
padding: 0px
}
@@ -38,152 +29,89 @@ const TEST_URI = `
<body><div id="div1"></div><div id="div2"></div></body>
`;
// #f09
const ORIGINAL_COLOR = "rgb(255, 0, 153)";
// #ff5
const EXPECTED_COLOR = "rgb(255, 255, 85)";
-// Test opening the eyedropper from the color picker. Pressing escape
-// to close it, and clicking the page to select a color.
-
add_task(function* () {
- // clear telemetry so we can get accurate counts
- clearTelemetry();
-
+ info("Add the test tab, open the rule-view and select the test node");
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
- let {inspector, view} = yield openRuleView();
+ let {testActor, inspector, view} = yield openRuleView();
yield selectNode("#div2", inspector);
+ info("Get the background-color property from the rule-view");
let property = getRuleViewProperty(view, "#div2", "background-color");
let swatch = property.valueSpan.querySelector(".ruleview-colorswatch");
ok(swatch, "Color swatch is displayed for the bg-color property");
- let dropper = yield openEyedropper(view, swatch);
+ info("Open the eyedropper from the colorpicker tooltip");
+ yield openEyedropper(view, swatch);
let tooltip = view.tooltips.colorPicker.tooltip;
- ok(tooltip.isHidden(),
- "color picker tooltip is closed after opening eyedropper");
+ ok(tooltip.isHidden(), "color picker tooltip is closed after opening eyedropper");
- yield testESC(swatch, dropper);
+ info("Test that pressing escape dismisses the eyedropper");
+ yield testESC(swatch, inspector, testActor);
- dropper = yield openEyedropper(view, swatch);
-
- ok(dropper, "dropper opened");
+ info("Open the eyedropper again");
+ yield openEyedropper(view, swatch);
- yield testSelect(view, swatch, dropper);
-
- checkTelemetry();
+ info("Test that a color can be selected with the eyedropper");
+ yield testSelect(view, swatch, inspector, testActor);
});
-function testESC(swatch, dropper) {
- let deferred = defer();
-
- dropper.once("destroy", () => {
- let color = swatch.style.backgroundColor;
- is(color, ORIGINAL_COLOR, "swatch didn't change after pressing ESC");
+function* testESC(swatch, inspector, testActor) {
+ info("Press escape");
+ let onCanceled = new Promise(resolve => {
+ inspector.inspector.once("color-pick-canceled", resolve);
+ });
+ yield testActor.synthesizeKey({key: "VK_ESCAPE", options: {}});
+ yield onCanceled;
- deferred.resolve();
- });
-
- inspectPage(dropper, false).then(pressESC);
-
- return deferred.promise;
+ let color = swatch.style.backgroundColor;
+ is(color, ORIGINAL_COLOR, "swatch didn't change after pressing ESC");
}
-function* testSelect(view, swatch, dropper) {
- let onDestroyed = dropper.once("destroy");
- // the change to the content is done async after rule view change
+function* testSelect(view, swatch, inspector, testActor) {
+ info("Click at x:10px y:10px");
+ let onPicked = new Promise(resolve => {
+ inspector.inspector.once("color-picked", resolve);
+ });
+ // The change to the content is done async after rule view change
let onRuleViewChanged = view.once("ruleview-changed");
- inspectPage(dropper);
+ yield testActor.synthesizeMouse({selector: "html", x: 10, y: 10,
+ options: {type: "mousemove"}});
+ yield testActor.synthesizeMouse({selector: "html", x: 10, y: 10,
+ options: {type: "mousedown"}});
+ yield testActor.synthesizeMouse({selector: "html", x: 10, y: 10,
+ options: {type: "mouseup"}});
- yield onDestroyed;
+ yield onPicked;
yield onRuleViewChanged;
let color = swatch.style.backgroundColor;
is(color, EXPECTED_COLOR, "swatch changed colors");
is((yield getComputedStyleProperty("div", null, "background-color")),
EXPECTED_COLOR,
"div's color set to body color after dropper");
}
-function clearTelemetry() {
- for (let histogramId in EXPECTED_TELEMETRY) {
- let histogram = Services.telemetry.getHistogramById(histogramId);
- histogram.clear();
- }
-}
-
-function checkTelemetry() {
- for (let histogramId in EXPECTED_TELEMETRY) {
- let expected = EXPECTED_TELEMETRY[histogramId];
- let histogram = Services.telemetry.getHistogramById(histogramId);
- let snapshot = histogram.snapshot();
-
- is(snapshot.sum, expected,
- "eyedropper telemetry value correct for " + histogramId);
- }
-}
-
-/* Helpers */
-
-function openEyedropper(view, swatch) {
- let deferred = defer();
-
+function* openEyedropper(view, swatch) {
let tooltip = view.tooltips.colorPicker.tooltip;
- tooltip.once("shown", () => {
- let tooltipDoc = tooltip.content.contentDocument;
- let dropperButton = tooltipDoc.querySelector("#eyedropper-button");
-
- tooltip.once("eyedropper-opened", (event, dropper) => {
- deferred.resolve(dropper);
- });
- dropperButton.click();
- });
-
+ info("Click on the swatch");
+ let onShown = tooltip.once("shown");
swatch.click();
- return deferred.promise;
-}
-
-function inspectPage(dropper, click = true) {
- let target = document.documentElement;
- let win = window;
-
- // get location of the content, offset from browser window
- let box = gBrowser.selectedBrowser.getBoundingClientRect();
- let x = box.left + 1;
- let y = box.top + 1;
-
- return dropperStarted(dropper).then(() => {
- EventUtils.synthesizeMouse(target, x, y, { type: "mousemove" }, win);
+ yield onShown;
- return dropperLoaded(dropper).then(() => {
- EventUtils.synthesizeMouse(target, x + 10, y + 10,
- { type: "mousemove" }, win);
-
- if (click) {
- EventUtils.synthesizeMouse(target, x + 10, y + 10, {}, win);
- }
- });
- });
-}
+ let tooltipDoc = tooltip.content.contentDocument;
+ let dropperButton = tooltipDoc.querySelector("#eyedropper-button");
-function dropperStarted(dropper) {
- if (dropper.isStarted) {
- return promise.resolve();
- }
- return dropper.once("started");
+ info("Click on the eyedropper icon");
+ let onOpened = tooltip.once("eyedropper-opened");
+ dropperButton.click();
+ yield onOpened;
}
-
-function dropperLoaded(dropper) {
- if (dropper.loaded) {
- return promise.resolve();
- }
- return dropper.once("load");
-}
-
-function pressESC() {
- EventUtils.synthesizeKey("VK_ESCAPE", { });
-}
--- a/devtools/client/inspector/shared/style-inspector-overlays.js
+++ b/devtools/client/inspector/shared/style-inspector-overlays.js
@@ -285,17 +285,17 @@ TooltipsOverlay.prototype = {
this.previewTooltip.startTogglingOnHover(this.view.element,
this._onPreviewTooltipTargetHover.bind(this));
// MDN CSS help tooltip
this.cssDocs = new CssDocsTooltip(panelDoc);
if (this.isRuleView) {
// Color picker tooltip
- this.colorPicker = new SwatchColorPickerTooltip(panelDoc);
+ this.colorPicker = new SwatchColorPickerTooltip(panelDoc, this.view.inspector);
// Cubic bezier tooltip
this.cubicBezier = new SwatchCubicBezierTooltip(panelDoc);
// Filter editor tooltip
this.filterEditor = new SwatchFilterTooltip(panelDoc);
}
this._isStarted = true;
},
--- a/devtools/client/shared/widgets/Tooltip.js
+++ b/devtools/client/shared/widgets/Tooltip.js
@@ -10,17 +10,16 @@ const {Spectrum} = require("devtools/cli
const {CubicBezierWidget} =
require("devtools/client/shared/widgets/CubicBezierWidget");
const {MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget");
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const {TooltipToggle} = require("devtools/client/shared/widgets/tooltip/TooltipToggle");
const EventEmitter = require("devtools/shared/event-emitter");
const {colorUtils} = require("devtools/shared/css-color");
const Heritage = require("sdk/core/heritage");
-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");
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
loader.lazyRequireGetter(this, "clearNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
@@ -853,19 +852,21 @@ SwatchBasedEditorTooltip.prototype = {
* The swatch color picker tooltip class is a specific class meant to be used
* along with output-parser's generated color swatches.
* It extends the parent SwatchBasedEditorTooltip class.
* It just wraps a standard Tooltip and sets its content with an instance of a
* color picker.
*
* @param {XULDocument} doc
*/
-function SwatchColorPickerTooltip(doc) {
+function SwatchColorPickerTooltip(doc, inspector) {
SwatchBasedEditorTooltip.call(this, doc);
+ this.inspector = inspector;
+
// 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._onSpectrumColorChange = this._onSpectrumColorChange.bind(this);
this._openEyeDropper = this._openEyeDropper.bind(this);
}
module.exports.SwatchColorPickerTooltip = SwatchColorPickerTooltip;
@@ -887,19 +888,26 @@ Heritage.extend(SwatchBasedEditorTooltip
this.spectrum.then(spectrum => {
spectrum.off("changed", this._onSpectrumColorChange);
spectrum.rgb = this._colorToRgba(color);
spectrum.on("changed", this._onSpectrumColorChange);
spectrum.updateUI();
});
}
- let tooltipDoc = this.tooltip.content.contentDocument;
- let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
- eyeButton.addEventListener("click", this._openEyeDropper);
+ let {target} = this.inspector.toolbox;
+ target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
+ let tooltipDoc = this.tooltip.content.contentDocument;
+ let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
+ if (value) {
+ eyeButton.addEventListener("click", this._openEyeDropper);
+ } else {
+ eyeButton.style.display = "none";
+ }
+ }, e => console.error(e));
},
_onSpectrumColorChange: function (event, rgba, cssColor) {
this._selectColor(cssColor);
},
_selectColor: function (color) {
if (this.activeSwatch) {
@@ -912,65 +920,52 @@ Heritage.extend(SwatchBasedEditorTooltip
if (this.eyedropperOpen) {
this.commit();
}
}
},
_openEyeDropper: function () {
- let chromeWindow = this.tooltip.doc.defaultView.top;
- let windowType = chromeWindow.document.documentElement
- .getAttribute("windowtype");
- let toolboxWindow;
- if (windowType != gDevTools.chromeWindowType) {
- // this means the toolbox is in a seperate window. We need to make
- // sure we'll be inspecting the browser window instead
- toolboxWindow = chromeWindow;
- chromeWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- chromeWindow.focus();
- }
- let dropper = new Eyedropper(chromeWindow, { copyOnSelect: false,
- context: "picker" });
+ let {inspector, toolbox} = this.inspector;
+ inspector.pickColorFromPage({copyOnSelect: false}).catch(e => console.error(e));
- dropper.once("select", (event, color) => {
- if (toolboxWindow) {
- toolboxWindow.focus();
- }
+ inspector.once("color-picked", color => {
+ toolbox.win.focus();
this._selectColor(color);
});
- dropper.once("destroy", () => {
+ inspector.once("color-pick-canceled", () => {
this.eyedropperOpen = false;
this.activeSwatch = null;
});
- dropper.open();
this.eyedropperOpen = true;
// close the colorpicker tooltip so that only the eyedropper is open.
this.hide();
- this.tooltip.emit("eyedropper-opened", dropper);
+ this.tooltip.emit("eyedropper-opened");
},
_colorToRgba: function (color) {
color = new colorUtils.CssColor(color);
let rgba = color._getRGBATuple();
return [rgba.r, rgba.g, rgba.b, rgba.a];
},
_toDefaultType: function (color) {
let colorObj = new colorUtils.CssColor(color);
colorObj.setAuthoredUnitFromColor(this._originalColor);
return colorObj.toString();
},
destroy: function () {
SwatchBasedEditorTooltip.prototype.destroy.call(this);
+ this.inspector = null;
this.currentSwatchColor = null;
this.spectrum.then(spectrum => {
spectrum.off("changed", this._onSpectrumColorChange);
spectrum.destroy();
});
}
});