Skip to content

Commit

Permalink
Backed out 2 changesets (bug 1692673) for causing build bustages on E…
Browse files Browse the repository at this point in the history
…ditorBase.cpp. CLOSED TREE

Backed out changeset 988b919adc5c (bug 1692673)
Backed out changeset 5b1ba8dbfc8a (bug 1692673)
  • Loading branch information
Butkovits Atila committed Mar 11, 2021
1 parent ba23557 commit 479d6f8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 247 deletions.
47 changes: 4 additions & 43 deletions editor/libeditor/TextEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@
#include "PlaceholderTransaction.h"
#include "gfxFontUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/ContentIterator.h"
#include "mozilla/EditAction.h"
#include "mozilla/EditorDOMPoint.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/LookAndFeel.h"
Expand Down Expand Up @@ -56,7 +54,6 @@
#include "nsIWeakReferenceUtils.h"
#include "nsNameSpaceManager.h"
#include "nsLiteralString.h"
#include "nsPresContext.h"
#include "nsReadableUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
Expand Down Expand Up @@ -1217,52 +1214,17 @@ bool TextEditor::AreClipboardCommandsUnconditionallyEnabled() const {
return document && document->AreClipboardCommandsUnconditionallyEnabled();
}

bool TextEditor::CheckForClipboardCommandListener(
nsAtom* aCommand, EventMessage aEventMessage) const {
RefPtr<Document> document = GetDocument();
if (!document) {
return false;
}
RefPtr<PresShell> presShell = document->GetObservingPresShell();
if (!presShell) {
return false;
}
RefPtr<nsPresContext> presContext = presShell->GetPresContext();
if (!presContext) {
return false;
}

RefPtr<EventTarget> et = GetDOMEventTarget();
while (et) {
EventListenerManager* elm = et->GetOrCreateListenerManager();
if (elm && elm->HasListenersFor(aCommand)) {
return true;
}
InternalClipboardEvent event(true, aEventMessage);
EventChainPreVisitor visitor(presContext, &event, nullptr,
nsEventStatus_eIgnore, false, et);
et->GetEventTargetParent(visitor);
et = visitor.GetParentTarget();
}

return false;
}

bool TextEditor::IsCutCommandEnabled() const {
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return false;
}

if (IsModifiable() && IsCopyToClipboardAllowedInternal()) {
if (AreClipboardCommandsUnconditionallyEnabled()) {
return true;
}

// If there's an event listener for "cut", we always enable the command
// as we don't really know what the listener may want to do in response.
// We look up the event target chain for a possible listener on a parent
// in addition to checking the immediate target.
return CheckForClipboardCommandListener(nsGkAtoms::oncut, eCut);
return IsModifiable() && IsCopyToClipboardAllowedInternal();
}

NS_IMETHODIMP TextEditor::Copy() {
Expand All @@ -1284,12 +1246,11 @@ bool TextEditor::IsCopyCommandEnabled() const {
return false;
}

if (IsCopyToClipboardAllowedInternal()) {
if (AreClipboardCommandsUnconditionallyEnabled()) {
return true;
}

// Like "cut", always enable "copy" if there's a listener.
return CheckForClipboardCommandListener(nsGkAtoms::oncopy, eCopy);
return IsCopyToClipboardAllowedInternal();
}

bool TextEditor::CanDeleteSelection() const {
Expand Down
11 changes: 2 additions & 9 deletions editor/libeditor/TextEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
* disabled. This always returns true if we're in non-chrome HTML/XHTML
* document. Otherwise, same as the result of `IsCopyToClipboardAllowed()`.
*/
MOZ_CAN_RUN_SCRIPT bool IsCutCommandEnabled() const;
bool IsCutCommandEnabled() const;

NS_IMETHOD Copy() override;

Expand All @@ -105,7 +105,7 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
* This always returns true if we're in non-chrome HTML/XHTML document.
* Otherwise, same as the result of `IsCopyToClipboardAllowed()`.
*/
MOZ_CAN_RUN_SCRIPT bool IsCopyCommandEnabled() const;
bool IsCopyCommandEnabled() const;

/**
* IsCopyToClipboardAllowed() returns true if the selected content can
Expand Down Expand Up @@ -786,13 +786,6 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
bool aNotify,
bool aForceStartMasking);

/**
* Helper for Is{Cut|Copy}CommandEnabled.
* Look for a listener for the given command, including up the target chain.
*/
MOZ_CAN_RUN_SCRIPT bool CheckForClipboardCommandListener(
nsAtom* aCommand, EventMessage aEventMessage) const;

protected:
mutable nsCOMPtr<nsIDocumentEncoder> mCachedDocumentEncoder;

Expand Down
186 changes: 15 additions & 171 deletions editor/libeditor/tests/test_cut_copy_delete_command_enabled.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,182 +24,41 @@

function doTest() {
var text = $("text-field");
var textWithHandlers = $("text-field-2");
var password = $("password-field");
var passwordWithHandlers = $("password-field-2");
var textWithParentHandlers = $("text-field-3");
var passwordWithParentHandlers = $("password-field-3");
var textarea1 = $("text-area-1");
var textarea2 = $("text-area-2");
var textarea3 = $("text-area-3");

var editor1 = SpecialPowers.wrap(text).editor;
var editor2 = SpecialPowers.wrap(password).editor;
var editor3 = SpecialPowers.wrap(textWithHandlers).editor;
var editor4 = SpecialPowers.wrap(passwordWithHandlers).editor;
var editor5 = SpecialPowers.wrap(textWithParentHandlers).editor;
var editor6 = SpecialPowers.wrap(passwordWithParentHandlers).editor;
var editor7 = SpecialPowers.wrap(textarea1).editor;
var editor8 = SpecialPowers.wrap(textarea2).editor;
var editor9 = SpecialPowers.wrap(textarea3).editor;

text.focus();

ok(!editor1.canCopy(),
"nsIEditor.canCopy() should return false in <input type=text> with no selection");
ok(!editor1.canCut(),
"nsIEditor.canCut() should return false in <input type=text> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be disabled in <input type=text> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be disabled in <input type=text> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be disabled in <input type=text> with no selection");

text.select();

ok(editor1.canCopy(),
"nsIEditor.canCopy() should return true in <input type=text> with selection");
"nsIEditor.canCopy() should return true in <input type=text>");
ok(editor1.canCut(),
"nsIEditor.canCut() should return true in <input type=text> with selection");
"nsIEditor.canCut() should return true in <input type=text>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <input type=text> with selection");
"cmd_copy command should be enabled in <input type=text>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <input type=text> with selection");
"cmd_cut command should be enabled in <input type=text>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be enabled in <input type=text> with selection");
"cmd_delete command should be enabled in <input type=text>");

