Bug 1449564 - part 2: Make absolute positioned element editor disabled in default and make it possible to enable it with new command r=m_kato

We have another built-in UI of editor which is not implemented by any other
browsers.  That is a draggable handler to move absolute positioned elements.
So, we should disable it in default for compatibility with the other browsers.

However, different from resizers and inline table editor, we don't have
command to enable/disable this feature but for backward compatibility, we
should have it.  Therefore, this patch adds new command
"enableAbsolutePositionEditor".

Note that whether resizing UI is available only with enableObjectResizing
state is different from enableInlineTableEditing command.  Resizers for
absolute positioned elements are NOT available both enableObjectResizing
and enableAbsolutePositionEditor are enabled.

Additionally, this adds automated tests to check basic functions of absolute
positioned editor.

MozReview-Commit-ID: 9ZSGB8tLpFw

--HG--
rename : editor/libeditor/tests/test_resizers_appearance.html => editor/libeditor/tests/test_abs_positioner_appearance.html
rename : editor/libeditor/tests/test_resizers_resizing_elements.html => editor/libeditor/tests/test_abs_positioner_positioning_elements.html
extra : rebase_source : d516f3f3ef36d4ad13938f214cb6e3868d7ff407
This commit is contained in:
Masayuki Nakano 2018-04-04 22:27:49 +09:00
Родитель b808917841
Коммит 44ae690779
13 изменённых файлов: 399 добавлений и 53 удалений

Просмотреть файл

