/* 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 *special*
// elements like ,
and can be edited correctly.
const TEST_URL =
"data:text/html," +
"" +
"" +
"" +
'' +
"" +
"";
const SELECTOR = "#keyboard";
const OLD_HTML = '';
const NEW_HTML = 'Edited
';
requestLongerTimeout(2);
add_task(async function () {
const { inspector } = await openInspectorForURL(TEST_URL);
inspector.markup._frame.focus();
info("Check that pressing escape cancels edits");
await testEscapeCancels(inspector);
info("Check that copying seletected text in editor works as expected");
await testCopyTextSelection(inspector);
info("Check that pressing F2 commits edits");
await testF2Commits(inspector);
info("Check that editing the element works like other nodes");
await testBody(inspector);
info("Check that editing the element works like other nodes");
await testHead(inspector);
info("Check that editing the element works like other nodes");
await testDocumentElement(inspector);
info("Check (again) that editing the element works like other nodes");
await testDocumentElement2(inspector);
});
async function testEscapeCancels(inspector) {
await selectNode(SELECTOR, inspector);
const onHtmlEditorCreated = once(inspector.markup, "begin-editing");
EventUtils.sendKey("F2", inspector.markup._frame.contentWindow);
await onHtmlEditorCreated;
ok(inspector.markup.htmlEditor.isVisible, "HTML Editor is visible");
is(
await getContentPageElementProperty(SELECTOR, "outerHTML"),
OLD_HTML,
"The node is starting with old HTML."
);
info("Check that copying from the editor does work as expected");
inspector.markup.htmlEditor.editor.setText(NEW_HTML);
const onEditorHiddem = once(inspector.markup.htmlEditor, "popuphidden");
EventUtils.sendKey("ESCAPE", inspector.markup.htmlEditor.doc.defaultView);
await onEditorHiddem;
ok(!inspector.markup.htmlEditor.isVisible, "HTML Editor is not visible");
is(
await getContentPageElementProperty(SELECTOR, "outerHTML"),
OLD_HTML,
"Escape cancels edits"
);
}
async function testCopyTextSelection(inspector) {
await selectNode(SELECTOR, inspector);
const onHtmlEditorCreated = once(inspector.markup, "begin-editing");
EventUtils.sendKey("F2", inspector.markup._frame.contentWindow);
await onHtmlEditorCreated;
ok(inspector.markup.htmlEditor.isVisible, "HTML Editor is visible");
info("Check that copying from the editor does work as expected");
inspector.markup.htmlEditor.editor.setText(NEW_HTML);
// Select the "div" word in the editor
inspector.markup.htmlEditor.editor.setSelectionAt(
{ line: 1, column: 1 },
{ line: 1, column: 4 }
);
await waitForClipboardPromise(() => {
EventUtils.synthesizeKey("c", { accelKey: true });
}, `div`);
ok(true, "Expected text was copied to clipboard");
// Close the editor
const onEditorHiddem = once(inspector.markup.htmlEditor, "popuphidden");
EventUtils.sendKey("ESCAPE", inspector.markup.htmlEditor.doc.defaultView);
await onEditorHiddem;
}
async function testF2Commits(inspector) {
const onEditorShown = once(inspector.markup.htmlEditor, "popupshown");
inspector.markup._frame.contentDocument.documentElement.focus();
EventUtils.sendKey("F2", inspector.markup._frame.contentWindow);
await onEditorShown;
ok(inspector.markup.htmlEditor.isVisible, "HTML Editor is visible");
is(
await getContentPageElementProperty(SELECTOR, "outerHTML"),
OLD_HTML,
"The node is starting with old HTML."
);
const onMutations = inspector.once("markupmutation");
inspector.markup.htmlEditor.editor.setText(NEW_HTML);
EventUtils.sendKey("F2", inspector.markup._frame.contentWindow);
await onMutations;
ok(!inspector.markup.htmlEditor.isVisible, "HTML Editor is not visible");
is(
await getContentPageElementProperty(SELECTOR, "outerHTML"),
NEW_HTML,
"F2 commits edits - the node has new HTML."
);
}
async function testBody(inspector) {
const currentBodyHTML = await getContentPageElementProperty(
"body",
"outerHTML"
);
const bodyHTML = '';
const bodyFront = await getNodeFront("body", inspector);
const onUpdated = inspector.once("inspector-updated");
const onReselected = inspector.markup.once("reselectedonremoved");
await inspector.markup.updateNodeOuterHTML(
bodyFront,
bodyHTML,
currentBodyHTML
);
await onReselected;
await onUpdated;
const newBodyHTML = await getContentPageElementProperty("body", "outerHTML");
is(newBodyHTML, bodyHTML, " HTML has been updated");
const headsNum = await getNumberOfMatchingElementsInContentPage("head");
is(headsNum, 1, "no extra s have been added");
}
async function testHead(inspector) {
await selectNode("head", inspector);
const currentHeadHTML = await getContentPageElementProperty(
"head",
"outerHTML"
);
const headHTML =
'New Title' +
'';
const headFront = await getNodeFront("head", inspector);
const onUpdated = inspector.once("inspector-updated");
const onReselected = inspector.markup.once("reselectedonremoved");
await inspector.markup.updateNodeOuterHTML(
headFront,
headHTML,
currentHeadHTML
);
await onReselected;
await onUpdated;
is(await getDocumentTitle(), "New Title", "New title has been added");
is(await getWindowFoo(), undefined, "Script has not been executed");
is(
await getContentPageElementProperty("head", "outerHTML"),
headHTML,
" HTML has been updated"
);
is(
await getNumberOfMatchingElementsInContentPage("body"),
1,
"no extra s have been added"
);
}
async function testDocumentElement(inspector) {
const currentDocElementOuterHMTL = await getDocumentOuterHTML();
const docElementHTML =
'' +
"Updated from document element" +
'' +
"Hello
";
const docElementFront = await inspector.markup.walker.documentElement();
const onReselected = inspector.markup.once("reselectedonremoved");
await inspector.markup.updateNodeOuterHTML(
docElementFront,
docElementHTML,
currentDocElementOuterHMTL
);
await onReselected;
is(
await getDocumentTitle(),
"Updated from document element",
"New title has been added"
);
is(await getWindowFoo(), undefined, "Script has not been executed");
is(
await getContentPageElementAttribute("html", "id"),
"updated",
" ID has been updated"
);
is(
await getContentPageElementAttribute("html", "class"),
null,
" class has been updated"
);
is(
await getContentPageElementAttribute("html", "foo"),
"bar",
" attribute has been updated"
);
is(
await getContentPageElementProperty("html", "outerHTML"),
docElementHTML,
" HTML has been updated"
);
is(
await getNumberOfMatchingElementsInContentPage("head"),
1,
"no extra s have been added"
);
is(
await getNumberOfMatchingElementsInContentPage("body"),
1,
"no extra s have been added"
);
is(
await getContentPageElementProperty("body", "textContent"),
"Hello",
"document.body.textContent has been updated"
);
}
async function testDocumentElement2(inspector) {
const currentDocElementOuterHMTL = await getDocumentOuterHTML();
const docElementHTML =
'' +
"Updated again from document element" +
'' +
"Hello again
";
const docElementFront = await inspector.markup.walker.documentElement();
const onReselected = inspector.markup.once("reselectedonremoved");
inspector.markup.updateNodeOuterHTML(
docElementFront,
docElementHTML,
currentDocElementOuterHMTL
);
await onReselected;
is(
await getDocumentTitle(),
"Updated again from document element",
"New title has been added"
);
is(await getWindowFoo(), undefined, "Script has not been executed");
is(
await getContentPageElementAttribute("html", "id"),
"somethingelse",
" ID has been updated"
);
is(
await getContentPageElementAttribute("html", "class"),
"updated",
" class has been updated"
);
is(
await getContentPageElementAttribute("html", "foo"),
null,
" attribute has been removed"
);
is(
await getContentPageElementProperty("html", "outerHTML"),
docElementHTML,
" HTML has been updated"
);
is(
await getNumberOfMatchingElementsInContentPage("head"),
1,
"no extra s have been added"
);
is(
await getNumberOfMatchingElementsInContentPage("body"),
1,
"no extra s have been added"
);
is(
await getContentPageElementProperty("body", "textContent"),
"Hello again",
"document.body.textContent has been updated"
);
}
function getDocumentTitle() {
return SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
() => content.document.title
);
}
function getDocumentOuterHTML() {
return SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
() => content.document.documentElement.outerHTML
);
}
function getWindowFoo() {
return SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
() => content.wrappedJSObject.foo
);
}