password.focus();

ok(!editor2.canCopy(),
"nsIEditor.canCopy() should return false in <input type=password> with no selection");
ok(!editor2.canCut(),
"nsIEditor.canCut() should return false in <input type=password> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be disabled in <input type=password> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be disabled in <input type=password> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be disabled in <input type=password> with no selection");

// Copy and cut commands don't do anything on password fields by default,
// so they remain disabled even when there is a selection...
password.select();

ok(!editor2.canCopy(),
"nsIEditor.canCopy() should return false in <input type=password> with selection");
ok(!editor2.canCut(),
"nsIEditor.canCut() should return false in <input type=password> with selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be disabled in <input type=password> with selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be disabled in <input type=password> with selection");
// Delete, on the other hand, does apply to password fields.
ok(SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be enabled in <input type=password with selection>");

// ...but webpages can hook up event handlers to cut/copy events, so we have to
// keep the cut and copy commands enabled if event handlers are attached,
// for both regular edit fields and password fields (even when there's no
// selection, as we don't know what the handler might want to do).
textWithHandlers.focus();

ok(editor3.canCopy(),
"nsIEditor.canCopy() should return true in <input type=text> with event handler");
ok(editor3.canCut(),
"nsIEditor.canCut() should return true in <input type=text> with event handler");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <input type=text> with event handler");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <input type=text> with event handler");

passwordWithHandlers.focus();

ok(editor4.canCopy(),
"nsIEditor.canCopy() should return true in <input type=password> with event handler");
ok(editor4.canCut(),
"nsIEditor.canCut() should return true in <input type=password> with event handler");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <input type=password> with event handler");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <input type=password> with event handler");

// Also check that the commands are enabled if there's a handler on a parent element.
textWithParentHandlers.focus();

ok(editor5.canCopy(),
"nsIEditor.canCopy() should return true in <input type=text> with event handler on an ancestor");
ok(editor5.canCut(),
"nsIEditor.canCut() should return true in <input type=text> with event handler on an ancestor");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <input type=text> with event handler on an ancestor");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <input type=text> with event handler on an ancestor");

passwordWithParentHandlers.focus();

ok(editor6.canCopy(),
"nsIEditor.canCopy() should return true in <input type=password> with event handler on an ancestor");
ok(editor6.canCut(),
"nsIEditor.canCut() should return true in <input type=password> with event handler on an ancestor");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <input type=password> with event handler on an ancestor");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <input type=password> with event handler on an ancestor");

// TEXTAREA tests

textarea1.focus();

ok(!editor7.canCopy(),
"nsIEditor.canCopy() should return false in <textarea> with no selection");
ok(!editor7.canCut(),
"nsIEditor.canCut() should return false in <textarea> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be disabled in <textarea> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be disabled in <textarea> with no selection");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be disabled in <textarea> with no selection");

textarea1.select();