@ -2728,6 +2728,7 @@ static const struct MidasCommand gMidasCommandTable[] = {
{ "defaultParagraphSeparator", "cmd_defaultParagraphSeparator", "", false, false },
{ "enableObjectResizing", "cmd_enableObjectResizing", "", false, true },
{ "enableInlineTableEditing", "cmd_enableInlineTableEditing", "", false, true },
{ "enableAbsolutePositionEditing", "cmd_enableAbsolutePositionEditing", "", false, true },
#if 0
// no editor support to remove alignments right now
{ "justifynone", "cmd_align", "", true, false },

Просмотреть файл

@ -109,14 +109,14 @@ HTMLEditor::GetAbsolutelyPositionedSelectionContainer()
NS_IMETHODIMP
HTMLEditor::GetAbsolutePositioningEnabled(bool* aIsEnabled)
{
*aIsEnabled = AbsolutePositioningEnabled();
*aIsEnabled = IsAbsolutePositionEditorEnabled();
return NS_OK;
}
NS_IMETHODIMP
HTMLEditor::SetAbsolutePositioningEnabled(bool aIsEnabled)
{
mIsAbsolutelyPositioningEnabled = aIsEnabled;
EnableAbsolutePositionEditor(aIsEnabled);
return NS_OK;
}

Просмотреть файл

@ -295,7 +295,7 @@ HTMLEditor::CheckSelectionStateForAnonymousButtons(Selection* aSelection)
// early way out if all contextual UI extensions are disabled
if (NS_WARN_IF(!IsObjectResizerEnabled() &&
!mIsAbsolutelyPositioningEnabled &&
!IsAbsolutePositionEditorEnabled() &&
!IsInlineTableEditorEnabled())) {
return NS_OK;
}
@ -320,7 +320,7 @@ HTMLEditor::CheckSelectionStateForAnonymousButtons(Selection* aSelection)
nsAtom* focusTagAtom = focusElement->NodeInfo()->NameAtom();
RefPtr<Element> absPosElement;
if (mIsAbsolutelyPositioningEnabled) {
if (IsAbsolutePositionEditorEnabled()) {
// Absolute Positioning support is enabled, is the selection contained
// in an absolutely positioned element ?
absPosElement = GetAbsolutelyPositionedSelectionContainer();
@ -361,7 +361,7 @@ HTMLEditor::CheckSelectionStateForAnonymousButtons(Selection* aSelection)
// content which means a DOMAttrModified handler may cause arbitrary
// side effects while this code runs (bug 420439).
if (mIsAbsolutelyPositioningEnabled && mAbsolutelyPositionedObject &&
if (IsAbsolutePositionEditorEnabled() && mAbsolutelyPositionedObject &&
absPosElement != mAbsolutelyPositionedObject) {
HideGrabber();
NS_ASSERTION(!mAbsolutelyPositionedObject, "HideGrabber failed");
@ -402,7 +402,7 @@ HTMLEditor::CheckSelectionStateForAnonymousButtons(Selection* aSelection)
}
}
if (mIsAbsolutelyPositioningEnabled && absPosElement &&
if (IsAbsolutePositionEditorEnabled() && absPosElement &&
IsModifiableNode(*absPosElement) && absPosElement != hostContent) {
if (mAbsolutelyPositionedObject) {
nsresult rv = RefreshGrabber();

Просмотреть файл

@ -120,7 +120,7 @@ HTMLEditor::HTMLEditor()
, mIsResizing(false)
, mPreserveRatio(false)
, mResizedObjectIsAnImage(false)
, mIsAbsolutelyPositioningEnabled(true)
, mIsAbsolutelyPositioningEnabled(false)
, mResizedObjectIsAbsolutelyPositioned(false)
, mHasShownGrabber(false)
, mGrabberClicked(false)

Просмотреть файл

@ -247,12 +247,22 @@ public:
return mIsInlineTableEditingEnabled;
}
// non-virtual methods of interface methods
bool AbsolutePositioningEnabled() const
/**
* Enable/disable absolute position editor, resizing absolute positioned
* elements (required object resizers enabled) or positioning them with
* dragging grabber.
*/
void EnableAbsolutePositionEditor(bool aEnable)
{
mIsAbsolutelyPositioningEnabled = aEnable;
}
bool IsAbsolutePositionEditorEnabled() const
{
return mIsAbsolutelyPositioningEnabled;
}
// non-virtual methods of interface methods
/**
* returns the deepest absolutely positioned container of the selection
* if it exists or null.

Просмотреть файл

@ -1084,9 +1084,9 @@ AbsolutePositioningCommand::AbsolutePositioningCommand()
NS_IMETHODIMP
AbsolutePositioningCommand::IsCommandEnabled(const char* aCommandName,
nsISupports* aCommandRefCon,
bool* outCmdEnabled)
bool* aOutCmdEnabled)
{
*outCmdEnabled = false;
*aOutCmdEnabled = false;
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
if (!editor) {
@ -1099,7 +1099,7 @@ AbsolutePositioningCommand::IsCommandEnabled(const char* aCommandName,
if (!htmlEditor->IsSelectionEditable()) {
return NS_OK;
}
*outCmdEnabled = htmlEditor->AbsolutePositioningEnabled();
*aOutCmdEnabled = htmlEditor->IsAbsolutePositionEditorEnabled();
return NS_OK;
}
@ -1112,8 +1112,7 @@ AbsolutePositioningCommand::GetCurrentState(HTMLEditor* aHTMLEditor,
}
nsCommandParams* params = aParams->AsCommandParams();
bool isEnabled = aHTMLEditor->AbsolutePositioningEnabled();
if (!isEnabled) {
if (!aHTMLEditor->IsAbsolutePositionEditorEnabled()) {
params->SetBool(STATE_MIXED, false);
params->SetCString(STATE_ATTRIBUTE, EmptyCString());
return NS_OK;
@ -1143,10 +1142,10 @@ AbsolutePositioningCommand::ToggleState(HTMLEditor* aHTMLEditor)
NS_IMETHODIMP
DecreaseZIndexCommand::IsCommandEnabled(const char* aCommandName,
nsISupports* refCon,
bool* outCmdEnabled)
nsISupports* aRefCon,
bool* aOutCmdEnabled)
{
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aRefCon);
if (NS_WARN_IF(!editor)) {
return NS_ERROR_FAILURE;
}
@ -1155,18 +1154,19 @@ DecreaseZIndexCommand::IsCommandEnabled(const char* aCommandName,
return NS_ERROR_FAILURE;
}
*outCmdEnabled = htmlEditor->AbsolutePositioningEnabled();
if (!(*outCmdEnabled))
if (!htmlEditor->IsAbsolutePositionEditorEnabled()) {
*aOutCmdEnabled = false;
return NS_OK;
}
RefPtr<Element> positionedElement = htmlEditor->GetPositionedElement();
*outCmdEnabled = false;
if (!positionedElement) {
*aOutCmdEnabled = false;
return NS_OK;
}
int32_t z = htmlEditor->GetZIndex(*positionedElement);
*outCmdEnabled = (z > 0);
*aOutCmdEnabled = (z > 0);
return NS_OK;
}
@ -1209,10 +1209,10 @@ DecreaseZIndexCommand::GetCommandStateParams(const char* aCommandName,
NS_IMETHODIMP
IncreaseZIndexCommand::IsCommandEnabled(const char* aCommandName,
nsISupports* refCon,
bool* outCmdEnabled)
nsISupports* aRefCon,
bool* aOutCmdEnabled)
{
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aRefCon);
if (NS_WARN_IF(!editor)) {
return NS_ERROR_FAILURE;
}
@ -1221,12 +1221,12 @@ IncreaseZIndexCommand::IsCommandEnabled(const char* aCommandName,
return NS_ERROR_FAILURE;
}
*outCmdEnabled = htmlEditor->AbsolutePositioningEnabled();
if (!(*outCmdEnabled))
if (!htmlEditor->IsAbsolutePositionEditorEnabled()) {
*aOutCmdEnabled = false;
return NS_OK;
}
Element* positionedElement = htmlEditor->GetPositionedElement();
*outCmdEnabled = (nullptr != positionedElement);
*aOutCmdEnabled = !!htmlEditor->GetPositionedElement();
return NS_OK;
}

Просмотреть файл

@ -69,7 +69,8 @@ HTMLEditorController::RegisterEditorDocStateCommands(
NS_REGISTER_NEXT_COMMAND(SetDocumentStateCommand, "cmd_insertBrOnReturn")
NS_REGISTER_NEXT_COMMAND(SetDocumentStateCommand, "cmd_defaultParagraphSeparator")
NS_REGISTER_NEXT_COMMAND(SetDocumentStateCommand, "cmd_enableObjectResizing")
NS_REGISTER_LAST_COMMAND(SetDocumentStateCommand, "cmd_enableInlineTableEditing")
NS_REGISTER_NEXT_COMMAND(SetDocumentStateCommand, "cmd_enableInlineTableEditing")
NS_REGISTER_LAST_COMMAND(SetDocumentStateCommand, "cmd_enableAbsolutePositionEditing")
NS_REGISTER_ONE_COMMAND(SetDocumentOptionsCommand, "cmd_setDocumentOptions")

Просмотреть файл

@ -362,6 +362,21 @@ SetDocumentStateCommand::DoCommandParams(const char* aCommandName,
return NS_OK;
}
if (!nsCRT::strcmp(aCommandName, "cmd_enableAbsolutePositionEditing")) {
NS_ENSURE_ARG_POINTER(aParams);
HTMLEditor* htmlEditor = textEditor->AsHTMLEditor();
if (NS_WARN_IF(!htmlEditor)) {
return NS_ERROR_INVALID_ARG;
}
ErrorResult error;
bool enabled = params->GetBool(STATE_ATTRIBUTE, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
htmlEditor->EnableAbsolutePositionEditor(enabled);
return NS_OK;
}
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -524,6 +539,18 @@ SetDocumentStateCommand::GetCommandStateParams(const char* aCommandName,
return NS_OK;
}
// cmd_enableAbsolutePositionEditing is a Gecko specific command,
// "cenableAbsolutePositionEditing".
if (!nsCRT::strcmp(aCommandName, "cmd_enableAbsolutePositionEditing")) {
NS_ENSURE_ARG_POINTER(aParams);
HTMLEditor* htmlEditor = textEditor->AsHTMLEditor();
if (NS_WARN_IF(!htmlEditor)) {
return NS_ERROR_INVALID_ARG;
}
return params->SetBool(STATE_ALL,
htmlEditor->IsAbsolutePositionEditorEnabled());
}
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -259,6 +259,10 @@ skip-if = toolkit == 'android' # bug 1315898
[test_bug1409520.html]
[test_bug1425997.html]
[test_abs_positioner_appearance.html]
skip-if = toolkit == 'android' && debug # bug 1480702, causes permanent failure of non-related test
[test_abs_positioner_positioning_elements.html]
skip-if = android_version == '18' # bug 1147989
[test_CF_HTML_clipboard.html]
subsuite = clipboard
[test_composition_event_created_in_chrome.html]

Просмотреть файл

@ -0,0 +1,167 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for absolute positioner appearance</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none;">
</div>
<div id="editor" contenteditable></div>
<div id="clickaway" style="width: 3px; height: 3px;"></div>
<img src="green.png"><!-- for ensuring to load the image at first test of <img> case -->
<pre id="test">
<script class="testbody" type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(async function() {
async function waitForSelectionChange() {
return new Promise(resolve => {
document.addEventListener("selectionchange", () => {
resolve();
}, {once: true});
});
}
let editor = document.getElementById("editor");
let outOfEditor = document.getElementById("clickaway");
async function testIfAppears() {
const kTests = [
{ description: "absolute positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: absolute; top: 50px; left: 50px;\">positioned</div>",
movable: true,
},
{ description: "fixed positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: fixed; top: 50px; left: 50px;\">positioned</div>",
movable: false,
},
{ description: "relative positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: relative; top: 50px; left: 50px;\">positioned</div>",
movable: false,
},
];
for (const kTest of kTests) {
const kDescription = "testIfAppears, " + kTest.description + ": ";
editor.innerHTML = kTest.innerHTML;
let target = document.getElementById("target");
document.execCommand("enableAbsolutePositionEditing", false, false);
ok(!document.queryCommandState("enableAbsolutePositionEditing"),
kDescription + "Absolute positioned element editor should be disabled by the call of execCommand");
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent1 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent1;
ok(!target.hasAttribute("_moz_abspos"),
kDescription + "While enableAbsolutePositioner is disabled, positioner shouldn't appear");
document.execCommand("enableAbsolutePositionEditing", false, true);
ok(document.queryCommandState("enableAbsolutePositionEditing"),
kDescription + "Absolute positioned element editor should be enabled by the call of execCommand");
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent2 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent2;
is(target.hasAttribute("_moz_abspos"), kTest.movable,
kDescription + (kTest.movable ? "While enableAbsolutePositionEditing is enabled, positioner should appear" :
"Even while enableAbsolutePositionEditing is enabled, positioner shouldn't appear"));
}
}
async function testStyle() {
// See HTMLEditor::GetTemporaryStyleForFocusedPositionedElement().
const kTests = [
{ description: "background-color: transparent; color: white;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-color: transparent; " +
"color: white;\">positioned</div>",
value: "black",
},
{ description: "background-color: transparent; color: black;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-color: transparent; " +
"color: black;\">positioned</div>",
value: "white",
},
{ description: "background-color: black; color: white;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-color: black; " +
"color: white;\">positioned</div>",
value: "",
},
{ description: "background-color: white; color: black;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-color: white; " +
"color: black;\">positioned</div>",
value: "",
},
{ description: "background-image: green.png; background-color: black; color: white;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-image: green.png; " +
"background-color: black; " +
"color: white;\">positioned</div>",
value: "",
},
{ description: "background-image: green.png; background-color: white; color: black;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-image: green.png; " +
"background-color: white; " +
"color: black;\">positioned</div>",
value: "",
},
{ description: "background-image: green.png;",
innerHTML: "<div id=\"target\" style=\"position: absolute; " +
"top: 50%; left: 50%; " +
"background-image: green.png;\">positioned</div>",
value: "white", // XXX Why? background-image is not "none"...
},
];
document.execCommand("enableAbsolutePositionEditing", false, true);
ok(document.queryCommandState("enableAbsolutePositionEditing"),
"testStyle, Absolute positioned element editor should be enabled by the call of execCommand");
for (const kTest of kTests) {
const kDescription = "testStyle, " + kTest.description + ": ";
editor.innerHTML = kTest.innerHTML;
let target = document.getElementById("target");
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent;
is(target.getAttribute("_moz_abspos"), kTest.value,
kDescription + "The value of _moz_abspos attribute is unexpected");
}
}
await testIfAppears();
await testStyle();
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,120 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for positioners of absolute positioned elements</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
#target {
background-color: green;
}
</style>
</head>
<body>
<p id="display"></p>
<div id="content" contenteditable style="height: 200px; width: 200px;"></div>
<div id="clickaway" style="position: absolute; top: 250px; width: 10px; height: 10px; z-index: 100;"></div>
<img src="green.png"><!-- for ensuring to load the image at first test of <img> case -->
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(async function() {
document.execCommand("enableAbsolutePositionEditing", false, true);
ok(document.queryCommandState("enableAbsolutePositionEditing"),
"Absolute positioned element editor should be enabled by the call of execCommand");
let outOfEditor = document.getElementById("clickaway");
function cancel(e) { /* TODO: e.stopPropagation(); */ }
let content = document.getElementById("content");
content.addEventListener("mousedown", cancel);
content.addEventListener("mousemove", cancel);
content.addEventListener("mouseup", cancel);
async function waitForSelectionChange() {
return new Promise(resolve => {
document.addEventListener("selectionchange", () => {
resolve();
}, {once: true});
});
}
async function doTest(aDescription, aInnerHTML) {
content.innerHTML = aInnerHTML;
let description = aDescription + ": ";
let target = document.getElementById("target");
target.style.position = "absolute";
async function testPositioner(aDeltaX, aDeltaY) {
ok(true, description + "testPositioner(" + [aDeltaX, aDeltaY].join(", ") + ")");
// Reset the position of the target.
target.style.top = "50px";
target.style.left = "50px";
// Click on the target to show the positioner.
let promiseSelectionChangeEvent = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent;
let rect = target.getBoundingClientRect();
ok(target.hasAttribute("_moz_abspos"),
description + "While enableAbsolutePositionEditing is enabled, the positioner should appear");
// left is abs positioned element's left + margin-left + border-left-width + 12.
// XXX Perhaps, we need to add border-left-width here if you add new test to have thick border.
const kPositionerX = 18
// top is abs positioned element's top + margin-top + border-top-width - 14.
// XXX Perhaps, we need to add border-top-width here if you add new test to have thick border.
const kPositionerY = -7;
// Click on the positioner.
synthesizeMouse(target, kPositionerX, kPositionerY, {type: "mousedown"});
// Drag it delta pixels.
synthesizeMouse(target, kPositionerX + aDeltaX, kPositionerY + aDeltaY, {type: "mousemove"});
// Release the mouse button
synthesizeMouse(target, kPositionerX + aDeltaX, kPositionerY + aDeltaY, {type: "mouseup"});
// Move the mouse delta more pixels to the same direction to make sure that the
// positioning operation has stopped.
synthesizeMouse(target, kPositionerX + aDeltaX * 2, kPositionerY + aDeltaY * 2, {type: "mousemove"});
// Click outside of the image to hide the positioner.
synthesizeMouseAtCenter(outOfEditor, {});
// Get the new dimensions for the absolute positioned element.
let newRect = target.getBoundingClientRect();
isfuzzy(newRect.x, rect.x + aDeltaX, 1, description + "The left should be increased by " + aDeltaX + " pixels");
isfuzzy(newRect.y, rect.y + aDeltaY, 1, description + "The top should be increased by " + aDeltaY + "pixels");
}
await testPositioner( 10, 10);
await testPositioner( 10, -10);
await testPositioner(-10, 10);
await testPositioner(-10, -10);
}
const kTests = [
{ description: "Positioner for <img>",
innerHTML: "<img id=\"target\" src=\"green.png\">",
},
{ description: "Positioner for <table>",
innerHTML: "<table id=\"target\" border><tr><td>cell</td><td>cell</td></tr></table>",
},
{ description: "Positioner for <div>",
innerHTML: "<div id=\"target\">div element</div>",
},
];
for (const kTest of kTests) {
await doTest(kTest.description, kTest.innerHTML);
}
content.innerHTML = "";
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -44,7 +44,7 @@ SimpleTest.waitForFocus(async function() {
},
{ description: "absolute positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: absolute; top: 50px; left: 50px;\">positioned</div>",
resizable: true,
resizable: function () { return document.queryCommandState("enableAbsolutePositionEditing"); },
},
{ description: "fixed positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: fixed; top: 50px; left: 50px;\">positioned</div>",
@ -56,35 +56,40 @@ SimpleTest.waitForFocus(async function() {
},
];
for (const kTest of kTests) {
const kDescription = kTest.description + ": ";
editor.innerHTML = kTest.innerHTML;
let target = document.getElementById("target");
for (let kEnableAbsolutePositionEditor of [true, false]) {
document.execCommand("enableAbsolutePositionEditing", false, kEnableAbsolutePositionEditor);
for (const kTest of kTests) {
const kDescription = kTest.description +
(kEnableAbsolutePositionEditor ? " (enabled absolute position editor)" : "") + ": ";
editor.innerHTML = kTest.innerHTML;
let target = document.getElementById("target");
document.execCommand("enableObjectResizing", false, false);
ok(!document.queryCommandState("enableObjectResizing"),
kDescription + "Object resizer should be disabled by the call of execCommand");
document.execCommand("enableObjectResizing", false, false);
ok(!document.queryCommandState("enableObjectResizing"),
kDescription + "Object resizer should be disabled by the call of execCommand");
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent1 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent1;
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent1 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent1;
ok(!target.hasAttribute("_moz_resizing"),
kDescription + ": While enableObjectResizing is disabled, resizers shouldn't appear");
ok(!target.hasAttribute("_moz_resizing"),
kDescription + ": While enableObjectResizing is disabled, resizers shouldn't appear");
document.execCommand("enableObjectResizing", false, true);
ok(document.queryCommandState("enableObjectResizing"),
kDescription + "Object resizer should be enabled by the call of execCommand");
document.execCommand("enableObjectResizing", false, true);
ok(document.queryCommandState("enableObjectResizing"),
kDescription + "Object resizer should be enabled by the call of execCommand");
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent2 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent2;
synthesizeMouseAtCenter(outOfEditor, {});
let promiseSelectionChangeEvent2 = waitForSelectionChange();
synthesizeMouseAtCenter(target, {});
await promiseSelectionChangeEvent2;
is(target.hasAttribute("_moz_resizing"), kTest.resizable,
kDescription + (kTest.resizable ? "While enableObjectResizing is enabled, resizers should appear" :
"Even while enableObjectResizing is enabled, resizers shouldn't appear"));
const kResizable = typeof kTest.resizable === "function" ? kTest.resizable() : kTest.resizable;
is(target.hasAttribute("_moz_resizing"), kResizable,
kDescription + (kResizable ? "While enableObjectResizing is enabled, resizers should appear" :
"Even while enableObjectResizing is enabled, resizers shouldn't appear"));
}
}
SimpleTest.finish();

Просмотреть файл

@ -47,6 +47,9 @@ SimpleTest.waitForFocus(async function() {
if (SpecialPowers.getBoolPref("editor.resizing.preserve_ratio")) {
description += " (preserve ratio pref is true)";
}
if (document.queryCommandState("enableAbsolutePositionEditing")) {
description += " (absolute position editor is enabled)";
}
description += ": ";
content.innerHTML = aInnerHTML;
let target = document.getElementById("target");
@ -202,23 +205,31 @@ SimpleTest.waitForFocus(async function() {
{ description: "Resiziers for <img>",
innerHTML: "<img id=\"target\" src=\"green.png\">",
mayPreserveRatio: true,
isAbsolutePosition: false,
},
{ description: "Resiziers for <table>",
innerHTML: "<table id=\"target\" border><tr><td>cell</td><td>cell</td></tr></table>",
mayPreserveRatio: false,
isAbsolutePosition: false,
},
{ description: "Resiziers for absolute positioned <div>",
innerHTML: "<div id=\"target\" style=\"position: absolute; top: 50px; left: 50px;\">positioned</div>",
mayPreserveRatio: false,
isAbsolutePosition: true,
},
];
// Resizers for absolute positioned element are available only when
// enableAbsolutePositionEditing is enabled. So, let's enable it
// during testing resizers for absolute positioned elements.
await SpecialPowers.pushPrefEnv({"set": [["editor.resizing.preserve_ratio", false]]});
for (const kTest of kTests) {
document.execCommand("enableAbsolutePositionEditing", false, kTests.isAbsolutePosition);
await doTest(kTest.description, false, kTest.innerHTML);
}
await SpecialPowers.pushPrefEnv({"set": [["editor.resizing.preserve_ratio", true]]});
for (const kTest of kTests) {
document.execCommand("enableAbsolutePositionEditing", false, kTests.isAbsolutePosition);
await doTest(kTest.description, kTest.mayPreserveRatio, kTest.innerHTML);
}
content.innerHTML = "";