Bug 964014 - Adds copy-image-data-uri option to images in the markup-view, r=harth
This commit is contained in:
@@ -549,11 +549,13 @@ InspectorPanel.prototype = {
|
||||
* Disable the delete item if needed. Update the pseudo classes.
|
||||
*/
|
||||
_setupNodeMenu: function InspectorPanel_setupNodeMenu() {
|
||||
let isSelectionElement = this.selection.isElementNode();
|
||||
|
||||
// Set the pseudo classes
|
||||
for (let name of ["hover", "active", "focus"]) {
|
||||
let menu = this.panelDoc.getElementById("node-menu-pseudo-" + name);
|
||||
|
||||
if (this.selection.isElementNode()) {
|
||||
if (isSelectionElement) {
|
||||
let checked = this.selection.nodeFront.hasPseudoClassLock(":" + name);
|
||||
menu.setAttribute("checked", checked);
|
||||
menu.removeAttribute("disabled");
|
||||
@@ -575,8 +577,7 @@ InspectorPanel.prototype = {
|
||||
let unique = this.panelDoc.getElementById("node-menu-copyuniqueselector");
|
||||
let copyInnerHTML = this.panelDoc.getElementById("node-menu-copyinner");
|
||||
let copyOuterHTML = this.panelDoc.getElementById("node-menu-copyouter");
|
||||
let selectionIsElement = this.selection.isElementNode();
|
||||
if (selectionIsElement) {
|
||||
if (isSelectionElement) {
|
||||
unique.removeAttribute("disabled");
|
||||
copyInnerHTML.removeAttribute("disabled");
|
||||
copyOuterHTML.removeAttribute("disabled");
|
||||
@@ -586,12 +587,24 @@ InspectorPanel.prototype = {
|
||||
copyOuterHTML.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
// Enable the "edit HTML" item if the selection is an element and the root
|
||||
// actor has the appropriate trait (isOuterHTMLEditable)
|
||||
let editHTML = this.panelDoc.getElementById("node-menu-edithtml");
|
||||
if (this.isOuterHTMLEditable && selectionIsElement) {
|
||||
if (this.isOuterHTMLEditable && isSelectionElement) {
|
||||
editHTML.removeAttribute("disabled");
|
||||
} else {
|
||||
editHTML.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
// Enable the "copy image data-uri" item if the selection is previewable
|
||||
// which essentially checks if it's an image or canvas tag
|
||||
let copyImageData = this.panelDoc.getElementById("node-menu-copyimagedatauri");
|
||||
let markupContainer = this.markup.getContainer(this.selection.nodeFront);
|
||||
if (markupContainer && markupContainer.isPreviewable()) {
|
||||
copyImageData.removeAttribute("disabled");
|
||||
} else {
|
||||
copyImageData.setAttribute("disabled", "true");
|
||||
}
|
||||
},
|
||||
|
||||
_resetNodeMenu: function InspectorPanel_resetNodeMenu() {
|
||||
@@ -717,7 +730,19 @@ InspectorPanel.prototype = {
|
||||
this._copyLongStr(this.walker.outerHTML(this.selection.nodeFront));
|
||||
},
|
||||
|
||||
_copyLongStr: function(promise) {
|
||||
/**
|
||||
* Copy the data-uri for the currently selected image in the clipboard.
|
||||
*/
|
||||
copyImageDataUri: function InspectorPanel_copyImageDataUri()
|
||||
{
|
||||
let container = this.markup.getContainer(this.selection.nodeFront);
|
||||
if (container && container.isPreviewable()) {
|
||||
container.copyImageDataUri();
|
||||
}
|
||||
},
|
||||
|
||||
_copyLongStr: function InspectorPanel_copyLongStr(promise)
|
||||
{
|
||||
return promise.then(longstr => {
|
||||
return longstr.string().then(toCopy => {
|
||||
longstr.release().then(null, console.error);
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
label="&inspectorCopyUniqueSelector.label;"
|
||||
accesskey="&inspectorCopyUniqueSelector.accesskey;"
|
||||
oncommand="inspector.copyUniqueSelector()"/>
|
||||
<menuitem id="node-menu-copyimagedatauri"
|
||||
label="&inspectorCopyImageDataUri.label;"
|
||||
oncommand="inspector.copyImageDataUri()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="node-menu-delete"
|
||||
label="&inspectorHTMLDelete.label;"
|
||||
|
||||
@@ -28,6 +28,7 @@ const EventEmitter = require("devtools/shared/event-emitter");
|
||||
Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/Templater.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
loader.lazyGetter(this, "DOMParser", function() {
|
||||
return Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
|
||||
@@ -1279,20 +1280,27 @@ MarkupContainer.prototype = {
|
||||
return "[MarkupContainer for " + this.node + "]";
|
||||
},
|
||||
|
||||
_prepareImagePreview: function() {
|
||||
isPreviewable: function() {
|
||||
if (this.node.tagName) {
|
||||
let tagName = this.node.tagName.toLowerCase();
|
||||
let srcAttr = this.editor.getAttributeElement("src");
|
||||
let isImage = tagName === "img" && srcAttr;
|
||||
let isCanvas = tagName === "canvas";
|
||||
|
||||
return isImage || isCanvas;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
_prepareImagePreview: function() {
|
||||
if (this.isPreviewable()) {
|
||||
// Get the image data for later so that when the user actually hovers over
|
||||
// the element, the tooltip does contain the image
|
||||
if (isImage || isCanvas) {
|
||||
let def = promise.defer();
|
||||
|
||||
this.tooltipData = {
|
||||
target: isImage ? srcAttr : this.editor.tag,
|
||||
target: this.editor.getAttributeElement("src") || this.editor.tag,
|
||||
data: def.promise
|
||||
};
|
||||
|
||||
@@ -1308,7 +1316,18 @@ MarkupContainer.prototype = {
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
copyImageDataUri: function() {
|
||||
// We need to send again a request to gettooltipData even if one was sent for
|
||||
// the tooltip, because we want the full-size image
|
||||
this.node.getImageData().then(data => {
|
||||
if (data) {
|
||||
data.data.string().then(str => {
|
||||
clipboardHelper.copyString(str, this.markup.doc);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_buildTooltipContent: function(target, tooltip) {
|
||||
@@ -2068,3 +2087,8 @@ function parseAttributeValues(attr, doc) {
|
||||
loader.lazyGetter(MarkupView.prototype, "strings", () => Services.strings.createBundle(
|
||||
"chrome://browser/locale/devtools/inspector.properties"
|
||||
));
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function() {
|
||||
return Cc["@mozilla.org/widget/clipboardhelper;1"].
|
||||
getService(Ci.nsIClipboardHelper);
|
||||
});
|
||||
|
||||
@@ -21,3 +21,4 @@ skip-if = true
|
||||
[browser_inspector_markup_subset.js]
|
||||
[browser_inspector_markup_765105_tooltip.js]
|
||||
[browser_inspector_markup_950732.js]
|
||||
[browser_inspector_markup_964014_copy_image_data.js]
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@ const Cu = Components.utils;
|
||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
let {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
let promise = devtools.require("sdk/core/promise");
|
||||
|
||||
// Clear preferences that may be set during the course of tests.
|
||||
function clearUserPrefs() {
|
||||
@@ -27,3 +28,38 @@ function getContainerForRawNode(markupView, rawNode) {
|
||||
let container = markupView.getContainer(front);
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
*/
|
||||
function openInspector() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
let inspector = toolbox.getCurrentPanel();
|
||||
inspector.once("inspector-updated", () => {
|
||||
deferred.resolve(inspector, toolbox);
|
||||
});
|
||||
}).then(null, console.error);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inspector's current selection to the first match of the given css
|
||||
* selector
|
||||
* @return a promise that resolves when the inspector is updated with the new
|
||||
* node
|
||||
*/
|
||||
function selectNode(selector, inspector) {
|
||||
let deferred = promise.defer();
|
||||
let node = content.document.querySelector(selector);
|
||||
ok(node, "A node was found for selector " + selector + ". Selecting it now");
|
||||
inspector.selection.setNode(node, "test");
|
||||
inspector.once("inspector-updated", () => {
|
||||
deferred.resolve(node);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
@@ -17,3 +17,5 @@
|
||||
|
||||
<!ENTITY inspectorSearchHTML.label "Search HTML">
|
||||
<!ENTITY inspectorSearchHTML.key "F">
|
||||
|
||||
<!ENTITY inspectorCopyImageDataUri.label "Copy Image Data-URL">
|
||||
|
||||
Reference in New Issue
Block a user