ok(editor7.canCopy(),
"nsIEditor.canCopy() should return true in <textarea> with selection");
ok(editor7.canCut(),
"nsIEditor.canCut() should return true in <textarea> with selection");
// Copy and cut commands don't do anything on password fields by default,
// but webpages can hook up event handlers to the event, and thus, we have to
// always keep the cut and copy event enabled in HTML/XHTML documents.
ok(editor2.canCopy(),
"nsIEditor.canCopy() should return true in <input type=password>");
ok(editor2.canCut(),
"nsIEditor.canCut() should return true in <input type=password>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <textarea> with selection");
"cmd_copy command should be enabled in <input type=password>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <textarea> with selection");
"cmd_cut command should be enabled in <input type=password>");
ok(SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be enabled in <textarea> with selection");

textarea2.focus();

ok(!editor8.canCopy(),
"nsIEditor.canCopy() should return false in <textarea> with only a 'cut' handler");
ok(editor8.canCut(),
"nsIEditor.canCut() should return true in <textarea> with only a 'cut' handler");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be disabled in <textarea> with only a 'cut' handler");
ok(SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be enabled in <textarea> with only a 'cut' handler");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be disabled in <textarea> with only a 'cut' handler");

textarea3.focus();

ok(editor9.canCopy(),
"nsIEditor.canCopy() should return true in <textarea> with only a 'copy' handler on ancestor");
ok(!editor9.canCut(),
"nsIEditor.canCut() should return false in <textarea> with only a 'copy' handler on ancestor");
ok(SpecialPowers.isCommandEnabled(window, "cmd_copy"),
"cmd_copy command should be enabled in <textarea> with only a 'copy' handler on ancestor");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_cut"),
"cmd_cut command should be disabled in <textarea> with only a 'copy' handler on ancestor");
ok(!SpecialPowers.isCommandEnabled(window, "cmd_delete"),
"cmd_delete command should be disabled in <textarea> with only a 'copy' handler on ancestor");
"cmd_delete command should be enabled in <input type=password>");

SimpleTest.finish();
}
Expand All @@ -208,20 +67,5 @@

<input type="text" value="Gonzo says hi" id="text-field" />
<input type="password" value="Jan also" id="password-field" />
<input type="text" value="Hi says Gonzo" id="text-field-2" oncut="cut()" oncopy="copy()" ondelete="delete()"/>
<input type="password" value="Also Jan" id="password-field-2" oncut="cut()" oncopy="copy()" ondelete="delete()"/>
<div oncut="cut()">
<ul oncopy="copy()">
<li><input type="text" value="Hi again" id="text-field-3"/></li>
<li><input type="password" value="And again, hi" id="password-field-3"/></li>
</ul>
</div>
<textarea id="text-area-1">textarea</textarea>
<textarea oncut="cut()" id="text-area-2">textarea with cut handler</textarea>
<div oncopy="copy()">
<blockquote>
<p><textarea id="text-area-3">textarea with copy handler on parent</textarea></p>
</blockquote>
</div>
</body>
</html>
24 changes: 0 additions & 24 deletions toolkit/content/tests/browser/browser_bug1170531.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ add_task(async function() {
is(menu_copy_disabled, false, "menu_copy should be enabled");
await new Promise(closeMenu);

// When there is no text selected in the contentEditable, we expect the Cut
// and Copy commands to be disabled.
BrowserTestUtils.loadURI(
browser,
"data:text/html,<div contentEditable='true'>hello!</div>"
Expand All @@ -84,28 +82,6 @@ add_task(async function() {
window.requestAnimationFrame(() => executeSoon(resolve))
);
await new Promise(openMenu);
menu_cut_disabled =
menuPopup.querySelector("#menu_cut").getAttribute("disabled") == "true";
is(menu_cut_disabled, true, "menu_cut should be disabled");
menu_copy_disabled =
menuPopup.querySelector("#menu_copy").getAttribute("disabled") ==
"true";
is(menu_copy_disabled, true, "menu_copy should be disabled");
await new Promise(closeMenu);

// When the text of the contentEditable is selected, the Cut and Copy commands
// should be enabled.
BrowserTestUtils.loadURI(
browser,
"data:text/html,<div contentEditable='true'>hello!</div><script>r=new Range;r.selectNodeContents(document.body.firstChild);document.getSelection().addRange(r);</script>"
);
await BrowserTestUtils.browserLoaded(browser);
browser.focus();
await new Promise(resolve => waitForFocus(resolve, window));
await new Promise(resolve =>
window.requestAnimationFrame(() => executeSoon(resolve))
);
await new Promise(openMenu);
menu_cut_disabled =
menuPopup.querySelector("#menu_cut").getAttribute("disabled") == "true";
is(menu_cut_disabled, false, "menu_cut should be enabled");
Expand Down

0 comments on commit 479d6f8

Please sign in to comment.