Diff
Modified: trunk/LayoutTests/ChangeLog (235954 => 235955)
--- trunk/LayoutTests/ChangeLog 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/LayoutTests/ChangeLog 2018-09-12 22:26:12 UTC (rev 235955)
@@ -1,3 +1,21 @@
+2018-09-12 Dan Bernstein <m...@apple.com>
+
+ [Cocoa] Complete support for Paste as Quotation
+ https://bugs.webkit.org/show_bug.cgi?id=189504
+
+ Reviewed by Wenson Hsieh.
+
+ Took a few existing tests of the Paste as Quotation behavior and modified them to use the
+ new PasteAsQuotation command. The only difference in the results is that the blockquote has
+ the "type" attribute set to "cite".
+
+ * editing/pasteboard/4930986-1-paste-as-quotation-expected.txt: Added.
+ * editing/pasteboard/4930986-1-paste-as-quotation.html: Added.
+ * editing/pasteboard/4930986-2-paste-as-quotation-expected.txt: Added.
+ * editing/pasteboard/4930986-2-paste-as-quotation.html: Added.
+ * editing/pasteboard/4930986-3-paste-as-quotation-expected.txt: Added.
+ * editing/pasteboard/4930986-3-paste-as-quotation.html: Added.
+
2018-09-12 Sihui Liu <sihui_...@apple.com>
Move IndexedDB to Network Process
Added: trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation-expected.txt (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation-expected.txt 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,2 @@
+This tests to make sure that content that has the document default color is pasted as blue (or whatever the color for quoted content is) during a Paste as Quotation.
+<blockquote type="cite">This text should be blue (it should not be wrapped in a style span).</blockquote>
Added: trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation.html (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation.html (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-1-paste-as-quotation.html 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,34 @@
+<html>
+<head>
+<style>
+blockquote {
+ color: blue;
+ border-left: 2px solid blue;
+ margin-left: 0px;
+ padding-left: 10px;
+}
+</style>
+</head>
+<body>
+<div id="description">This tests to make sure that content that has the document default color is pasted as blue (or whatever the color for quoted content is) during a Paste as Quotation.</div>
+<div id="edit" contenteditable="true"></div>
+
+<script>
+document.addEventListener("beforecopy", (event) => event.preventDefault());
+document.addEventListener("copy", (event) => {
+ event.clipboardData.setData("text/html", "<span class='Apple-style-span' style='color: black;'>This text should be blue (it should not be wrapped in a style span).</span>");
+ event.preventDefault();
+});
+document.execCommand("Copy", false);
+
+edit = document.getElementById("edit");
+description = document.getElementById("description");
+edit.focus();
+document.execCommand("PasteAsQuotation", false);
+if (window.testRunner) {
+ window.testRunner.dumpAsText();
+ document.body.innerText = description.innerText + "\n" + edit.innerHTML;
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation-expected.txt (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation-expected.txt 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,2 @@
+This tests to make sure that content that is colored by the user is pasted with that color during a Paste as Quotation.
+<blockquote type="cite"><span class="Apple-style-span" style="color: red;">This text should be red (it should be wrapped in a style span).</span></blockquote>
Added: trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation.html (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation.html (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-2-paste-as-quotation.html 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,34 @@
+<html>
+<head>
+<style>
+blockquote {
+ color: blue;
+ border-left: 2px solid blue;
+ margin-left: 0px;
+ padding-left: 10px;
+}
+</style>
+<script>
+function runTest() {
+ document.addEventListener("beforecopy", (event) => event.preventDefault());
+ document.addEventListener("copy", (event) => {
+ event.clipboardData.setData("text/html", "<span class='Apple-style-span' style='color: black;'><span class='Apple-style-span' style='color: red;'>This text should be red (it should be wrapped in a style span).</span></span>");
+ event.preventDefault();
+ });
+ document.execCommand("Copy", false);
+
+ div = document.getElementById("edit");
+ div.focus();
+ document.execCommand("PasteAsQuotation", false);
+ if (window.testRunner) {
+ window.testRunner.dumpAsText();
+ document.body.innerText = document.getElementById("description").innerText + "\n" + div.innerHTML;
+ }
+}
+</script>
+</head>
+<body _onload_="runTest();">
+<div id="description">This tests to make sure that content that is colored by the user is pasted with that color during a Paste as Quotation.</div>
+<div id="edit" contenteditable="true"></div>
+</body>
+</html>
Added: trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation-expected.txt (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation-expected.txt 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,2 @@
+This tests to make sure that an Apple-paste-as-quotation blockquote can override document default styles even if they are different than the insertion position.
+<blockquote type="cite">This text should have the blockquote color (blue). There should be no style spans around it.</blockquote>
Added: trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation.html (0 => 235955)
--- trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation.html (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/4930986-3-paste-as-quotation.html 2018-09-12 22:26:12 UTC (rev 235955)
@@ -0,0 +1,34 @@
+<html>
+<head>
+<style>
+blockquote {
+ color: blue;
+ padding-left: 10px;
+ margin-left: 0px;
+ border-left: 2px solid blue;
+}
+</style>
+</head>
+<body>
+<div id="description">This tests to make sure that an Apple-paste-as-quotation blockquote can override document default styles even if they are different than the insertion position.</div>
+<div id="edit" contenteditable="true" style="color: red;"></div>
+
+<script>
+document.addEventListener("beforecopy", (event) => event.preventDefault());
+document.addEventListener("copy", (event) => {
+ event.clipboardData.setData("text/html", "<span class='Apple-style-span' style='color:black;'>This text should have the blockquote color (blue). There should be no style spans around it.</span>");
+ event.preventDefault();
+});
+document.execCommand("Copy", false);
+
+edit = document.getElementById("edit");
+description = document.getElementById("description");
+edit.focus();
+document.execCommand("PasteAsQuotation", false);
+if (window.testRunner) {
+ window.testRunner.dumpAsText();
+ document.body.innerText = description.innerText + "\n" + edit.innerHTML;
+}
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (235954 => 235955)
--- trunk/Source/WebCore/ChangeLog 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/ChangeLog 2018-09-12 22:26:12 UTC (rev 235955)
@@ -1,3 +1,63 @@
+2018-09-12 Dan Bernstein <m...@apple.com>
+
+ [Cocoa] Complete support for Paste as Quotation
+ https://bugs.webkit.org/show_bug.cgi?id=189504
+
+ Reviewed by Wenson Hsieh.
+
+ Tests: editing/pasteboard/4930986-1-paste-as-quotation.html
+ editing/pasteboard/4930986-2-paste-as-quotation.html
+ editing/pasteboard/4930986-3-paste-as-quotation.html
+
+ * editing/Editor.cpp:
+ Added ClipboardEventKind::PasteAsQuotation.
+ (WebCore::eventNameForClipboardEvent): Map PasteAsQuotation to the "paste" DOM event name.
+ (WebCore::createDataTransferForClipboardEvent): Place the unquoted content in the event.
+ This means that currently event handlers can’t emulate pasting as quotation, because they
+ neither have the quoted content nor knowledge that quoting has been requested. We could
+ change this in the future if needed.
+ (WebCore::Editor::paste): Updated for change in pasteWithPasteboard’s argument type.
+ (WebCore::Editor::pasteAsQuotation): Added. Similar to paste, but passes
+ PasteOption::AsQuotation to pasteWithPasteboard.
+ (WebCore::Editor::quoteFragmentForPasting): Added. Quoting for pasting consists of enclosing
+ the fragment in a blockquote element with the "type" attribute set to "cite" and the
+ "class" attribute set to a well-known value, which is used to trigger special behavior in
+ ReplaceSelectionCommand. The behavior includes removing the "class" attribute in the end,
+ so eventually, we could stop using this form of in-band signaling.
+ * editing/Editor.h: Declared PasteOption enum class to encompass the existing allowPlainText
+ and MailBlockquoteHandling arguments to pasteWithPasteboard as well as the new AsQuotation
+ behavior.
+
+ * editing/EditorCommand.cpp:
+ (WebCore::executePasteAsQuotation): Added. Similar to executing Paste.
+ (WebCore::createCommandMap): Added an entry for PasteAsQuotation, based on the Paste entry.
+
+ * editing/cocoa/EditorCocoa.mm:
+ (WebCore::Editor::webContentFromPasteboard): Moved from EditorIOS.mm and EditorMac.mm to
+ here.
+
+ * editing/gtk/EditorGtk.cpp:
+ (WebCore::Editor::pasteWithPasteboard): Updated for new OptionSet argument, added a call to
+ quote the fragment if needed.
+
+ * editing/ios/EditorIOS.mm:
+ (WebCore::Editor::pasteWithPasteboard): Ditto.
+ (WebCore::Editor::webContentFromPasteboard): Moved to EditorCocoa.mm.
+
+ * editing/mac/EditorMac.mm:
+ (WebCore::Editor::pasteWithPasteboard): Updated for new OptionSet argument, added a call to
+ quote the fragment if needed.
+ (WebCore::Editor::readSelectionFromPasteboard): Updated for new OptionSet argument to
+ pasteWithPasteboard.
+ (WebCore::Editor::webContentFromPasteboard): Moved to EditorCocoa.mm.
+
+ * editing/win/EditorWin.cpp:
+ (WebCore::Editor::pasteWithPasteboard): Updated for new OptionSet argument, added a call to
+ quote the fragment if needed.
+
+ * editing/wpe/EditorWPE.cpp:
+ (WebCore::Editor::pasteWithPasteboard): Ditto.
+
2018-09-11 Simon Fraser <simon.fra...@apple.com>
Make GraphicsLayers ref-counted, so their tree can persist when disconnected from RenderLayerBackings
Modified: trunk/Source/WebCore/editing/Editor.cpp (235954 => 235955)
--- trunk/Source/WebCore/editing/Editor.cpp 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/Editor.cpp 2018-09-12 22:26:12 UTC (rev 235955)
@@ -54,6 +54,7 @@
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLAttachmentElement.h"
+#include "HTMLBRElement.h"
#include "HTMLCollection.h"
#include "HTMLFormControlElement.h"
#include "HTMLFrameOwnerElement.h"
@@ -60,6 +61,7 @@
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "HTMLQuoteElement.h"
#include "HTMLSpanElement.h"
#include "HitTestResult.h"
#include "IndentOutdentCommand.h"
@@ -327,6 +329,7 @@
Cut,
Paste,
PasteAsPlainText,
+ PasteAsQuotation,
BeforeCopy,
BeforeCut,
BeforePaste,
@@ -341,6 +344,7 @@
return eventNames().cutEvent;
case ClipboardEventKind::Paste:
case ClipboardEventKind::PasteAsPlainText:
+ case ClipboardEventKind::PasteAsQuotation:
return eventNames().pasteEvent;
case ClipboardEventKind::BeforeCopy:
return eventNames().beforecopyEvent;
@@ -369,6 +373,7 @@
}
FALLTHROUGH;
case ClipboardEventKind::Paste:
+ case ClipboardEventKind::PasteAsQuotation:
return DataTransfer::createForCopyAndPaste(document, DataTransfer::StoreMode::Readonly, Pasteboard::createForCopyAndPaste());
case ClipboardEventKind::BeforeCopy:
case ClipboardEventKind::BeforeCut:
@@ -1404,7 +1409,7 @@
updateMarkersForWordsAffectedByEditing(false);
ResourceCacheValidationSuppressor validationSuppressor(document().cachedResourceLoader());
if (m_frame.selection().selection().isContentRichlyEditable())
- pasteWithPasteboard(&pasteboard, true);
+ pasteWithPasteboard(&pasteboard, { PasteOption::AllowPlainText });
else
pasteAsPlainTextWithPasteboard(pasteboard);
}
@@ -1419,6 +1424,40 @@
pasteAsPlainTextWithPasteboard(*Pasteboard::createForCopyAndPaste());
}
+void Editor::pasteAsQuotation()
+{
+ if (!dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::PasteAsQuotation))
+ return;
+ if (!canPaste())
+ return;
+ updateMarkersForWordsAffectedByEditing(false);
+ ResourceCacheValidationSuppressor validationSuppressor(document().cachedResourceLoader());
+ auto pasteboard = Pasteboard::createForCopyAndPaste();
+ if (m_frame.selection().selection().isContentRichlyEditable())
+ pasteWithPasteboard(pasteboard.get(), { PasteOption::AllowPlainText, PasteOption::AsQuotation });
+ else
+ pasteAsPlainTextWithPasteboard(*pasteboard);
+}
+
+void Editor::quoteFragmentForPasting(DocumentFragment& fragment)
+{
+ auto blockQuote = HTMLQuoteElement::create(blockquoteTag, document());
+ blockQuote->setAttributeWithoutSynchronization(typeAttr, AtomicString("cite"));
+ blockQuote->setAttributeWithoutSynchronization(classAttr, AtomicString(ApplePasteAsQuotation));
+
+ auto childNode = fragment.firstChild();
+
+ if (childNode) {
+ while (childNode) {
+ blockQuote->appendChild(*childNode);
+ childNode = fragment.firstChild();
+ }
+ } else
+ blockQuote->appendChild(HTMLBRElement::create(document()));
+
+ fragment.appendChild(blockQuote);
+}
+
void Editor::performDelete()
{
if (!canDelete()) {
Modified: trunk/Source/WebCore/editing/Editor.h (235954 => 235955)
--- trunk/Source/WebCore/editing/Editor.h 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/Editor.h 2018-09-12 22:26:12 UTC (rev 235955)
@@ -129,6 +129,12 @@
explicit Editor(Frame&);
~Editor();
+ enum class PasteOption : uint8_t {
+ AllowPlainText = 1 << 0,
+ IgnoreMailBlockquote = 1 << 1,
+ AsQuotation = 1 << 2,
+ };
+
WEBCORE_EXPORT EditorClient* client() const;
WEBCORE_EXPORT TextCheckerClient* textChecker() const;
@@ -158,6 +164,7 @@
WEBCORE_EXPORT void paste();
void paste(Pasteboard&);
WEBCORE_EXPORT void pasteAsPlainText();
+ void pasteAsQuotation();
WEBCORE_EXPORT void performDelete();
WEBCORE_EXPORT void copyURL(const URL&, const String& title);
@@ -519,9 +526,11 @@
bool canDeleteRange(Range*) const;
bool canSmartReplaceWithPasteboard(Pasteboard&);
void pasteAsPlainTextWithPasteboard(Pasteboard&);
- void pasteWithPasteboard(Pasteboard*, bool allowPlainText, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
+ void pasteWithPasteboard(Pasteboard*, OptionSet<PasteOption>);
String plainTextFromPasteboard(const PasteboardPlainText&);
+ void quoteFragmentForPasting(DocumentFragment&);
+
void revealSelectionAfterEditingOperation(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
OptionSet<TextCheckingType> resolveTextCheckingTypeMask(const Node& rootEditableElement, OptionSet<TextCheckingType>);
Modified: trunk/Source/WebCore/editing/EditorCommand.cpp (235954 => 235955)
--- trunk/Source/WebCore/editing/EditorCommand.cpp 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/EditorCommand.cpp 2018-09-12 22:26:12 UTC (rev 235955)
@@ -926,6 +926,16 @@
return true;
}
+static bool executePasteAsQuotation(Frame& frame, Event*, EditorCommandSource source, const String&)
+{
+ if (source == CommandFromMenuOrKeyBinding) {
+ UserTypingGestureIndicator typingGestureIndicator(frame);
+ frame.editor().pasteAsQuotation();
+ } else
+ frame.editor().pasteAsQuotation();
+ return true;
+}
+
static bool executePrint(Frame& frame, Event*, EditorCommandSource, const String&)
{
Page* page = frame.page();
@@ -1636,6 +1646,7 @@
{ "Paste", { executePaste, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabledPaste } },
{ "PasteAndMatchStyle", { executePasteAndMatchStyle, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabledPaste } },
{ "PasteAsPlainText", { executePasteAsPlainText, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabledPaste } },
+ { "PasteAsQuotation", { executePasteAsQuotation, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabledPaste } },
{ "Print", { executePrint, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Redo", { executeRedo, supported, enabledRedo, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "RemoveFormat", { executeRemoveFormat, supported, enabledRangeInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
Modified: trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm (235954 => 235955)
--- trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -291,4 +291,14 @@
return nullptr;
}
+// FIXME: Should give this function a name that makes it clear it adds resources to the document loader as a side effect.
+// Or refactor so it does not do that.
+RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)
+{
+ WebContentReader reader(m_frame, context, allowPlainText);
+ pasteboard.read(reader);
+ chosePlainText = reader.madeFragmentFromPlainText;
+ return WTFMove(reader.fragment);
}
+
+}
Modified: trunk/Source/WebCore/editing/gtk/EditorGtk.cpp (235954 => 235955)
--- trunk/Source/WebCore/editing/gtk/EditorGtk.cpp 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/gtk/EditorGtk.cpp 2018-09-12 22:26:12 UTC (rev 235955)
@@ -86,7 +86,7 @@
return nullptr;
}
-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
RefPtr<Range> range = selectedRange();
if (!range)
@@ -93,9 +93,13 @@
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, m_frame, *range, allowPlainText, chosePlainText);
+ RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, m_frame, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+
+ if (fragment && options.contains(PasteOption::AsQuotation))
+ quoteFragmentForPasting(*fragment);
+
if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
- pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling);
+ pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
static const AtomicString& elementURL(Element& element)
Modified: trunk/Source/WebCore/editing/ios/EditorIOS.mm (235954 => 235955)
--- trunk/Source/WebCore/editing/ios/EditorIOS.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/ios/EditorIOS.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -215,19 +215,10 @@
pasteboard.write(pasteboardImage);
}
-// FIXME: Should give this function a name that makes it clear it adds resources to the document loader as a side effect.
-// Or refactor so it does not do that.
-RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- WebContentReader reader(m_frame, context, allowPlainText);
- pasteboard.read(reader);
- chosePlainText = reader.madeFragmentFromPlainText;
- return WTFMove(reader.fragment);
-}
-
-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
-{
RefPtr<Range> range = selectedRange();
+ bool allowPlainText = options.contains(PasteOption::AllowPlainText);
WebContentReader reader(m_frame, *range, allowPlainText);
int numberOfPasteboardItems = client()->getPasteboardItemsCount();
for (int i = 0; i < numberOfPasteboardItems; ++i) {
@@ -243,8 +234,11 @@
fragment = webContentFromPasteboard(*pasteboard, *range, allowPlainText, chosePlainTextIgnored);
}
+ if (fragment && options.contains(PasteOption::AsQuotation))
+ quoteFragmentForPasting(*fragment);
+
if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
- pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling);
+ pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
void Editor::insertDictationPhrases(Vector<Vector<String>>&& dictationPhrases, RetainPtr<id> metadata)
Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (235954 => 235955)
--- trunk/Source/WebCore/editing/mac/EditorMac.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -77,7 +77,7 @@
[[NSApplication sharedApplication] orderFrontColorPanel:nil];
}
-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
RefPtr<Range> range = selectedRange();
@@ -87,10 +87,13 @@
ALLOW_DEPRECATED_DECLARATIONS_END
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = webContentFromPasteboard(*pasteboard, *range, allowPlainText, chosePlainText);
+ RefPtr<DocumentFragment> fragment = webContentFromPasteboard(*pasteboard, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+ if (fragment && options.contains(PasteOption::AsQuotation))
+ quoteFragmentForPasting(*fragment);
+
if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
- pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling);
+ pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote );
client()->setInsertionPasteboard(String());
}
@@ -120,7 +123,7 @@
{
Pasteboard pasteboard(pasteboardName);
if (m_frame.selection().selection().isContentRichlyEditable())
- pasteWithPasteboard(&pasteboard, true);
+ pasteWithPasteboard(&pasteboard, { PasteOption::AllowPlainText });
else
pasteAsPlainTextWithPasteboard(pasteboard);
}
@@ -276,16 +279,6 @@
pasteboard.write(pasteboardImage);
}
-// FIXME: Should give this function a name that makes it clear it adds resources to the document loader as a side effect.
-// Or refactor so it does not do that.
-RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)
-{
- WebContentReader reader(m_frame, context, allowPlainText);
- pasteboard.read(reader);
- chosePlainText = reader.madeFragmentFromPlainText;
- return WTFMove(reader.fragment);
-}
-
} // namespace WebCore
#endif // PLATFORM(MAC)
Modified: trunk/Source/WebCore/editing/win/EditorWin.cpp (235954 => 235955)
--- trunk/Source/WebCore/editing/win/EditorWin.cpp 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/win/EditorWin.cpp 2018-09-12 22:26:12 UTC (rev 235955)
@@ -35,7 +35,7 @@
namespace WebCore {
-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
RefPtr<Range> range = selectedRange();
if (!range)
@@ -42,9 +42,13 @@
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, *range, allowPlainText, chosePlainText);
+ RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(m_frame, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+
+ if (fragment && options.contains(PasteOption::AsQuotation))
+ quoteFragmentForPasting(*fragment);
+
if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
- pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling);
+ pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
template <typename PlatformDragData>
Modified: trunk/Source/WebCore/editing/wpe/EditorWPE.cpp (235954 => 235955)
--- trunk/Source/WebCore/editing/wpe/EditorWPE.cpp 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebCore/editing/wpe/EditorWPE.cpp 2018-09-12 22:26:12 UTC (rev 235955)
@@ -73,7 +73,7 @@
notImplemented();
}
-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
RefPtr<Range> range = selectedRange();
if (!range)
@@ -80,9 +80,13 @@
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, m_frame, *range, allowPlainText, chosePlainText);
+ RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, m_frame, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+
+ if (fragment && options.contains(PasteOption::AsQuotation))
+ quoteFragmentForPasting(*fragment);
+
if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
- pasteAsFragment(*fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling);
+ pasteAsFragment(*fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (235954 => 235955)
--- trunk/Source/WebKit/ChangeLog 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/ChangeLog 2018-09-12 22:26:12 UTC (rev 235955)
@@ -1,3 +1,29 @@
+2018-09-12 Dan Bernstein <m...@apple.com>
+
+ [Cocoa] Complete support for Paste as Quotation
+ https://bugs.webkit.org/show_bug.cgi?id=189504
+
+ Reviewed by Wenson Hsieh.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView canPerformAction:withSender:]): Handle _pasteAsQuotation:. It’s not included
+ in FOR_EACH_WKCONTENTVIEW_ACTION, because it’s declared and implemented in the WKPrivate
+ category. If we add more actions in the category, it could make sense to fold them into
+ a new FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION.
+ (-[WKWebView targetForAction:withSender:]): Handle _pasteAsQuotation:.
+ (-[WKWebView _pasteAsQuotation:]): Send to the WebViewImpl or the WKContentView.
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h: Declared a new _pasteAsQuotation: action.
+
+ * UIProcess/Cocoa/WebViewImpl.mm:
+ (WebKit::selectorExceptionMap): Added a custom mapping from the new selector to the
+ PasteAsQuotation command.
+
+ * UIProcess/ios/WKContentViewInteraction.h: Declare methods for the new action.
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ Forward _pasteAsQuotation: to the WKWebView so that clients get a chance to override its
+ behavior.
+ (-[WKContentView _pasteAsQuotationForWebView:]): Send the command to the page.
+
2018-09-12 Sihui Liu <sihui_...@apple.com>
Move IndexedDB to Network Process
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (235954 => 235955)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -1387,6 +1387,8 @@
FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_CANPERFORMACTION_TO_WKCONTENTVIEW)
+ FORWARD_CANPERFORMACTION_TO_WKCONTENTVIEW(_pasteAsQuotation)
+
#undef FORWARD_CANPERFORMACTION_TO_WKCONTENTVIEW
return [super canPerformAction:action withSender:sender];
@@ -1400,6 +1402,8 @@
FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_TARGETFORACTION_TO_WKCONTENTVIEW)
+ FORWARD_TARGETFORACTION_TO_WKCONTENTVIEW(_pasteAsQuotation)
+
#undef FORWARD_TARGETFORACTION_TO_WKCONTENTVIEW
return [super targetForAction:action withSender:sender];
@@ -4547,6 +4551,16 @@
#endif
}
+- (void)_pasteAsQuotation:(id)sender
+{
+#if PLATFORM(MAC)
+ _impl->executeEditCommandForSelector(_cmd);
+#else
+ if (self.usesStandardContentView)
+ [_contentView _pasteAsQuotationForWebView:sender];
+#endif
+}
+
- (void)_evaluateJavaScriptWithoutUserGesture:(NSString *)_javascript_String completionHandler:(void (^)(id, NSError *))completionHandler
{
[self _evaluateJavaScript:_javascript_String forceUserGesture:NO completionHandler:completionHandler];
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (235954 => 235955)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2018-09-12 22:26:12 UTC (rev 235955)
@@ -185,6 +185,8 @@
- (_WKAttachment *)_insertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType options:(_WKAttachmentDisplayOptions *)options completion:(void(^)(BOOL success))completionHandler WK_API_DEPRECATED_WITH_REPLACEMENT("-_insertAttachmentWithFileWrapper:contentType:completion:", macosx(WK_MAC_TBA, WK_MAC_TBA), ios(WK_IOS_TBA, WK_IOS_TBA));
- (_WKAttachment *)_insertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType completion:(void(^)(BOOL success))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (IBAction)_pasteAsQuotation:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
#if TARGET_OS_IPHONE
// DERECATED: The setters of the three following function are deprecated, please use overrideLayoutParameters.
// Define the smallest size a page take with a regular viewport.
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (235954 => 235955)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -2624,7 +2624,10 @@
{ @selector(pageUp:), "MovePageUp"_s },
{ @selector(pageUpAndModifySelection:), "MovePageUpAndModifySelection"_s },
{ @selector(scrollPageDown:), "ScrollPageForward"_s },
- { @selector(scrollPageUp:), "ScrollPageBackward"_s }
+ { @selector(scrollPageUp:), "ScrollPageBackward"_s },
+#if WK_API_ENABLED
+ { @selector(_pasteAsQuotation:), "PasteAsQuotation"_s },
+#endif
};
for (auto& name : names)
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (235954 => 235955)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-09-12 22:26:12 UTC (rev 235955)
@@ -316,6 +316,7 @@
#define DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW(_action) \
- (void)_action ## ForWebView:(id)sender;
FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
+DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW(_pasteAsQuotation)
#undef DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW
#if ENABLE(TOUCH_EVENTS)
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (235954 => 235955)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-09-12 22:26:12 UTC (rev 235955)
@@ -2161,6 +2161,8 @@
FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKWEBVIEW)
+FORWARD_ACTION_TO_WKWEBVIEW(_pasteAsQuotation)
+
#undef FORWARD_ACTION_TO_WKWEBVIEW
- (void)_lookupForWebView:(id)sender
@@ -2462,6 +2464,11 @@
_page->executeEditCommand("paste"_s);
}
+- (void)_pasteAsQuotationForWebView:(id)sender
+{
+ _page->executeEditCommand("PasteAsQuotation"_s);
+}
+
- (void)selectForWebView:(id)sender
{
[_textSelectionAssistant selectWord];
Modified: trunk/Tools/ChangeLog (235954 => 235955)
--- trunk/Tools/ChangeLog 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Tools/ChangeLog 2018-09-12 22:26:12 UTC (rev 235955)
@@ -1,3 +1,12 @@
+2018-09-12 Dan Bernstein <m...@apple.com>
+
+ [Cocoa] Complete support for Paste as Quotation
+ https://bugs.webkit.org/show_bug.cgi?id=189504
+
+ Reviewed by Wenson Hsieh.
+
+ * MiniBrowser/mac/MainMenu.xib: Added a Paste as Quotation command in the Edit menu.
+
2018-09-12 Sihui Liu <sihui_...@apple.com>
Move IndexedDB to Network Process
Modified: trunk/Tools/MiniBrowser/mac/MainMenu.xib (235954 => 235955)
--- trunk/Tools/MiniBrowser/mac/MainMenu.xib 2018-09-12 22:16:45 UTC (rev 235954)
+++ trunk/Tools/MiniBrowser/mac/MainMenu.xib 2018-09-12 22:26:12 UTC (rev 235955)
@@ -197,6 +197,11 @@
<action selector="paste:" target="-1" id="226"/>
</connections>
</menuItem>
+ <menuItem title="Paste as Quotation" keyEquivalent="V" id="8Ng-DB-z0Y">
+ <connections>
+ <action selector="_pasteAsQuotation:" target="-1" id="6Mn-XC-2qO"/>
+ </connections>
+ </menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>