mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-29 18:53:15 +00:00
7624030fbf
- Bug 1055181 - CSS Filter Tooltip; r=pbrosset (327b035a7) - Bug 1137238 - Fix toolboxes when switching between apps in WebIDE. r=jryans (1a333bdfa) - Bug 1138939 - Notify when WebIDE has finished initializing so that Valence can register runtime scanners. r=ochameau (7fe61c384) - Don't let WebIDE break when trying to debug Chrome settings (bug 1134619). r=ochameau (4a18f048e) - fix imports since devtools are in a different path compared to FF (15c2a1e70) - port bits of Bug 916804 - Telemetry for WebIDE. (cf5b49ca7) - Bug 1042859 - Ignore host port when fetching cookies with the gcli cookie command. r=pbrosset (1e6217f76) - fix include path (6efaacd7a) - Bug 1128988 - runAt support for commands/converters; r=bgrins (bed6cb594) - Bug 1143027 - The performance tool tab highlights during a recording. r=vp (e1f310e2d) - missing pieces of Bug 1141817 - Followup to fix additional intermittents and Bug 1142748 - Fix the 'Protocol error (unknownError) (b27da36af) - Bug 1159480 - Pull out actor-specific logic from Performance Front. r=vp (9c253604b) - Bug 1156499 - Disable all non-profiler/fps components in the performance tools when in aurora, for 40.0 release. r=vp (041a0fa34) - Bug 1159052 - Performance recording should stop rendering and recording as soon as the recording stops. r=vp (2a9f093b4) - Bug 114187 - Add getBufferInfo to devtools profiler actor. r=fitzgen (00496e8e4) - Bug 1145187 - Implement polling for buffer status on performance actor facades. r=vp (ae2cbac27) - Bug 1082695 - Simplify the record start/stop time buttons, and more cleanly render the console.profile notifications during a console recording. r=vp (dfe9a9b26) - Bug 1160900 - Display buffer status while recording a profile. r=vp (c3d302a62) - Bug 1154115 - Add adapter that deduplicates old, undeduplicated profiles in the frontend. (r=jsantell,vporof) (aa1bd6769) - Bug 1160696 - Display MIRTypes in the JIT optimizations side pane as "Site : MIRType". (r=jsantell) (beccaed3d) - Bug 1154115 - Make the memory stuff in the performance devtool synthesize the new profiler JSON format. (r=jsantell) (685e3a576) - Bug 1154115 - Fix nsIProfiler xpcshell tests to use the new profiler JSON format. (r=me) (da2a18c89) - Bug 1151526 - Do not display optimization data for meta-platform frames in the profiler. r=vporof (d4cc514ca) - Bug 1154115 - Fix devtools tests to use the new profiler JSON format. (r=jsantell) (61a9064ce) - Bug 1126432: Set preference toggle to switch to new WebIDE project listing layout r=jryans (825831eeb) - Bug 1130084 - Avoid spurious connection errors even on success. r=past (1911930b6) - missing bits of Bug 1069552 - Add WebIDE scanner / runtime API. (773111b87) - Bug 1130084 - Allow runtimes to take infinite time to connect. r=past (a1482c500) - Bug 1025311 - Add telemetry for canvas debugger. r=vp,miker (d2f8d51f2) - Bug 1134778 - Consolidate usages of view sourcing in tools with a source-utils module. r=vp,jryans (1432dfac1) - Bug 1167230 - Use nsCString instead of std::string in FrameKey in the profiler. (r=mstange) (9a3d84b86) - Bug 1166492 - Handle huge strings in the profile JSON writer. (r=mstange) (3d6f90062) - Bug 1166492 - Remove dead code in the ProfileBuffer and ThreadProfile. (r=mstange) (cc8e81dd3) - Bug 1166492 - Return UniquePtr<char[]> from profiler_get_profile to avoid double copying. (r=mstange) (f9d58d5cf) - Bug 1167230 - Don't pack ProfileEntry on ARM. r=shu (b6f920dd3) - Bug 1168784 - Part 1: Fix the script merging profiles to handle new profiler JSON format. r=benwa (dd1008084) - Bug 1090949 - Add `nextTick()` to `lazyIframeIsLoaded()` in WebIDE tests. r=ochameau (94bf972da) - Bug 1143028 - Make AppMan reinitable; update tab list when sidebars disabled. r=past (1020f8306) - Bug 1146542 - Clean up and describe app-manager events. r=ochameau (cc4bcadf5) - Bug 1146542 - Restore tab list changes for non-sidebar case. r=ochameau (531b70e41) - Bug 1149820 - Restore WebIDE project auto select. r=ochameau (d0526612a) - Bug 1135018 - Move getjson from webide/ to shared/. r=jryans (9e405c1bf) - Bug 1135018 - Make devices.js use a CDN. r=ochameau (16adb49c4) - Bug 1090949 - Make WebIDE's Firefox OS Simulators configurable. r=ochameau (354331a6e) - Bug 1157201 - Prevent exception while hovering the rule-view. r=pbrosset (4ec81d85b)
423 lines
12 KiB
JavaScript
423 lines
12 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
// The style-inspector overlays are:
|
|
// - tooltips that appear when hovering over property values
|
|
// - editor tooltips that appear when clicking color swatches, etc.
|
|
// - in-content highlighters that appear when hovering over property values
|
|
// - etc.
|
|
|
|
const {Cc, Ci, Cu} = require("chrome");
|
|
const {
|
|
Tooltip,
|
|
SwatchColorPickerTooltip,
|
|
SwatchCubicBezierTooltip,
|
|
SwatchFilterTooltip
|
|
} = require("devtools/shared/widgets/Tooltip");
|
|
const {CssLogic} = require("devtools/styleinspector/css-logic");
|
|
const {Promise:promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
|
Cu.import("resource://gre/modules/Task.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
|
|
const PREF_IMAGE_TOOLTIP_SIZE = "devtools.inspector.imagePreviewTooltipSize";
|
|
|
|
// Types of existing tooltips
|
|
const TOOLTIP_IMAGE_TYPE = "image";
|
|
const TOOLTIP_FONTFAMILY_TYPE = "font-family";
|
|
|
|
// Types of existing highlighters
|
|
const HIGHLIGHTER_TRANSFORM_TYPE = "CssTransformHighlighter";
|
|
const HIGHLIGHTER_SELECTOR_TYPE = "SelectorHighlighter";
|
|
const HIGHLIGHTER_TYPES = [
|
|
HIGHLIGHTER_TRANSFORM_TYPE,
|
|
HIGHLIGHTER_SELECTOR_TYPE
|
|
];
|
|
|
|
// Types of nodes in the rule/computed-view
|
|
const VIEW_NODE_SELECTOR_TYPE = exports.VIEW_NODE_SELECTOR_TYPE = 1;
|
|
const VIEW_NODE_PROPERTY_TYPE = exports.VIEW_NODE_PROPERTY_TYPE = 2;
|
|
const VIEW_NODE_VALUE_TYPE = exports.VIEW_NODE_VALUE_TYPE = 3;
|
|
const VIEW_NODE_IMAGE_URL_TYPE = exports.VIEW_NODE_IMAGE_URL_TYPE = 4;
|
|
|
|
/**
|
|
* Manages all highlighters in the style-inspector.
|
|
* @param {CssRuleView|CssHtmlTree} view Either the rule-view or computed-view
|
|
* panel
|
|
*/
|
|
function HighlightersOverlay(view) {
|
|
this.view = view;
|
|
|
|
let {CssRuleView} = require("devtools/styleinspector/rule-view");
|
|
this.isRuleView = view instanceof CssRuleView;
|
|
|
|
this.highlighterUtils = this.view.inspector.toolbox.highlighterUtils;
|
|
|
|
this._onMouseMove = this._onMouseMove.bind(this);
|
|
this._onMouseLeave = this._onMouseLeave.bind(this);
|
|
|
|
this.promises = {};
|
|
this.highlighters = {};
|
|
|
|
// Only initialize the overlay if at least one of the highlighter types is
|
|
// supported
|
|
this.supportsHighlighters = this.highlighterUtils.supportsCustomHighlighters();
|
|
}
|
|
|
|
exports.HighlightersOverlay = HighlightersOverlay;
|
|
|
|
HighlightersOverlay.prototype = {
|
|
/**
|
|
* Add the highlighters overlay to the view. This will start tracking mouse
|
|
* movements and display highlighters when needed
|
|
*/
|
|
addToView: function() {
|
|
if (!this.supportsHighlighters || this._isStarted || this._isDestroyed) {
|
|
return;
|
|
}
|
|
|
|
let el = this.view.element;
|
|
el.addEventListener("mousemove", this._onMouseMove, false);
|
|
el.addEventListener("mouseleave", this._onMouseLeave, false);
|
|
|
|
this._isStarted = true;
|
|
},
|
|
|
|
/**
|
|
* Remove the overlay from the current view. This will stop tracking mouse
|
|
* movement and showing highlighters
|
|
*/
|
|
removeFromView: function() {
|
|
if (!this.supportsHighlighters || !this._isStarted || this._isDestroyed) {
|
|
return;
|
|
}
|
|
|
|
this._hideCurrent();
|
|
|
|
let el = this.view.element;
|
|
el.removeEventListener("mousemove", this._onMouseMove, false);
|
|
el.removeEventListener("mouseleave", this._onMouseLeave, false);
|
|
|
|
this._isStarted = false;
|
|
},
|
|
|
|
_onMouseMove: function(event) {
|
|
// Bail out if the target is the same as for the last mousemove
|
|
if (event.target === this._lastHovered) {
|
|
return;
|
|
}
|
|
|
|
// Only one highlighter can be displayed at a time, hide the currently shown
|
|
this._hideCurrent();
|
|
|
|
this._lastHovered = event.target;
|
|
|
|
let nodeInfo = this.view.getNodeInfo(event.target);
|
|
if (!nodeInfo) {
|
|
return;
|
|
}
|
|
|
|
// Choose the type of highlighter required for the hovered node
|
|
let type, options;
|
|
if (this._isRuleViewTransform(nodeInfo) ||
|
|
this._isComputedViewTransform(nodeInfo)) {
|
|
type = HIGHLIGHTER_TRANSFORM_TYPE;
|
|
} else if (nodeInfo.type === VIEW_NODE_SELECTOR_TYPE) {
|
|
type = HIGHLIGHTER_SELECTOR_TYPE;
|
|
options = {
|
|
selector: nodeInfo.value,
|
|
hideInfoBar: true,
|
|
showOnly: "border",
|
|
region: "border"
|
|
};
|
|
}
|
|
|
|
if (type) {
|
|
this.highlighterShown = type;
|
|
let node = this.view.inspector.selection.nodeFront;
|
|
this._getHighlighter(type).then(highlighter => {
|
|
highlighter.show(node, options);
|
|
});
|
|
}
|
|
},
|
|
|
|
_onMouseLeave: function(event) {
|
|
this._lastHovered = null;
|
|
this._hideCurrent();
|
|
},
|
|
|
|
/**
|
|
* Is the current hovered node a css transform property value in the rule-view
|
|
* @param {Object} nodeInfo
|
|
* @return {Boolean}
|
|
*/
|
|
_isRuleViewTransform: function(nodeInfo) {
|
|
let isTransform = nodeInfo.type === VIEW_NODE_VALUE_TYPE &&
|
|
nodeInfo.value.property === "transform";
|
|
let isEnabled = nodeInfo.value.enabled &&
|
|
!nodeInfo.value.overridden &&
|
|
!nodeInfo.value.pseudoElement;
|
|
return this.isRuleView && isTransform && isEnabled;
|
|
},
|
|
|
|
/**
|
|
* Is the current hovered node a css transform property value in the
|
|
* computed-view
|
|
* @param {Object} nodeInfo
|
|
* @return {Boolean}
|
|
*/
|
|
_isComputedViewTransform: function(nodeInfo) {
|
|
let isTransform = nodeInfo.type === VIEW_NODE_VALUE_TYPE &&
|
|
nodeInfo.value.property === "transform";
|
|
return !this.isRuleView && isTransform;
|
|
},
|
|
|
|
/**
|
|
* Hide the currently shown highlighter
|
|
*/
|
|
_hideCurrent: function() {
|
|
if (this.highlighterShown) {
|
|
this._getHighlighter(this.highlighterShown).then(highlighter => {
|
|
// For some reason, the call to highlighter.hide doesn't always return a
|
|
// promise. This causes some tests to fail when trying to install a
|
|
// rejection handler on the result of the call. To avoid this, check
|
|
// whether the result is truthy before installing the handler.
|
|
let promise = highlighter.hide();
|
|
if (promise) {
|
|
promise.then(null, Cu.reportError);
|
|
}
|
|
this.highlighterShown = null;
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get a highlighter front given a type. It will only be initialized once
|
|
* @param {String} type The highlighter type. One of this.highlighters
|
|
* @return a promise that resolves to the highlighter
|
|
*/
|
|
_getHighlighter: function(type) {
|
|
let utils = this.highlighterUtils;
|
|
|
|
if (this.promises[type]) {
|
|
return this.promises[type];
|
|
}
|
|
|
|
return this.promises[type] = utils.getHighlighterByType(type).then(highlighter => {
|
|
this.highlighters[type] = highlighter;
|
|
return highlighter;
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Destroy this overlay instance, removing it from the view and destroying
|
|
* all initialized highlighters
|
|
*/
|
|
destroy: function() {
|
|
this.removeFromView();
|
|
|
|
for (let type in this.highlighters) {
|
|
if (this.highlighters[type]) {
|
|
this.highlighters[type].finalize();
|
|
this.highlighters[type] = null;
|
|
}
|
|
}
|
|
|
|
this.promises = null;
|
|
this.view = null;
|
|
this.highlighterUtils = null;
|
|
|
|
this._isDestroyed = true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Manages all tooltips in the style-inspector.
|
|
* @param {CssRuleView|CssHtmlTree} view Either the rule-view or computed-view
|
|
* panel
|
|
*/
|
|
function TooltipsOverlay(view) {
|
|
this.view = view;
|
|
|
|
let {CssRuleView} = require("devtools/styleinspector/rule-view");
|
|
this.isRuleView = view instanceof CssRuleView;
|
|
|
|
this._onNewSelection = this._onNewSelection.bind(this);
|
|
this.view.inspector.selection.on("new-node-front", this._onNewSelection);
|
|
}
|
|
|
|
exports.TooltipsOverlay = TooltipsOverlay;
|
|
|
|
TooltipsOverlay.prototype = {
|
|
get isEditing() {
|
|
return this.colorPicker.tooltip.isShown() ||
|
|
this.colorPicker.eyedropperOpen ||
|
|
this.cubicBezier.tooltip.isShown() ||
|
|
this.filterEditor.tooltip.isShown();
|
|
},
|
|
|
|
/**
|
|
* Add the tooltips overlay to the view. This will start tracking mouse
|
|
* movements and display tooltips when needed
|
|
*/
|
|
addToView: function() {
|
|
if (this._isStarted || this._isDestroyed) {
|
|
return;
|
|
}
|
|
|
|
// Image, fonts, ... preview tooltip
|
|
this.previewTooltip = new Tooltip(this.view.inspector.panelDoc);
|
|
this.previewTooltip.startTogglingOnHover(this.view.element,
|
|
this._onPreviewTooltipTargetHover.bind(this));
|
|
|
|
if (this.isRuleView) {
|
|
// Color picker tooltip
|
|
this.colorPicker = new SwatchColorPickerTooltip(this.view.inspector.panelDoc);
|
|
// Cubic bezier tooltip
|
|
this.cubicBezier = new SwatchCubicBezierTooltip(this.view.inspector.panelDoc);
|
|
// Filter editor tooltip
|
|
this.filterEditor = new SwatchFilterTooltip(this.view.inspector.panelDoc);
|
|
}
|
|
|
|
this._isStarted = true;
|
|
},
|
|
|
|
/**
|
|
* Remove the tooltips overlay from the view. This will stop tracking mouse
|
|
* movements and displaying tooltips
|
|
*/
|
|
removeFromView: function() {
|
|
if (!this._isStarted || this._isDestroyed) {
|
|
return;
|
|
}
|
|
|
|
this.previewTooltip.stopTogglingOnHover(this.view.element);
|
|
this.previewTooltip.destroy();
|
|
|
|
if (this.colorPicker) {
|
|
this.colorPicker.destroy();
|
|
}
|
|
|
|
if (this.cubicBezier) {
|
|
this.cubicBezier.destroy();
|
|
}
|
|
|
|
if (this.filterEditor) {
|
|
this.filterEditor.destroy();
|
|
}
|
|
|
|
this._isStarted = false;
|
|
},
|
|
|
|
/**
|
|
* Given a hovered node info, find out which type of tooltip should be shown,
|
|
* if any
|
|
* @param {Object} nodeInfo
|
|
* @return {String} The tooltip type to be shown, or null
|
|
*/
|
|
_getTooltipType: function({type, value:prop}) {
|
|
let tooltipType = null;
|
|
let inspector = this.view.inspector;
|
|
|
|
// Image preview tooltip
|
|
if (type === VIEW_NODE_IMAGE_URL_TYPE && inspector.hasUrlToImageDataResolver) {
|
|
tooltipType = TOOLTIP_IMAGE_TYPE;
|
|
}
|
|
|
|
// Font preview tooltip
|
|
if (type === VIEW_NODE_VALUE_TYPE && prop.property === "font-family") {
|
|
let value = prop.value.toLowerCase();
|
|
if (value !== "inherit" && value !== "unset" && value !== "initial") {
|
|
tooltipType = TOOLTIP_FONTFAMILY_TYPE;
|
|
}
|
|
}
|
|
|
|
return tooltipType;
|
|
},
|
|
|
|
/**
|
|
* Executed by the tooltip when the pointer hovers over an element of the view.
|
|
* Used to decide whether the tooltip should be shown or not and to actually
|
|
* put content in it.
|
|
* Checks if the hovered target is a css value we support tooltips for.
|
|
* @param {DOMNode} target The currently hovered node
|
|
*/
|
|
_onPreviewTooltipTargetHover: function(target) {
|
|
let nodeInfo = this.view.getNodeInfo(target);
|
|
if (!nodeInfo) {
|
|
// The hovered node isn't something we care about
|
|
return promise.reject(false);
|
|
}
|
|
|
|
let type = this._getTooltipType(nodeInfo);
|
|
if (!type) {
|
|
// There is no tooltip type defined for the hovered node
|
|
return promise.reject(false);
|
|
}
|
|
|
|
if (this.isRuleView && this.colorPicker.tooltip.isShown()) {
|
|
this.colorPicker.revert();
|
|
this.colorPicker.hide();
|
|
}
|
|
|
|
if (this.isRuleView && this.cubicBezier.tooltip.isShown()) {
|
|
this.cubicBezier.revert();
|
|
this.cubicBezier.hide();
|
|
}
|
|
|
|
if (this.isRuleView && this.filterEditor.tooltip.isShown()) {
|
|
this.filterEditor.revert();
|
|
this.filterEdtior.hide();
|
|
}
|
|
|
|
let inspector = this.view.inspector;
|
|
|
|
if (type === TOOLTIP_IMAGE_TYPE) {
|
|
let dim = Services.prefs.getIntPref(PREF_IMAGE_TOOLTIP_SIZE);
|
|
// nodeInfo contains an absolute uri
|
|
let uri = nodeInfo.value.url;
|
|
return this.previewTooltip.setRelativeImageContent(uri,
|
|
inspector.inspector, dim);
|
|
}
|
|
|
|
if (type === TOOLTIP_FONTFAMILY_TYPE) {
|
|
return this.previewTooltip.setFontFamilyContent(nodeInfo.value.value,
|
|
inspector.selection.nodeFront);
|
|
}
|
|
},
|
|
|
|
_onNewSelection: function() {
|
|
if (this.previewTooltip) {
|
|
this.previewTooltip.hide();
|
|
}
|
|
|
|
if (this.colorPicker) {
|
|
this.colorPicker.hide();
|
|
}
|
|
|
|
if (this.cubicBezier) {
|
|
this.cubicBezier.hide();
|
|
}
|
|
|
|
if (this.filterEditor) {
|
|
this.filterEditor.hide();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Destroy this overlay instance, removing it from the view
|
|
*/
|
|
destroy: function() {
|
|
this.removeFromView();
|
|
|
|
this.view.inspector.selection.off("new-node-front", this._onNewSelection);
|
|
this.view = null;
|
|
|
|
this._isDestroyed = true;
|
|
}
|
|
};
|