mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 08:42:13 +00:00
Bug 1220696 - part 4: Make Document
consider whether the target is editable or not-editable with target editor r=smaug
Currently, `Document` checks it only with whether the document is editable or not. Only with this check, `execCommand` and the other related methods work only when there is `contenteditable`. Therefore, this patch makes it to check whether the target is editable or not with target editor. Differential Revision: https://phabricator.services.mozilla.com/D108570
This commit is contained in:
parent
f956ee81ea
commit
b2fd51c051
@ -5103,6 +5103,21 @@ TextEditor* Document::AutoEditorCommandTarget::GetTargetEditor() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Document::AutoEditorCommandTarget::IsEditable(Document* aDocument) const {
|
||||
if (RefPtr<Document> doc = aDocument->GetInProcessParentDocument()) {
|
||||
// Make sure frames are up to date, since that can affect whether
|
||||
// we're editable.
|
||||
doc->FlushPendingNotifications(FlushType::Frames);
|
||||
}
|
||||
TextEditor* targetEditor = GetTargetEditor();
|
||||
if (targetEditor && targetEditor->IsTextEditor()) {
|
||||
// FYI: When `disabled` attribute is set, `TextEditor` treats it as
|
||||
// "readonly" too.
|
||||
return !targetEditor->IsReadonly();
|
||||
}
|
||||
return aDocument->IsEditingOn();
|
||||
}
|
||||
|
||||
bool Document::AutoEditorCommandTarget::IsCommandEnabled() const {
|
||||
TextEditor* targetEditor = GetTargetEditor();
|
||||
if (!targetEditor) {
|
||||
@ -5187,11 +5202,6 @@ bool Document::ExecCommand(const nsAString& aHTMLCommandName, bool aShowUI,
|
||||
return false;
|
||||
}
|
||||
|
||||
// if editing is not on, bail
|
||||
if (commandData.IsAvailableOnlyWhenEditable() && !IsEditingOnAfterFlush()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (commandData.mCommand == Command::GetHTML) {
|
||||
return false;
|
||||
}
|
||||
@ -5217,6 +5227,11 @@ bool Document::ExecCommand(const nsAString& aHTMLCommandName, bool aShowUI,
|
||||
// by order of controllers in `nsCommandManager::GetControllerForCommand()`.
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (commandData.IsAvailableOnlyWhenEditable() &&
|
||||
!editCommandTarget.IsEditable(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (editCommandTarget.DoNothing()) {
|
||||
return false;
|
||||
}
|
||||
@ -5359,13 +5374,12 @@ bool Document::QueryCommandEnabled(const nsAString& aHTMLCommandName,
|
||||
return false;
|
||||
}
|
||||
|
||||
// if editing is not on, bail
|
||||
if (!IsEditingOnAfterFlush()) {
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (!editCommandTarget.IsEditable(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (editCommandTarget.IsEditor()) {
|
||||
return editCommandTarget.IsCommandEnabled();
|
||||
}
|
||||
@ -5399,13 +5413,11 @@ bool Document::QueryCommandIndeterm(const nsAString& aHTMLCommandName,
|
||||
return false;
|
||||
}
|
||||
|
||||
// if editing is not on, bail
|
||||
if (!IsEditingOnAfterFlush()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (!editCommandTarget.IsEditable(this)) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<nsCommandParams> params = new nsCommandParams();
|
||||
if (editCommandTarget.IsEditor()) {
|
||||
if (NS_FAILED(editCommandTarget.GetCommandStateParams(*params))) {
|
||||
@ -5449,11 +5461,6 @@ bool Document::QueryCommandState(const nsAString& aHTMLCommandName,
|
||||
return false;
|
||||
}
|
||||
|
||||
// if editing is not on, bail
|
||||
if (!IsEditingOnAfterFlush()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aHTMLCommandName.LowerCaseEqualsLiteral("usecss")) {
|
||||
// Per spec, state is supported for styleWithCSS but not useCSS, so we just
|
||||
// return false always.
|
||||
@ -5462,6 +5469,9 @@ bool Document::QueryCommandState(const nsAString& aHTMLCommandName,
|
||||
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (!editCommandTarget.IsEditable(this)) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<nsCommandParams> params = new nsCommandParams();
|
||||
if (editCommandTarget.IsEditor()) {
|
||||
if (NS_FAILED(editCommandTarget.GetCommandStateParams(*params))) {
|
||||
@ -5588,13 +5598,11 @@ void Document::QueryCommandValue(const nsAString& aHTMLCommandName,
|
||||
return;
|
||||
}
|
||||
|
||||
// if editing is not on, bail
|
||||
if (!IsEditingOnAfterFlush()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsPresContext> presContext = GetPresContext();
|
||||
AutoEditorCommandTarget editCommandTarget(presContext, commandData);
|
||||
if (!editCommandTarget.IsEditable(this)) {
|
||||
return;
|
||||
}
|
||||
RefPtr<nsCommandParams> params = new nsCommandParams();
|
||||
// FYI: Only GetHTML command is not implemented by editor. Use window's
|
||||
// command table instead.
|
||||
@ -5655,17 +5663,6 @@ void Document::QueryCommandValue(const nsAString& aHTMLCommandName,
|
||||
CopyUTF8toUTF16(result, aValue);
|
||||
}
|
||||
|
||||
bool Document::IsEditingOnAfterFlush() {
|
||||
RefPtr<Document> doc = GetInProcessParentDocument();
|
||||
if (doc) {
|
||||
// Make sure frames are up to date, since that can affect whether
|
||||
// we're editable.
|
||||
doc->FlushPendingNotifications(FlushType::Frames);
|
||||
}
|
||||
|
||||
return IsEditingOn();
|
||||
}
|
||||
|
||||
void Document::MaybeEditingStateChanged() {
|
||||
if (!mPendingMaybeEditingStateChanged && mMayStartLayout &&
|
||||
mUpdateNestLevel == 0 && (mContentEditableCount > 0) != IsEditingOn()) {
|
||||
|
@ -1578,11 +1578,6 @@ class Document : public nsINode,
|
||||
*/
|
||||
void DisconnectNodeTree();
|
||||
|
||||
/**
|
||||
* Like IsEditingOn(), but will flush as needed first.
|
||||
*/
|
||||
bool IsEditingOnAfterFlush();
|
||||
|
||||
/**
|
||||
* MaybeDispatchCheckKeyPressEventModelEvent() dispatches
|
||||
* "CheckKeyPressEventModel" event to check whether we should dispatch
|
||||
@ -4197,6 +4192,7 @@ class Document : public nsINode,
|
||||
delete;
|
||||
|
||||
bool DoNothing() const { return mDoNothing; }
|
||||
MOZ_CAN_RUN_SCRIPT bool IsEditable(Document* aDocument) const;
|
||||
bool IsEditor() const {
|
||||
MOZ_ASSERT_IF(mEditorCommand, mActiveEditor || mHTMLEditor);
|
||||
return !!mEditorCommand;
|
||||
|
@ -35,102 +35,12 @@
|
||||
[In <input>, execCommand("paste", false, null), a[\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), ab[\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), ab[\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), ab[\]c): <input>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), ab[\]c): input.inputType should be deleteContentBackward]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), ab[\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), a[b\]c): <input>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), a[b\]c): input.inputType should be deleteContentBackward]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("delete", false, null), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[b\]c): <input>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[b\]c): input.inputType should be deleteContentForward]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[\]bc): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[\]bc): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[\]bc): <input>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[\]bc): input.inputType should be deleteContentForward]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("forwarddelete", false, null), a[\]bc): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("selectall", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("selectall", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("selectall", false, null), a[b\]c): <input>.value should be "[abc\]"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("undo", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("undo", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("undo", false, null), a[b\]c): input.inputType should be historyUndo]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("undo", false, null), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("redo", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("redo", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("redo", false, null), a[b\]c): <input>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("redo", false, null), a[b\]c): input.inputType should be historyRedo]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("redo", false, null), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserthtml", false, <b>inserted</b>), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
@ -146,21 +56,6 @@
|
||||
[In <input>, execCommand("inserthtml", false, <b>inserted</b>), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserttext", false, **inserted**), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserttext", false, **inserted**), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserttext", false, **inserted**), a[b\]c): <input>.value should be "a**inserted**[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserttext", false, **inserted**), a[b\]c): input.inputType should be insertText]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("inserttext", false, **inserted**), a[b\]c): input.target should be [object HTMLInputElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <input>, execCommand("contentReadOnly", false, true), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
@ -227,102 +122,12 @@
|
||||
[In <textarea>, execCommand("paste", false, null), a[\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), ab[\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), ab[\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), ab[\]c): <textarea>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), ab[\]c): input.inputType should be deleteContentBackward]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), ab[\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), a[b\]c): <textarea>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), a[b\]c): input.inputType should be deleteContentBackward]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("delete", false, null), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[b\]c): <textarea>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[b\]c): input.inputType should be deleteContentForward]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[\]bc): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[\]bc): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[\]bc): <textarea>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[\]bc): input.inputType should be deleteContentForward]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("forwarddelete", false, null), a[\]bc): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("selectall", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("selectall", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("selectall", false, null), a[b\]c): <textarea>.value should be "[abc\]"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("undo", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("undo", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("undo", false, null), a[b\]c): input.inputType should be historyUndo]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("undo", false, null), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("redo", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("redo", false, null), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("redo", false, null), a[b\]c): <textarea>.value should be "a[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("redo", false, null), a[b\]c): input.inputType should be historyRedo]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("redo", false, null), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserthtml", false, <b>inserted</b>), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
@ -338,21 +143,6 @@
|
||||
[In <textarea>, execCommand("inserthtml", false, <b>inserted</b>), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserttext", false, **inserted**), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserttext", false, **inserted**), a[b\]c): execCommand() should return true]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserttext", false, **inserted**), a[b\]c): <textarea>.value should be "a**inserted**[\]c"]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserttext", false, **inserted**), a[b\]c): input.inputType should be insertText]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("inserttext", false, **inserted**), a[b\]c): input.target should be [object HTMLTextAreaElement\]]
|
||||
expected: FAIL
|
||||
|
||||
[In <textarea>, execCommand("insertparagraph", false, null), a[b\]c): The command should be enabled]
|
||||
expected: FAIL
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user