The purpose of this patch is to prevent users to make changes to
read-only editors.
This patch forces `IsCommandEnabled()` to return false for read-only
editors for "standard" editor commands that could have an associated
icon or menu entry and are therefore user-accessible.
This patch does not modify/test any paste commands or any of the
advanced internal editor commands.
Differential Revision: https://phabricator.services.mozilla.com/D203754
The purpose of this patch is to prevent users to make changes to
read-only editors.
This patch forces `IsCommandEnabled()` to return false for read-only
editors for "standard" editor commands that could have an associated
icon or menu entry and are therefore user-accessible.
Advanced internal editor commands are not touched.
Differential Revision: https://phabricator.services.mozilla.com/D203754
If a `paste` event listener moves focus, Chrome makes new editor keep handling
the pasting. For the compatibility, we should follow it unless the new focused
element is in different document because user should allow to paste it
explicitly.
On the other hand, this just stops handling "cut" in same situation because
handling it requires to update clipboard without user's activation. Therefore,
the clipboard content and/or the new editor content may be lost from the users
point of view.
Note that `nsContentUtils::GetActiveEditor` may return `HTMLEditor` instance
when focused element does not have `TextEditor` even when non-editable element
has focus. Therefore, if it returns an `HTMLEditor`, we need to check whether
it's active in the DOM window with a call of `HTMEditor::IsActiveInDOMWindow`.
Differential Revision: https://phabricator.services.mozilla.com/D176741
If a `paste` event listener moves focus, Chrome makes new editor keep handling
the pasting. For the compatibility, we should follow it unless the new focused
element is in different document because user should allow to paste it
explicitly.
On the other hand, this just stops handling "cut" in same situation because
handling it requires to update clipboard without user's activation. Therefore,
the clipboard content and/or the new editor content may be lost from the users
point of view.
Note that `nsContentUtils::GetActiveEditor` may return `HTMLEditor` instance
when focused element does not have `TextEditor` even when non-editable element
has focus. Therefore, if it returns an `HTMLEditor`, we need to check whether
it's active in the DOM window with a call of `HTMEditor::IsActiveInDOMWindow`.
Differential Revision: https://phabricator.services.mozilla.com/D176741
`TextEditor` will be not a parent class of `HTMLEditor`. Therefore, editor
command classes should use `EditorBase` class instead.
Depends on D117116
Differential Revision: https://phabricator.services.mozilla.com/D117117
It should be a virtual method derived from `EditorBase`, and `TextEditor`
and `HTMLEditor` should override it. Then, `nsIEditor::Paste()` requires
referring vtable again if we keep implementing it only in `EditorBase`.
Therefore, this patch avoid it with implementing it in both `TextEditor`
and `HTMLEditor`.
Depends on D116567
Differential Revision: https://phabricator.services.mozilla.com/D116568
`TextEditor` declares some virtual methods newly. However, for moving some
methods from `TextEditor` to `EditorBase`, they should be accessible from
`EditorBase`. Therefore, this patch adds declarations of pure virtual
methods of them to `EditorBase`.
Differential Revision: https://phabricator.services.mozilla.com/D115796
They just work with a transaction manager and transactions, and they are used
by both `TextEditor` and `HTMLEditor`. Therefore, they should be in
`EditorBase` for making `HTMLEditor` stop inheriting `TextEditor` in the
future.
Depends on D115787
Differential Revision: https://phabricator.services.mozilla.com/D115788
Those command handlers just check whether the given editor is an `HTMLEditor`
or not. Therefore, we should make them check whether the given editor is
a single line editor or not instead.
Differential Revision: https://phabricator.services.mozilla.com/D108572
Those command handlers just check whether the given editor is an `HTMLEditor`
or not. Therefore, we should make them check whether the given editor is
a single line editor or not instead.
Differential Revision: https://phabricator.services.mozilla.com/D108572
`DeleteSelection*()` are members of `TextEditor`, but they are also used by
`HTMLEditor`. Therefore, they and pref cache members for them should be
in `EditorBase` too.
Depends on D71911
Differential Revision: https://phabricator.services.mozilla.com/D72290
`TextEditRules::DocumentIsEmpty()` is a wrapper of `TextEditor::IsEmpty()` so
that we can get rid of it simply.
`HTMLEditRules::DocumentIsEmpty()` needs to change. It's oddly checks only
`EditorBase::mPaddingBRElementForEmptyEditor` is `nullptr` or not. However,
the editor may be completely empty. And the result may be different from
`TextEditor::IsEmpty()` which is not overridden by `HTMLEditor`. For partially
solving this issue, this patch makes `HTMLEditor` overrides `IsEmpty()` and
optimizes `TextEditor::IsEmpty()`.
With this change, the caller of `HTMLEditRules::DocumentIsEmpty()` may behave
differently in the only caller, `HTMLEditor::SelectEntireDocument()`. And
unfortunately, its root called from `SelectAllCommand::DoCommand()`. However,
it does just collapse `Selection` into the root element (`<body>` or
`Document.documentElement`) if it returns `true`. Therefore, this change
must be safe since anyway `SelectionRefPtr()->SelectAllChildren()` with
the root element is exactly same as `SelectionRefPtr()->Collapse()` with
the empty root element if it's truly empty.
Differential Revision: https://phabricator.services.mozilla.com/D45784
Meaningful job of `HTMLEditor::InsertParagraphSeparatorAsSubAction()` is only
calling `HTMLEditRules::WillInsertParagraph()` via
`HTMLEditRules::WillDoAction()`. Therefore, we can move all jobs in them
into `HTMLEditRules::WillInsertParagraph()` and rename it to
`HTMLEditor::InsertParagraphSeparatorAsSubAction()`.
Differential Revision: https://phabricator.services.mozilla.com/D44190
First, we need to make `nsCopySupport::FireClipboardEvent()` keep handling
`eCopy` and `eCut` event even in password field, only if `TextEditor` allows
them.
Then, we need to make `nsPlainTextSerializer::AppendText()` not expose
masked password for making users safer. Although `TextEditor` does not allow
`eCopy` nor `eCut` when selection is not in unmasked range. Fortunately,
retrieving masked and unmasked password from `nsTextFragment` has already
been implemented in `ContentEventHandler.cpp`. This patch moves it into
`EditorUtils` and makes `ContentEventHandler.cpp` and `nsPlaintextSerializer`
share it.
Differential Revision: https://phabricator.services.mozilla.com/D39000
It does not make sense to copy masked password with mask characters.
Therefore, we should allow users to copy/cut in password fields only when
selected range is in unmasked range.
Note that for web-compat, copy/cut are always enabled in HTML/XHTML document
in content. Therefore this patch changes the behavior only in chrome's
password fields.
Additionally, only the test uses `nsIEditor.canDelete()`. Therefore, this
removes it and make the test use `nsIDocShell.isCommandEnabled()` instead.
Unfortunately, `nsIEditor.canCopy()` and `nsIEditor.canCut()` are used by
BlueGriffon, therefore, we cannot get rid of them for now.
Differential Revision: https://phabricator.services.mozilla.com/D38999
`Document::ExecCommand()` knows subject principal. This patch makes it tell
`EditorCommand::DoCommand()` and `EditorCommand::DoCommandParam()`. Then,
makes they tell each editor public methods which may cause dispatching
`beforeinput` event once we implement it. Finally, each editor public
method sets it to the constructor of `EditorBase::AutoEditActionDataSetter`.
This means that when editor tries to dispatch `beforeinput` event, editor
can check whether it's called by JS or not from everywhere.
Differential Revision: https://phabricator.services.mozilla.com/D29635
`GetInternalCommand()` is currently used only by `EditorCommand` and it
treats the additional parameter only when given command is `cmd_align`.
However, the value is complicated since `AlignCommand` allows both `CString`
value and `String` value. Therefore, `EditorCommand::DoCommandParams()` may
fail to solve `cmd_align` to a `Command` value without checking both of them.
Therefore, it must make sense that `GetInternalCommand()` take `nsCommandParams`
as optional argument and check it only when given command matches `cmd_align`.
Then, we don't need to waste unnecessary run-time cost.
Note that this bug has been hidden since `AlignCommand` class does not refer
the `Command` value but refers only `nsCommandParams`. However, the previous
patch makes `EditorCommand::GetParamType()` not allow `Command::DoNothing`.
Therefore, we need this follow-up fix now.
Differential Revision: https://phabricator.services.mozilla.com/D30501
If `nsIControllerCommand::DoCommandParams()` is called without aParams or
`nsITransferable` pointer, this patch sets nullptr to `aTransferableParam` for
`DoCommandParam()`. This allows each implementation to choose ignore or
return error.
Differential Revision: https://phabricator.services.mozilla.com/D30500
Only `MultiStateCommandBase::DoCommandParams()` allows `CString` param and
`String` param (the former is preferred). This patch makes
`EditorCommand::DoCommandParams()` aware of this case.
Differential Revision: https://phabricator.services.mozilla.com/D30499
If `nsIControllerCommand::DoCommandParams()` is called with `nullptr` for its
`aParams`, this patch sets `VoidString()` to `DoCommandParam()` for making
each implementation be able to consider whether the case is an error or
treat it as specific default value.
Differential Revision: https://phabricator.services.mozilla.com/D30498
If `nsIControllerCommand::DoCommandParams()` is called with `nullptr` for its
`aParams`, this patch sets `VoidCString()` to `DoCommandParam()` for making
each implementation be able to consider whether the case is an error or
treat it as specific default value.
Differential Revision: https://phabricator.services.mozilla.com/D30497
We should use `Maybe` for `bool` because some command may treat the default
value when the parameter is omitted as `true` or `false. Although, current
implementation does not do that.
Differential Revision: https://phabricator.services.mozilla.com/D30496
Most `EditorCommand` classes don't require additional params for executing
a command. All of them just calls their `DoCommand()` or returns same result.
So, we can create new virtual method,
`EditorCommand::DoCommandParam(Command aCommand, TextEditor& aTextEditor)`,
which just delegates to `DoCommand()`.
This patch adds some undeclared commands but which are handled by
`EditorCommand` subclasses, and changes `CommandInt` type from `int8_t` to
`uint8_t` since the count of `Command` items becomes over 128.
Differential Revision: https://phabricator.services.mozilla.com/D30495
`strcmp` may be slow due to checking null character. Therefore, internal
methods of them should use command as far as possible. This patch makes
them take/use `Command` instead of `const char*`.
Differential Revision: https://phabricator.services.mozilla.com/D29174
This patch makes `EditorCommand` implement
`nsIControllerCommand::GetCommandStateParams()` and then, makes it call internal
`GetCommandStateParams()` method which takes `TextEditor` or `nsIEditingSession`
instead.
This makes each implementation really simpler.
Differential Revision: https://phabricator.services.mozilla.com/D28696
This patch makes `EditorCommand` implement
`nsIControllerCommand::DoCommandParams()` and then, makes it call internal
`DoCommandParams()` method which takes `TextEditor` instead.
This makes each implementation really simpler.
Differential Revision: https://phabricator.services.mozilla.com/D28694
This patch makes `EditorCommand` implement `nsIControllerCommand::DoCommand()`
and then, makes it call internal `DoCommand()` method which takes `TextEditor`
instead.
Note that `DoCommand()` of some command classes have not returned error when
given context is not editor. However, it does not make sense to do that only
for some commands. Therefore, this patch makes `EditorCommand::DoCommand()`
return error when given context is not an editor.
This makes each implementation really simpler.
Differential Revision: https://phabricator.services.mozilla.com/D28691
This patch makes `EditorCommand` implement
`nsIControllerCommand::IsCommandEnabled()` and then, makes it call internal
`IsCommandEnabled()` method which returns `bool` directly and takes `TextEditor`
instead.
This makes each implementation really simpler.
Differential Revision: https://phabricator.services.mozilla.com/D28687
This patch makes all editor command classes derived from `EditorCommand` class.
So, this allows `nsHTMLEditor::ExecCommand()` to access them directly in the
future.
Differential Revision: https://phabricator.services.mozilla.com/D28683
`CanCut()`, `CanCopy()` and `CanPaste()` return error only when the editor has
already been destroyed or not been initialized yet, or when failed to access
clipboard when the document is not HTML/XHTML.
`CanDelete()` returns error only when the editor has already been destroyed or
not been initialized yet.
So, these error result won't be exposed to the web in most cases and such
exception shouldn't stop any content script because Chrome basically does not
throw exception in such situation as far as I know.
Therefore, there should be overloads of them to return `bool` result directly
for making their callers simpler.
Differential Revision: https://phabricator.services.mozilla.com/D28608
Different from the comment in `EditorCommands.h`, editing commands and
editor commands are instantiated for each editable document or each
`HTMLInputElement` or `HTMLTextareaElement`. Therefore, even though they
are stateless, we allocate too many instances of them. We should make
them singleton classes to reduce the footprint and save runtime allocation
cost.
Differential Revision: https://phabricator.services.mozilla.com/D27406
`EditorBase::SelectEntierDocument()` uses `Selection::Extend()` but it's too
slow. It should use `Selection::SetStartAndEndInLimiter()` instead.
Additionally, `TextEditor::SelectEntierDocument()` shrink the result of
`EditorBase::SelectEntierDocument()` with `Selection::Extend()` if there is
a `moz-<br>` element. So, `TextEditor::SelectEntinerDocument()` should set
its expected selection with a call for saving the runtime cost.
Then, we don't need to make `EditorBase::SelectEntierDocument()` as non-pure
virtual method. So, this patch makes each its callers call
`Selection->SelectAllChildren()` directly.
Differential Revision: https://phabricator.services.mozilla.com/D23461
`EditorBase::SelectEntierDocument()` uses `Selection::Extend()` but it's too
slow. It should use `Selection::SetStartAndEndInLimiter()` instead.
Additionally, `TextEditor::SelectEntierDocument()` shrink the result of
`EditorBase::SelectEntierDocument()` with `Selection::Extend()` if there is
a `moz-<br>` element. So, `TextEditor::SelectEntinerDocument()` should set
its expected selection with a call for saving the runtime cost.
Then, we don't need to make `EditorBase::SelectEntierDocument()` as non-pure
virtual method. So, this patch makes each its callers call
`Selection->SelectAllChildren()` directly.
Differential Revision: https://phabricator.services.mozilla.com/D23461
As far as I've tested, Chrome does not throw exception even when editor is
destroyed or editor content is modified unexpectedly. So, we should return
`NS_OK` from most public methods of editor when internal methods return
`NS_ERROR_EDITOR_DESTROYED` or `NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE`.
Differential Revision: https://phabricator.services.mozilla.com/D20811
"cmd_copyAndCollapseToEnd" is referred only by CopyPasteAssistent (even
including comm-central and BlueGriffon), but CopyPasteAssistent won't receive
"copy" command to send it.
So, it seems that we can get rid of a lot around CopyPasteAssistent but this
patch just changes the mapping in it ("copy" is mapped to "cmd_copy") and
removes command handlers of "cmd_copyAndCollapseToEnd" completely.
Differential Revision: https://phabricator.services.mozilla.com/D20612