Bug 1540037 - part 41: Split `TextEditor::PasteAsAction()` r=m_kato

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
This commit is contained in:
Masayuki Nakano 2021-06-04 05:01:39 +00:00
Родитель 0ffb058047
Коммит 875fdeac2f
7 изменённых файлов: 70 добавлений и 37 удалений

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

@ -1730,10 +1730,7 @@ bool EditorBase::IsCopyCommandEnabled() const {
}
NS_IMETHODIMP EditorBase::Paste(int32_t aClipboardType) {
nsresult rv =
MOZ_KnownLive(AsTextEditor())->PasteAsAction(aClipboardType, true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "TextEditor::PasteAsAction() failed");
return rv;
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult EditorBase::PrepareToInsertContent(

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

@ -813,6 +813,23 @@ class EditorBase : public nsIEditor,
*/
virtual bool CanPasteTransferable(nsITransferable* aTransferable) = 0;
/**
* PasteAsAction() pastes clipboard content to Selection. This method
* may dispatch ePaste event first. If its defaultPrevent() is called,
* this does nothing but returns NS_OK.
*
* @param aClipboardType nsIClipboard::kGlobalClipboard or
* nsIClipboard::kSelectionClipboard.
* @param aDispatchPasteEvent true if this should dispatch ePaste event
* before pasting. Otherwise, false.
* @param aPrincipal Set subject principal if it may be called by
* JS. If set to nullptr, will be treated as
* called by system.
*/
MOZ_CAN_RUN_SCRIPT virtual nsresult PasteAsAction(
int32_t aClipboardType, bool aDispatchPasteEvent,
nsIPrincipal* aPrincipal = nullptr) = 0;
/**
* Paste aTransferable at Selection.
*

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

@ -466,7 +466,7 @@ nsresult PasteCommand::DoCommand(Command aCommand, TextEditor& aTextEditor,
nsIPrincipal* aPrincipal) const {
nsresult rv = aTextEditor.PasteAsAction(nsIClipboard::kGlobalClipboard, true,
aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "TextEditor::PasteAsAction() failed");
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::PasteAsAction() failed");
return rv;
}

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

@ -203,6 +203,17 @@ class HTMLEditor final : public TextEditor,
MOZ_CAN_RUN_SCRIPT nsresult GetBackgroundColorState(bool* aMixed,
nsAString& aOutColor);
MOZ_CAN_RUN_SCRIPT NS_IMETHOD Paste(int32_t aClipboardType) final {
const nsresult rv = HTMLEditor::PasteAsAction(aClipboardType, true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TextEditor::PasteAsAction() failed");
return rv;
}
MOZ_CAN_RUN_SCRIPT nsresult
PasteAsAction(int32_t aClipboardType, bool aDispatchPasteEvent,
nsIPrincipal* aPrincipal = nullptr) final;
/**
* PasteNoFormatting() pastes content in clipboard without any style
* information.

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

@ -1983,6 +1983,37 @@ bool HTMLEditor::HavePrivateHTMLFlavor(nsIClipboard* aClipboard) {
return NS_SUCCEEDED(rv) && bHavePrivateHTMLFlavor;
}
nsresult HTMLEditor::PasteAsAction(int32_t aClipboardType,
bool aDispatchPasteEvent,
nsIPrincipal* aPrincipal) {
AutoEditActionDataSetter editActionData(*this, EditAction::ePaste,
aPrincipal);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return NS_ERROR_NOT_INITIALIZED;
}
if (aDispatchPasteEvent) {
if (!FireClipboardEvent(ePaste, aClipboardType)) {
return EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_ACTION_CANCELED);
}
} else {
// The caller must already have dispatched a "paste" event.
editActionData.NotifyOfDispatchingClipboardEvent();
}
editActionData.InitializeDataTransferWithClipboard(
SettingDataTransfer::eWithFormat, aClipboardType);
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
if (NS_FAILED(rv)) {
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
"CanHandleAndMaybeDispatchBeforeInputEvent() failed");
return EditorBase::ToGenericNSResult(rv);
}
rv = PasteInternal(aClipboardType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::PasteInternal() failed");
return EditorBase::ToGenericNSResult(rv);
}
nsresult HTMLEditor::PasteInternal(int32_t aClipboardType) {
MOZ_ASSERT(IsEditActionDataAvailable());

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

@ -57,6 +57,12 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
// Overrides of nsIEditor
NS_IMETHOD GetTextLength(int32_t* aCount) override;
MOZ_CAN_RUN_SCRIPT NS_IMETHOD Paste(int32_t aClipboardType) override {
const nsresult rv = TextEditor::PasteAsAction(aClipboardType, true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::PasteAsAction() failed");
return rv;
}
// Shouldn't be used internally, but we need these using declarations for
// avoiding warnings of clang.
@ -85,22 +91,9 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed {
virtual dom::EventTarget* GetDOMEventTarget() const override;
/**
* PasteAsAction() pastes clipboard content to Selection. This method
* may dispatch ePaste event first. If its defaultPrevent() is called,
* this does nothing but returns NS_OK.
*
* @param aClipboardType nsIClipboard::kGlobalClipboard or
* nsIClipboard::kSelectionClipboard.
* @param aDispatchPasteEvent true if this should dispatch ePaste event
* before pasting. Otherwise, false.
* @param aPrincipal Set subject principal if it may be called by
* JS. If set to nullptr, will be treated as
* called by system.
*/
MOZ_CAN_RUN_SCRIPT nsresult PasteAsAction(int32_t aClipboardType,
bool aDispatchPasteEvent,
nsIPrincipal* aPrincipal = nullptr);
MOZ_CAN_RUN_SCRIPT nsresult
PasteAsAction(int32_t aClipboardType, bool aDispatchPasteEvent,
nsIPrincipal* aPrincipal = nullptr) override;
MOZ_CAN_RUN_SCRIPT nsresult
PasteAsQuotationAsAction(int32_t aClipboardType, bool aDispatchPasteEvent,

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

@ -493,22 +493,6 @@ nsresult TextEditor::PasteAsAction(int32_t aClipboardType,
editActionData.NotifyOfDispatchingClipboardEvent();
}
if (IsHTMLEditor()) {
editActionData.InitializeDataTransferWithClipboard(
SettingDataTransfer::eWithFormat, aClipboardType);
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
if (NS_FAILED(rv)) {
NS_WARNING_ASSERTION(
rv == NS_ERROR_EDITOR_ACTION_CANCELED,
"CanHandleAndMaybeDispatchBeforeInputEvent() failed");
return EditorBase::ToGenericNSResult(rv);
}
rv = MOZ_KnownLive(AsHTMLEditor())->PasteInternal(aClipboardType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::PasteInternal() failed");
return EditorBase::ToGenericNSResult(rv);
}
if (!GetDocument()) {
NS_WARNING("The editor didn't have document, but ignored");
return NS_OK;