Skip to content

Commit 4237ebc

Browse files
Web Inspector: Elements: Support copying HTML text of multiple selected DOM nodes
https://bugs.webkit.org/show_bug.cgi?id=307799 rdar://169196441 Reviewed by Devin Rousso. The context menu options to copy HTML and HTML (formatted) are updated to support copying the HTML text of all selected nodes from the DOM tree outline. * Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js: (WI.FormatterWorkerProxy.prototype.formatJavaScript): (WI.FormatterWorkerProxy.prototype.formatCSS): (WI.FormatterWorkerProxy.prototype.formatHTML): (WI.FormatterWorkerProxy.prototype.formatXML): (WI.FormatterWorkerProxy.prototype.performAction): * Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js: (WI.DOMTreeElement.prototype.populateDOMNodeContextMenu): (WI.DOMTreeElement.prototype._copyHTMLOfSelectedDOMNodes.async then): (WI.DOMTreeElement.prototype._copyHTMLOfSelectedDOMNodes): Canonical link: https://commits.webkit.org/307826@main
1 parent 3f7a23f commit 4237ebc

File tree

2 files changed

+51
-16
lines changed

2 files changed

+51
-16
lines changed

Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,22 @@ WI.FormatterWorkerProxy = class FormatterWorkerProxy
4747

4848
formatJavaScript(sourceText, isModule, indentString, includeSourceMapData)
4949
{
50-
this.performAction("formatJavaScript", ...arguments);
50+
return this.performAction("formatJavaScript", ...arguments);
5151
}
5252

5353
formatCSS(sourceText, indentString, includeSourceMapData)
5454
{
55-
this.performAction("formatCSS", ...arguments);
55+
return this.performAction("formatCSS", ...arguments);
5656
}
5757

5858
formatHTML(sourceText, indentString, includeSourceMapData)
5959
{
60-
this.performAction("formatHTML", ...arguments);
60+
return this.performAction("formatHTML", ...arguments);
6161
}
6262

6363
formatXML(sourceText, indentString, includeSourceMapData)
6464
{
65-
this.performAction("formatXML", ...arguments);
65+
return this.performAction("formatXML", ...arguments);
6666
}
6767

6868
// Public
@@ -80,6 +80,30 @@ WI.FormatterWorkerProxy = class FormatterWorkerProxy
8080
this._postMessage({callId, actionName, actionArguments});
8181
}
8282

83+
performAction(actionName)
84+
{
85+
console.assert(typeof actionName === "string", "performAction should always have an actionName");
86+
87+
let callId = this._nextCallId++;
88+
89+
let callback = arguments[arguments.length - 1];
90+
if (typeof callback !== "function") {
91+
return new Promise((resolve, reject) => {
92+
this._callbacks.set(callId, resolve);
93+
this._postMessage({
94+
callId,
95+
actionName,
96+
actionArguments: Array.prototype.slice.call(arguments, 1),
97+
});
98+
});
99+
}
100+
101+
let actionArguments = Array.prototype.slice.call(arguments, 1, arguments.length - 1);
102+
103+
this._callbacks.set(callId, callback);
104+
this._postMessage({callId, actionName, actionArguments});
105+
}
106+
83107
// Private
84108

85109
_postMessage()

Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -868,21 +868,11 @@ WI.DOMTreeElement = class DOMTreeElement extends WI.TreeElement
868868

869869
if (!this.representedObject.destroyed && !this.representedObject.isPseudoElement()) {
870870
subMenus.copy.appendItem(WI.UIString("HTML"), () => {
871-
this.representedObject.getOuterHTML()
872-
.then((outerHTML) => {
873-
InspectorFrontendHost.copyText(outerHTML);
874-
});
871+
this._copyHTMLOfSelectedDOMNodes();
875872
});
876873

877874
subMenus.copy.appendItem(WI.UIString("HTML (Formatted)"), () => {
878-
this.representedObject.getOuterHTML()
879-
.then((outerHTML) => {
880-
let workerProxy = WI.FormatterWorkerProxy.singleton();
881-
const includeSourceMapData = false;
882-
workerProxy.formatHTML(outerHTML, WI.indentString(), includeSourceMapData, ({formattedText}) => {
883-
InspectorFrontendHost.copyText(formattedText);
884-
});
885-
});
875+
this._copyHTMLOfSelectedDOMNodes({formatted: true});
886876
});
887877
}
888878

@@ -934,6 +924,27 @@ WI.DOMTreeElement = class DOMTreeElement extends WI.TreeElement
934924
}
935925
}
936926

927+
_copyHTMLOfSelectedDOMNodes({formatted} = {})
928+
{
929+
Promise.all(this.treeOutline.selectedTreeElements.map(async function(treeElement) {
930+
let outerHTML = await treeElement.representedObject.getOuterHTML();
931+
if (formatted) {
932+
let workerProxy = WI.FormatterWorkerProxy.singleton();
933+
const includeSourceMapData = false;
934+
let {formattedText} = await workerProxy.formatHTML(outerHTML, WI.indentString(), includeSourceMapData);
935+
outerHTML = formattedText || "";
936+
}
937+
938+
return outerHTML;
939+
}))
940+
.then(function(outerHTMLs) {
941+
InspectorFrontendHost.copyText(outerHTMLs.join("\n"));
942+
})
943+
.catch(function(error) {
944+
WI.reportInternalError(error);
945+
});
946+
}
947+
937948
_startEditing()
938949
{
939950
if (this.treeOutline.selectedDOMNode() !== this.representedObject)

0 commit comments

Comments
 (0)