зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1297633 - Fixed editing of SVG elements in Inspector. r=jdescottes
Differential Revision: https://phabricator.services.mozilla.com/D102844
This commit is contained in:
Родитель
a5bf84f203
Коммит
c1b72d4f7a
|
@ -1767,7 +1767,9 @@ MarkupView.prototype = {
|
|||
this.cancelReselectOnRemoved();
|
||||
|
||||
// Get the removedNode index in its parent node to reselect the right node.
|
||||
const isHTMLTag = removedNode.tagName.toLowerCase() === "html";
|
||||
const isRootElement = ["html", "svg"].includes(
|
||||
removedNode.tagName.toLowerCase()
|
||||
);
|
||||
const oldContainer = this.getContainer(removedNode);
|
||||
const parentContainer = this.getContainer(removedNode.parentNode());
|
||||
const childIndex = parentContainer
|
||||
|
@ -1781,7 +1783,7 @@ MarkupView.prototype = {
|
|||
mutation.removed && mutation.removed.some(n => n === removedNode);
|
||||
if (
|
||||
mutation.type === "childList" &&
|
||||
(containsRemovedNode || isHTMLTag)
|
||||
(containsRemovedNode || isRootElement)
|
||||
) {
|
||||
isNodeRemovalMutation = true;
|
||||
break;
|
||||
|
@ -1798,7 +1800,7 @@ MarkupView.prototype = {
|
|||
// selection.
|
||||
if (
|
||||
this.inspector.selection.nodeFront === parentContainer.node ||
|
||||
(this.inspector.selection.nodeFront === removedNode && isHTMLTag)
|
||||
(this.inspector.selection.nodeFront === removedNode && isRootElement)
|
||||
) {
|
||||
const childContainers = parentContainer.getChildContainers();
|
||||
if (childContainers?.[childIndex]) {
|
||||
|
|
|
@ -166,6 +166,7 @@ skip-if = verify
|
|||
[browser_markup_html_edit_01.js]
|
||||
[browser_markup_html_edit_02.js]
|
||||
[browser_markup_html_edit_03.js]
|
||||
[browser_markup_html_edit_04.js]
|
||||
[browser_markup_html_edit_undo-redo.js]
|
||||
[browser_markup_image_tooltip.js]
|
||||
[browser_markup_image_tooltip_mutations.js]
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that outerHTML editing keybindings work as expected and that the <svg>
|
||||
// root element can be edited correctly.
|
||||
|
||||
const TEST_URL =
|
||||
"data:image/svg+xml," +
|
||||
'<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<circle cx="50" cy="50" r="50"/>' +
|
||||
"</svg>";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
add_task(async function() {
|
||||
const { inspector, testActor } = await openInspectorForURL(TEST_URL);
|
||||
|
||||
inspector.markup._frame.focus();
|
||||
|
||||
info("Check that editing the <svg> element works like other nodes");
|
||||
await testDocumentElement(inspector, testActor);
|
||||
|
||||
info("Check (again) that editing the <svg> element works like other nodes");
|
||||
await testDocumentElement2(inspector, testActor);
|
||||
});
|
||||
|
||||
async function testDocumentElement(inspector, testActor) {
|
||||
const currentDocElementOuterHTML = await testActor.eval(
|
||||
"document.documentElement.outerHTML"
|
||||
);
|
||||
const docElementSVG =
|
||||
'<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<rect x="10" y="10" width="180" height="180"/>' +
|
||||
"</svg>";
|
||||
const docElementFront = await inspector.markup.walker.documentElement();
|
||||
|
||||
const onReselected = inspector.markup.once("reselectedonremoved");
|
||||
await inspector.markup.updateNodeOuterHTML(
|
||||
docElementFront,
|
||||
docElementSVG,
|
||||
currentDocElementOuterHTML
|
||||
);
|
||||
await onReselected;
|
||||
|
||||
is(
|
||||
await testActor.getAttribute("svg", "width"),
|
||||
"200",
|
||||
"<svg> width has been updated"
|
||||
);
|
||||
is(
|
||||
await testActor.getAttribute("svg", "height"),
|
||||
"200",
|
||||
"<svg> height has been updated"
|
||||
);
|
||||
is(
|
||||
await testActor.getProperty("svg", "outerHTML"),
|
||||
docElementSVG,
|
||||
"<svg> markup has been updated"
|
||||
);
|
||||
}
|
||||
|
||||
async function testDocumentElement2(inspector, testActor) {
|
||||
const currentDocElementOuterHTML = await testActor.eval(
|
||||
"document.documentElement.outerHTML"
|
||||
);
|
||||
const docElementSVG =
|
||||
'<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<ellipse cx="150" cy="150" rx="150" ry="100"/>' +
|
||||
"</svg>";
|
||||
const docElementFront = await inspector.markup.walker.documentElement();
|
||||
|
||||
const onReselected = inspector.markup.once("reselectedonremoved");
|
||||
inspector.markup.updateNodeOuterHTML(
|
||||
docElementFront,
|
||||
docElementSVG,
|
||||
currentDocElementOuterHTML
|
||||
);
|
||||
await onReselected;
|
||||
|
||||
is(
|
||||
await testActor.getAttribute("svg", "width"),
|
||||
"300",
|
||||
"<svg> width has been updated"
|
||||
);
|
||||
is(
|
||||
await testActor.getAttribute("svg", "height"),
|
||||
"300",
|
||||
"<svg> height has been updated"
|
||||
);
|
||||
is(
|
||||
await testActor.getProperty("svg", "outerHTML"),
|
||||
docElementSVG,
|
||||
"<svg> markup has been updated"
|
||||
);
|
||||
}
|
|
@ -1708,7 +1708,9 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
// created nodes can be adopted into rawNode.parentNode.
|
||||
parser = new win.DOMParser();
|
||||
}
|
||||
const parsedDOM = parser.parseFromString(value, "text/html");
|
||||
|
||||
const mimeType = rawNode.tagName === "svg" ? "image/svg+xml" : "text/html";
|
||||
const parsedDOM = parser.parseFromString(value, mimeType);
|
||||
const parentNode = rawNode.parentNode;
|
||||
|
||||
// Special case for head and body. Setting document.body.outerHTML
|
||||
|
@ -1730,8 +1732,8 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
rawNode.outerHTML = value;
|
||||
}
|
||||
} else if (node.isDocumentElement()) {
|
||||
// Unable to set outerHTML on the document element. Fall back by
|
||||
// setting attributes manually, then replace the body and head elements.
|
||||
// Unable to set outerHTML on the document element. Fall back by
|
||||
// setting attributes manually. Then replace all the child nodes.
|
||||
const finalAttributeModifications = [];
|
||||
const attributeModifications = {};
|
||||
for (const attribute of rawNode.attributes) {
|
||||
|
@ -1747,8 +1749,8 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
});
|
||||
}
|
||||
node.modifyAttributes(finalAttributeModifications);
|
||||
rawNode.replaceChild(parsedDOM.head, rawNode.querySelector("head"));
|
||||
rawNode.replaceChild(parsedDOM.body, rawNode.querySelector("body"));
|
||||
|
||||
rawNode.replaceChildren(...parsedDOM.firstElementChild.childNodes);
|
||||
} else {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
rawNode.outerHTML = value;
|
||||
|
|
Загрузка…
Ссылка в новой задаче