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

--HG--
extra : rebase_source : dd5a54d149ac1872be8580660c70b8a02da9db66
This commit is contained in:
Patrick Brosset 2016-07-20 14:47:24 +02:00
parent 4b2d233450
commit a6b51dd144
3 changed files with 69 additions and 145 deletions

View File

@ -1,19 +1,10 @@
/* 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">
@ -43,61 +34,61 @@ 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.isVisible(),
"color picker tooltip is closed after opening eyedropper");
ok(!tooltip.isVisible(), "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);
info("Open the eyedropper again");
yield openEyedropper(view, swatch);
ok(dropper, "dropper opened");
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();
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;
dropper.once("destroy", () => {
let color = swatch.style.backgroundColor;
is(color, ORIGINAL_COLOR, "swatch didn't change after pressing ESC");
deferred.resolve();
});
inspectPage(dropper, false).then(pressESC);
return deferred.promise;
}
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;
@ -108,81 +99,18 @@ function* testSelect(view, swatch, dropper) {
"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", () => {
info("Click on the swatch");
let onShown = tooltip.once("shown");
swatch.click();
yield onShown;
let dropperButton = tooltip.doc.querySelector("#eyedropper-button");
tooltip.once("eyedropper-opened", (event, dropper) => {
deferred.resolve(dropper);
});
info("Click on the eyedropper icon");
let onOpened = tooltip.once("eyedropper-opened");
dropperButton.click();
});
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);
return dropperLoaded(dropper).then(() => {
EventUtils.synthesizeMouse(target, x + 10, y + 10,
{ type: "mousemove" }, win);
if (click) {
EventUtils.synthesizeMouse(target, x + 10, y + 10, {}, win);
}
});
});
}
function dropperStarted(dropper) {
if (dropper.isStarted) {
return promise.resolve();
}
return dropper.once("started");
}
function dropperLoaded(dropper) {
if (dropper.loaded) {
return promise.resolve();
}
return dropper.once("load");
}
function pressESC() {
EventUtils.synthesizeKey("VK_ESCAPE", { });
yield onOpened;
}

View File

@ -293,7 +293,7 @@ TooltipsOverlay.prototype = {
if (this.isRuleView) {
// Color picker tooltip
this.colorPicker = new SwatchColorPickerTooltip(toolbox);
this.colorPicker = new SwatchColorPickerTooltip(toolbox, this.view.inspector);
// Cubic bezier tooltip
this.cubicBezier = new SwatchCubicBezierTooltip(toolbox);
// Filter editor tooltip

View File

@ -14,9 +14,6 @@ const {TooltipToggle} = require("devtools/client/shared/widgets/tooltip/TooltipT
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");
const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
@ -746,11 +743,15 @@ SwatchBasedEditorTooltip.prototype = {
*
* @param {Toolbox} toolbox
* The devtools toolbox, needed to get the devtools main window.
* @param {InspectorPanel} inspector
* The inspector panel, needed for the eyedropper.
*/
function SwatchColorPickerTooltip(toolbox) {
function SwatchColorPickerTooltip(toolbox, inspector) {
let stylesheet = "chrome://devtools/content/shared/widgets/spectrum.css";
SwatchBasedEditorTooltip.call(this, toolbox, stylesheet);
this.inspector = inspector;
// Creating a spectrum instance. this.spectrum will always be a promise that
// resolves to the spectrum instance
this.spectrum = this.setColorPickerContent([0, 0, 0, 1]);
@ -810,8 +811,16 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
this.spectrum.updateUI();
}
let eyeButton = this.tooltip.doc.querySelector("#eyedropper-button");
let {target} = this.inspector.toolbox;
target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
let tooltipDoc = this.tooltip.doc;
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) {
@ -834,39 +843,25 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
},
_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) {
@ -883,6 +878,7 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
destroy: function () {
SwatchBasedEditorTooltip.prototype.destroy.call(this);
this.inspector = null;
this.currentSwatchColor = null;
this.spectrum.off("changed", this._onSpectrumColorChange);
this.spectrum.destroy();