Diff
Modified: trunk/LayoutTests/ChangeLog (238474 => 238475)
--- trunk/LayoutTests/ChangeLog 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/LayoutTests/ChangeLog 2018-11-25 12:11:16 UTC (rev 238475)
@@ -1,3 +1,25 @@
+2018-11-25 Tim Horton <timothy_hor...@apple.com>
+
+ Make it possible to insert editable images with a gesture
+ https://bugs.webkit.org/show_bug.cgi?id=191937
+
+ Reviewed by Wenson Hsieh.
+
+ * editing/images/basic-editable-image-from-execCommand-expected.txt: Added.
+ * editing/images/basic-editable-image-from-execCommand.html: Added.
+ Add a test that ensures that editable images also work when
+ inserted via the editor command.
+
+ * editing/images/redo-insert-editable-image-maintains-strokes-expected.txt: Added.
+ * editing/images/redo-insert-editable-image-maintains-strokes.html: Added.
+ Add a test that ensures that strokes are maintained when re-doing an
+ un-done editable image insertion.
+
+ * editing/images/undo-insert-editable-image-expected.txt: Added.
+ * editing/images/undo-insert-editable-image.html: Added.
+ Add a test that ensures that the selection stays in a sensible place
+ when undoing and redoing editable image insertion.
+
2018-11-23 Ryosuke Niwa <rn...@webkit.org>
REGRESSION (r236785): Nullptr crash in StyledMarkupAccumulator::traverseNodesForSerialization
Added: trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand-expected.txt (0 => 238475)
--- trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand-expected.txt 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,3 @@
+
+Had 0 strokes in editable image before drawing.
+Had 1 stroke in editable image after drawing.
Added: trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand.html (0 => 238475)
--- trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand.html (rev 0)
+++ trunk/LayoutTests/editing/images/basic-editable-image-from-execCommand.html 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,23 @@
+<!DOCTYPE html><!-- webkit-test-runner [ enableEditableImages=true ] -->
+<head>
+<script src=""
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+addEventListener("load", async () => {
+ window.getSelection().setPosition(document.body, 0);
+ document.execCommand("InsertEditableImage");
+ const initialNumberOfStrokesInEditableImage = (await UIHelper.numberOfStrokesInEditableImage());
+ await UIHelper.drawSquareInEditableImage();
+ const numberOfStrokesInEditableImageAfterDrawing = (await UIHelper.numberOfStrokesInEditableImage());
+ document.getElementById("log").innerHTML = `Had ${initialNumberOfStrokesInEditableImage} strokes in editable image before drawing.<br/>Had ${numberOfStrokesInEditableImageAfterDrawing} stroke in editable image after drawing.`;
+ testRunner.notifyDone();
+});
+</script>
+</head>
+<body contenteditable>
+<div id="log"></div>
+</body>
Added: trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes-expected.txt (0 => 238475)
--- trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes-expected.txt 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,6 @@
+
+Had 0 strokes in editable image before drawing.
+Had 1 stroke in editable image after drawing.
+Had 0 strokes in editable image after undo.
+Had 1 stroke in editable image after redo.
+Had 2 strokes in editable image after drawing again.
Added: trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes.html (0 => 238475)
--- trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes.html (rev 0)
+++ trunk/LayoutTests/editing/images/redo-insert-editable-image-maintains-strokes.html 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,29 @@
+<!DOCTYPE html><!-- webkit-test-runner [ enableEditableImages=true ] -->
+<head>
+<script src=""
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+addEventListener("load", async () => {
+ window.getSelection().setPosition(document.body, 0);
+ document.execCommand("InsertEditableImage");
+ const initialNumberOfStrokesInEditableImage = (await UIHelper.numberOfStrokesInEditableImage());
+ await UIHelper.drawSquareInEditableImage();
+ const numberOfStrokesInEditableImageAfterDrawing = (await UIHelper.numberOfStrokesInEditableImage());
+ document.execCommand('undo', false, null);
+ const numberOfStrokesInEditableImageAfterUndo = (await UIHelper.numberOfStrokesInEditableImage());
+ document.execCommand('redo', false, null);
+ const numberOfStrokesInEditableImageAfterRedo = (await UIHelper.numberOfStrokesInEditableImage());
+ await UIHelper.drawSquareInEditableImage();
+ const numberOfStrokesInEditableImageAfterSecondDrawing = (await UIHelper.numberOfStrokesInEditableImage());
+ document.getElementById("log").innerHTML = `Had ${initialNumberOfStrokesInEditableImage} strokes in editable image before drawing.<br/>Had ${numberOfStrokesInEditableImageAfterDrawing} stroke in editable image after drawing.<br/>Had ${numberOfStrokesInEditableImageAfterUndo} strokes in editable image after undo.<br/>Had ${numberOfStrokesInEditableImageAfterRedo} stroke in editable image after redo.<br/>Had ${numberOfStrokesInEditableImageAfterSecondDrawing} strokes in editable image after drawing again.`;
+ testRunner.notifyDone();
+});
+</script>
+</head>
+<body contenteditable>
+<div id="log"></div>
+</body>
Added: trunk/LayoutTests/editing/images/undo-insert-editable-image-expected.txt (0 => 238475)
--- trunk/LayoutTests/editing/images/undo-insert-editable-image-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/images/undo-insert-editable-image-expected.txt 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,28 @@
+This test inserts a editable image, performs an undo, then a redo, ensuring that the selection remains after the image when re-done.
+
+before undo:
+| "Hello, world!"
+| <img>
+| height="300px"
+| style="display: block"
+| width="100%"
+| x-apple-editable-image=""
+| <shadow:root>
+| <attachment>
+| style="display: none !important;"
+| <#selection-caret>
+
+after undo:
+| "Hello, world!<#selection-caret>"
+
+after redo:
+| "Hello, world!"
+| <img>
+| height="300px"
+| style="display: block"
+| width="100%"
+| x-apple-editable-image=""
+| <shadow:root>
+| <attachment>
+| style="display: none !important;"
+| <#selection-caret>
Added: trunk/LayoutTests/editing/images/undo-insert-editable-image.html (0 => 238475)
--- trunk/LayoutTests/editing/images/undo-insert-editable-image.html (rev 0)
+++ trunk/LayoutTests/editing/images/undo-insert-editable-image.html 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,20 @@
+<!DOCTYPE html><!-- webkit-test-runner [ enableEditableImages=true ] -->
+<head>
+<script src="" type="text/_javascript_"></script>
+</head>
+<body contenteditable>
+<div id="test">Hello, world!</div>
+<script>
+const div = document.getElementById("test");
+
+window.getSelection().setPosition(div, 13);
+document.execCommand("InsertEditableImage");
+
+Markup.description("This test inserts a editable image, performs an undo, then a redo, ensuring that the selection remains after the image when re-done.")
+Markup.dump(div, "before undo");
+document.execCommand('undo', false, null);
+Markup.dump(div, "after undo");
+document.execCommand('redo', false, null);
+Markup.dump(div, "after redo");
+</script>
+</body>
Modified: trunk/Source/WebCore/ChangeLog (238474 => 238475)
--- trunk/Source/WebCore/ChangeLog 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/ChangeLog 2018-11-25 12:11:16 UTC (rev 238475)
@@ -1,3 +1,33 @@
+2018-11-25 Tim Horton <timothy_hor...@apple.com>
+
+ Make it possible to insert editable images with a gesture
+ https://bugs.webkit.org/show_bug.cgi?id=191937
+
+ Reviewed by Wenson Hsieh.
+
+ Tests:
+ editing/images/redo-insert-editable-image-maintains-strokes.html,
+ editing/images/undo-insert-editable-image.html,
+ editing/images/basic-editable-image-from-execCommand.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * Source/WebCore/editing/EditorCommand.cpp:
+ * Source/WebCore/en.lproj/Localizable.strings:
+ * editing/EditAction.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertEditableImage):
+ * editing/Editor.h:
+ * editing/InsertEditableImageCommand.cpp: Added.
+ (WebCore::InsertEditableImageCommand::InsertEditableImageCommand):
+ (WebCore::InsertEditableImageCommand::doApply):
+ * editing/InsertEditableImageCommand.h: Added.
+ (WebCore::InsertEditableImageCommand::create):
+ * editing/VisibleSelection.cpp:
+ Add an editor command that inserts an editable image.
+ It will likely get a bit more complicated, but for now it just inserts
+ a 100% by 300px editable image.
+
2018-11-24 Wenson Hsieh <wenson_hs...@apple.com>
[Cocoa] Fix a few localizable string descriptions in WebEditCommandProxy.cpp and WebEditorClient.mm
Modified: trunk/Source/WebCore/Sources.txt (238474 => 238475)
--- trunk/Source/WebCore/Sources.txt 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/Sources.txt 2018-11-25 12:11:16 UTC (rev 238475)
@@ -914,6 +914,7 @@
editing/HTMLInterchange.cpp
editing/InsertNestedListCommand.cpp
editing/IndentOutdentCommand.cpp
+editing/InsertEditableImageCommand.cpp
editing/InsertIntoTextNodeCommand.cpp
editing/InsertLineBreakCommand.cpp
editing/InsertListCommand.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (238474 => 238475)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-11-25 12:11:16 UTC (rev 238475)
@@ -754,6 +754,7 @@
2D70BA1318074DDF0001908A /* PlatformCALayerCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D70BA1218074DDF0001908A /* PlatformCALayerCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D76BB821945632400CFD29A /* RunLoopObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D76BB801945632400CFD29A /* RunLoopObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D7ED0AB1BAE99170043B3E5 /* TimerEventBasedMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */; };
+ 2D81E1CF21A78CC200A32CF4 /* InsertEditableImageCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D81E1CD21A78CC200A32CF4 /* InsertEditableImageCommand.h */; };
2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8287F516E4A0380086BD00 /* HitTestLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D8B92CE203D13E1009C868F /* UnifiedSource481.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5F84AD1FA1A48B006DB63B /* UnifiedSource481.cpp */; };
2D8B92CF203D13E1009C868F /* UnifiedSource482.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5F84C81FA1A4A4006DB63B /* UnifiedSource482.cpp */; };
@@ -6649,6 +6650,8 @@
2D76BB801945632400CFD29A /* RunLoopObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunLoopObserver.h; sourceTree = "<group>"; };
2D76BB8319456F8100CFD29A /* RunLoopObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RunLoopObserver.cpp; sourceTree = "<group>"; };
2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimerEventBasedMock.h; sourceTree = "<group>"; };
+ 2D81E1CB21A78CC100A32CF4 /* InsertEditableImageCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InsertEditableImageCommand.cpp; sourceTree = "<group>"; };
+ 2D81E1CD21A78CC200A32CF4 /* InsertEditableImageCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsertEditableImageCommand.h; sourceTree = "<group>"; };
2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestLocation.cpp; sourceTree = "<group>"; };
2D8287F516E4A0380086BD00 /* HitTestLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HitTestLocation.h; sourceTree = "<group>"; };
2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCrossfadeValue.cpp; sourceTree = "<group>"; };
@@ -20853,6 +20856,8 @@
93309D97099E64910056E581 /* HTMLInterchange.h */,
DB23C2C90A508D29002489EB /* IndentOutdentCommand.cpp */,
DB23C2CA0A508D29002489EB /* IndentOutdentCommand.h */,
+ 2D81E1CB21A78CC100A32CF4 /* InsertEditableImageCommand.cpp */,
+ 2D81E1CD21A78CC200A32CF4 /* InsertEditableImageCommand.h */,
93309D9A099E64910056E581 /* InsertIntoTextNodeCommand.cpp */,
93309D9B099E64910056E581 /* InsertIntoTextNodeCommand.h */,
93309D9C099E64910056E581 /* InsertLineBreakCommand.cpp */,
@@ -29205,6 +29210,7 @@
E52EFDF42112875A00AD282A /* InputMode.h in Headers */,
37E3524D12450C6600BAF5D9 /* InputType.h in Headers */,
C348612415FDE21E007A1CC9 /* InputTypeNames.h in Headers */,
+ 2D81E1CF21A78CC200A32CF4 /* InsertEditableImageCommand.h in Headers */,
93309DEA099E64920056E581 /* InsertIntoTextNodeCommand.h in Headers */,
93309DEC099E64920056E581 /* InsertLineBreakCommand.h in Headers */,
D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */,
Modified: trunk/Source/WebCore/editing/EditAction.h (238474 => 238475)
--- trunk/Source/WebCore/editing/EditAction.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/editing/EditAction.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -87,7 +87,8 @@
ConvertToOrderedList,
ConvertToUnorderedList,
Indent,
- Outdent
+ Outdent,
+ InsertEditableImage
};
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/Editor.cpp (238474 => 238475)
--- trunk/Source/WebCore/editing/Editor.cpp 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/editing/Editor.cpp 2018-11-25 12:11:16 UTC (rev 238475)
@@ -68,6 +68,7 @@
#include "HitTestResult.h"
#include "IndentOutdentCommand.h"
#include "InputEvent.h"
+#include "InsertEditableImageCommand.h"
#include "InsertListCommand.h"
#include "InsertTextCommand.h"
#include "KeyboardEvent.h"
@@ -4250,4 +4251,9 @@
return { };
}
+void Editor::insertEditableImage()
+{
+ InsertEditableImageCommand::create(document())->apply();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/Editor.h (238474 => 238475)
--- trunk/Source/WebCore/editing/Editor.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/editing/Editor.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -532,6 +532,8 @@
#endif
#endif
+ WEBCORE_EXPORT void insertEditableImage();
+
private:
Document& document() const;
Modified: trunk/Source/WebCore/editing/EditorCommand.cpp (238474 => 238475)
--- trunk/Source/WebCore/editing/EditorCommand.cpp 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/editing/EditorCommand.cpp 2018-11-25 12:11:16 UTC (rev 238475)
@@ -46,6 +46,7 @@
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "IndentOutdentCommand.h"
+#include "InsertEditableImageCommand.h"
#include "InsertListCommand.h"
#include "InsertNestedListCommand.h"
#include "Page.h"
@@ -478,6 +479,13 @@
return executeInsertNode(frame, WTFMove(image));
}
+static bool executeInsertEditableImage(Frame& frame, Event*, EditorCommandSource, const String&)
+{
+ ASSERT(frame.document());
+ InsertEditableImageCommand::create(*frame.document())->apply();
+ return true;
+}
+
static bool executeInsertLineBreak(Frame& frame, Event* event, EditorCommandSource source, const String&)
{
switch (source) {
@@ -1371,6 +1379,13 @@
return frame.editor().canUndo();
}
+static bool enabledInRichlyEditableTextWithEditableImagesEnabled(Frame& frame, Event* event, EditorCommandSource source)
+{
+ if (!frame.settings().editableImagesEnabled())
+ return false;
+ return enabledInRichlyEditableText(frame, event, source);
+}
+
// State functions
static TriState stateNone(Frame&, Event*)
@@ -1590,6 +1605,7 @@
{ "IgnoreSpelling", { executeIgnoreSpelling, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Indent", { executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertBacktab", { executeInsertBacktab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertEditableImage", { executeInsertEditableImage, supported, enabledInRichlyEditableTextWithEditableImagesEnabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertHTML", { executeInsertHTML, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertHorizontalRule", { executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertImage", { executeInsertImage, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
Added: trunk/Source/WebCore/editing/InsertEditableImageCommand.cpp (0 => 238475)
--- trunk/Source/WebCore/editing/InsertEditableImageCommand.cpp (rev 0)
+++ trunk/Source/WebCore/editing/InsertEditableImageCommand.cpp 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InsertEditableImageCommand.h"
+
+#include "Editing.h"
+#include "HTMLImageElement.h"
+
+namespace WebCore {
+
+InsertEditableImageCommand::InsertEditableImageCommand(Document& document)
+ : CompositeEditCommand(document)
+{
+}
+
+void InsertEditableImageCommand::doApply()
+{
+ if (endingSelection().isNone())
+ return;
+
+ auto imgElement = HTMLImageElement::create(document());
+ imgElement->setAttributeWithoutSynchronization(x_apple_editable_imageAttr, emptyAtom());
+ imgElement->setAttributeWithoutSynchronization(widthAttr, AtomicString("100%", AtomicString::ConstructFromLiteral));
+ imgElement->setAttributeWithoutSynchronization(heightAttr, AtomicString("300px", AtomicString::ConstructFromLiteral));
+ imgElement->setAttributeWithoutSynchronization(styleAttr, AtomicString("display: block", AtomicString::ConstructFromLiteral));
+
+ insertNodeAt(imgElement.copyRef(), endingSelection().start());
+ setEndingSelection(visiblePositionAfterNode(imgElement.get()));
+}
+
+}
Copied: trunk/Source/WebCore/editing/InsertEditableImageCommand.h (from rev 238474, trunk/Source/WebCore/editing/EditAction.h) (0 => 238475)
--- trunk/Source/WebCore/editing/InsertEditableImageCommand.h (rev 0)
+++ trunk/Source/WebCore/editing/InsertEditableImageCommand.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CompositeEditCommand.h"
+
+namespace WebCore {
+
+class InsertEditableImageCommand : public CompositeEditCommand {
+public:
+ static Ref<InsertEditableImageCommand> create(Document& document)
+ {
+ return adoptRef(*new InsertEditableImageCommand(document));
+ }
+
+private:
+ InsertEditableImageCommand(Document&);
+
+ void doApply() override;
+ EditAction editingAction() const final { return EditAction::InsertEditableImage; }
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/editing/VisibleSelection.cpp (238474 => 238475)
--- trunk/Source/WebCore/editing/VisibleSelection.cpp 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/editing/VisibleSelection.cpp 2018-11-25 12:11:16 UTC (rev 238475)
@@ -31,6 +31,7 @@
#include "Element.h"
#include "HTMLInputElement.h"
#include "Settings.h"
+#include "ShadowRoot.h"
#include "TextIterator.h"
#include "VisibleUnits.h"
#include <stdio.h>
Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (238474 => 238475)
--- trunk/Source/WebCore/en.lproj/Localizable.strings 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings 2018-11-25 12:11:16 UTC (rev 238475)
@@ -356,6 +356,9 @@
"Indent (Undo action name)" = "Indent";
/* Undo action name */
+"Insert Drawing (Undo action name)" = "Insert Drawing";
+
+/* Undo action name */
"Insert List (Undo action name)" = "Insert List";
/* Inspect Element context menu item */
Modified: trunk/Source/WebKit/ChangeLog (238474 => 238475)
--- trunk/Source/WebKit/ChangeLog 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/ChangeLog 2018-11-25 12:11:16 UTC (rev 238475)
@@ -1,5 +1,45 @@
2018-11-25 Tim Horton <timothy_hor...@apple.com>
+ Make it possible to insert editable images with a gesture
+ https://bugs.webkit.org/show_bug.cgi?id=191937
+
+ Reviewed by Wenson Hsieh.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _stylusTapGestureShouldCreateEditableImage]):
+ * UIProcess/API/Cocoa/WKWebViewInternal.h:
+ Add a internal getter for a WKWebViewConfiguration property.
+
+ * UIProcess/WebEditCommandProxy.cpp:
+ (WebKit::WebEditCommandProxy::nameForEditAction):
+ Add a undo name.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView setupInteraction]):
+ (-[WKContentView cleanupInteraction]):
+ (-[WKContentView _removeDefaultGestureRecognizers]):
+ (-[WKContentView _addDefaultGestureRecognizers]):
+ Add a single-stylus-tap gesture recognizer.
+
+ (-[WKContentView _stylusSingleTapRecognized:]):
+ If allowed, request to insert an editable image when a stylus tap occurs.
+
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::handleStylusSingleTapAtPoint):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::handleStylusSingleTapAtPoint):
+ Do a hit test, select the hit position, insert an editable image, and
+ then de-assist any assisted node (to make the keyboard go away).
+ For now, we'll only insert if we hit non-replaced elements,
+ though this heuristic will need to be enhanced significantly once we
+ decide on a design.
+
+2018-11-25 Tim Horton <timothy_hor...@apple.com>
+
Scrolling and drawing compete for incoming gestures
https://bugs.webkit.org/show_bug.cgi?id=191940
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -2440,6 +2440,11 @@
return !areEssentiallyEqualAsFloat(contentZoomScale(self), 1);
}
+- (BOOL)_stylusTapGestureShouldCreateEditableImage
+{
+ return [_configuration _editableImagesEnabled];
+}
+
#pragma mark - UIScrollViewDelegate
- (BOOL)usesStandardContentView
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -167,6 +167,7 @@
@property (nonatomic, readonly) WKSelectionGranularity _selectionGranularity;
@property (nonatomic, readonly) BOOL _allowsDoubleTapGestures;
+@property (nonatomic, readonly) BOOL _stylusTapGestureShouldCreateEditableImage;
@property (nonatomic, readonly) BOOL _haveSetObscuredInsets;
@property (nonatomic, readonly) UIEdgeInsets _computedObscuredInset;
@property (nonatomic, readonly) UIEdgeInsets _computedUnobscuredSafeAreaInset;
Modified: trunk/Source/WebKit/UIProcess/WebEditCommandProxy.cpp (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/WebEditCommandProxy.cpp 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/WebEditCommandProxy.cpp 2018-11-25 12:11:16 UTC (rev 238475)
@@ -177,6 +177,8 @@
return WEB_UI_STRING_KEY("Convert to Ordered List", "Convert to Ordered List (Undo action name)", "Undo action name");
case EditAction::ConvertToUnorderedList:
return WEB_UI_STRING_KEY("Convert to Unordered List", "Convert to Unordered List (Undo action name)", "Undo action name");
+ case EditAction::InsertEditableImage:
+ return WEB_UI_STRING_KEY("Insert Drawing", "Insert Drawing (Undo action name)", "Undo action name");
}
return String();
}
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -652,6 +652,7 @@
void contentSizeCategoryDidChange(const String& contentSizeCategory);
void getSelectionContext(WTF::Function<void(const String&, const String&, const String&, CallbackBase::Error)>&&);
void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
+ void handleStylusSingleTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
void setForceAlwaysUserScalable(bool);
bool forceAlwaysUserScalable() const { return m_forceAlwaysUserScalable; }
double layoutSizeScaleFactor() const { return m_viewportConfigurationLayoutSizeScaleFactor; }
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -210,6 +210,7 @@
RetainPtr<UITapGestureRecognizer> _nonBlockingDoubleTapGestureRecognizer;
RetainPtr<UITapGestureRecognizer> _twoFingerDoubleTapGestureRecognizer;
RetainPtr<UITapGestureRecognizer> _twoFingerSingleTapGestureRecognizer;
+ RetainPtr<UITapGestureRecognizer> _stylusSingleTapGestureRecognizer;
RetainPtr<WKInspectorNodeSearchGestureRecognizer> _inspectorNodeSearchGestureRecognizer;
#if PLATFORM(IOSMAC)
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -691,6 +691,12 @@
[_twoFingerSingleTapGestureRecognizer setDelegate:self];
[self addGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()];
+ _stylusSingleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_stylusSingleTapRecognized:)]);
+ [_stylusSingleTapGestureRecognizer setNumberOfTapsRequired:1];
+ [_stylusSingleTapGestureRecognizer setDelegate:self];
+ [_stylusSingleTapGestureRecognizer setAllowedTouchTypes:@[ @(UITouchTypePencil) ]];
+ [self addGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
+
#if HAVE(LINK_PREVIEW)
[self _registerPreview];
#endif
@@ -778,6 +784,9 @@
[_twoFingerSingleTapGestureRecognizer setDelegate:nil];
[self removeGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()];
+ [_stylusSingleTapGestureRecognizer setDelegate:nil];
+ [self removeGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
+
_layerTreeTransactionIdAtLastTouchStart = 0;
#if ENABLE(DATA_INTERACTION)
@@ -834,6 +843,7 @@
[self removeGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
[self removeGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
[self removeGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()];
+ [self removeGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
#if PLATFORM(IOSMAC)
[self removeGestureRecognizer:_hoverGestureRecognizer.get()];
#endif
@@ -848,6 +858,7 @@
[self addGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
[self addGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
[self addGestureRecognizer:_twoFingerSingleTapGestureRecognizer.get()];
+ [self addGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
#if PLATFORM(IOSMAC)
[self addGestureRecognizer:_hoverGestureRecognizer.get()];
#endif
@@ -1896,6 +1907,15 @@
_page->handleTwoFingerTapAtPoint(roundedIntPoint(gestureRecognizer.centroid), ++_latestTapID);
}
+- (void)_stylusSingleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
+{
+ if (!_webView._stylusTapGestureShouldCreateEditableImage)
+ return;
+
+ ASSERT(gestureRecognizer == _stylusSingleTapGestureRecognizer);
+ _page->handleStylusSingleTapAtPoint(roundedIntPoint(gestureRecognizer.location), ++_latestTapID);
+}
+
- (void)_longPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer
{
ASSERT(gestureRecognizer == _longPressGestureRecognizer);
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (238474 => 238475)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -597,6 +597,11 @@
process().send(Messages::WebPage::HandleTwoFingerTapAtPoint(point, requestID), m_pageID);
}
+void WebPageProxy::handleStylusSingleTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)
+{
+ process().send(Messages::WebPage::HandleStylusSingleTapAtPoint(point, requestID), m_pageID);
+}
+
void WebPageProxy::selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&& callbackFunction)
{
if (!isValid()) {
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (238474 => 238475)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2018-11-25 12:11:16 UTC (rev 238475)
@@ -653,6 +653,7 @@
void updateSelectionAppearance();
void getSelectionContext(CallbackID);
void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
+ void handleStylusSingleTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
void getRectsForGranularityWithSelectionOffset(uint32_t, int32_t, CallbackID);
void getRectsAtSelectionOffsetWithText(int32_t, const String&, CallbackID);
void storeSelectionForAccessibility(bool);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (238474 => 238475)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2018-11-25 12:11:16 UTC (rev 238475)
@@ -99,6 +99,7 @@
GetSelectionContext(WebKit::CallbackID callbackID)
SetAllowsMediaDocumentInlinePlayback(bool allows)
HandleTwoFingerTapAtPoint(WebCore::IntPoint point, uint64_t requestID)
+ HandleStylusSingleTapAtPoint(WebCore::IntPoint point, uint64_t requestID)
SetForceAlwaysUserScalable(bool userScalable)
GetRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, WebKit::CallbackID callbackID)
GetRectsAtSelectionOffsetWithText(int32_t offset, String text, WebKit::CallbackID callbackID)
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (238474 => 238475)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -758,6 +758,36 @@
completeSyntheticClick(nodeRespondingToClick, adjustedPoint, WebCore::TwoFingerTap);
}
+void WebPage::handleStylusSingleTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)
+{
+ auto& frame = m_page->focusController().focusedOrMainFrame();
+
+ auto pointInDocument = frame.view()->rootViewToContents(point);
+ HitTestResult hitTest = frame.eventHandler().hitTestResultAtPoint(pointInDocument, HitTestRequest::ReadOnly | HitTestRequest::Active);
+
+ Node* node = hitTest.innerNonSharedNode();
+ if (!node)
+ return;
+ auto renderer = node->renderer();
+ if (!renderer)
+ return;
+
+ if (renderer->isReplaced())
+ return;
+
+ VisiblePosition position = renderer->positionForPoint(hitTest.localPoint(), nullptr);
+ if (position.isNull())
+ position = firstPositionInOrBeforeNode(node);
+
+ if (position.isNull())
+ return;
+
+ auto range = Range::create(*frame.document(), position, position);
+ frame.selection().setSelectedRange(range.ptr(), position.affinity(), WebCore::FrameSelection::ShouldCloseTyping::Yes, UserTriggered);
+ frame.editor().insertEditableImage();
+ resetAssistedNodeForFrame(m_mainFrame.get());
+}
+
void WebPage::potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoint& position)
{
m_potentialTapNode = m_page->mainFrame().nodeRespondingToClickEvents(position, m_potentialTapLocation, m_potentialTapSecurityOrigin.get());
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (238474 => 238475)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2018-11-25 12:11:16 UTC (rev 238475)
@@ -1,3 +1,14 @@
+2018-11-25 Tim Horton <timothy_hor...@apple.com>
+
+ Make it possible to insert editable images with a gesture
+ https://bugs.webkit.org/show_bug.cgi?id=191937
+
+ Reviewed by Wenson Hsieh.
+
+ * WebCoreSupport/WebEditorClient.mm:
+ (undoNameForEditAction):
+ Add a undo name.
+
2018-11-24 Wenson Hsieh <wenson_hs...@apple.com>
[Cocoa] Fix a few localizable string descriptions in WebEditCommandProxy.cpp and WebEditorClient.mm
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm (238474 => 238475)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -655,6 +655,7 @@
case EditAction::Dictation: return UI_STRING_KEY_INTERNAL("Dictation", "Dictation (Undo action name)", "Undo action name");
case EditAction::ConvertToOrderedList: return UI_STRING_KEY_INTERNAL("Convert to Ordered List", "Convert to Ordered List (Undo action name)", "Undo action name");
case EditAction::ConvertToUnorderedList: return UI_STRING_KEY_INTERNAL("Convert to Unordered List", "Convert to Unordered List (Undo action name)", "Undo action name");
+ case EditAction::InsertEditableImage: return UI_STRING_KEY_INTERNAL("Insert Drawing", "Insert Drawing (Undo action name)", "Undo action name");
}
return nil;
}
Modified: trunk/Tools/ChangeLog (238474 => 238475)
--- trunk/Tools/ChangeLog 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Tools/ChangeLog 2018-11-25 12:11:16 UTC (rev 238475)
@@ -1,3 +1,15 @@
+2018-11-25 Tim Horton <timothy_hor...@apple.com>
+
+ Make it possible to insert editable images with a gesture
+ https://bugs.webkit.org/show_bug.cgi?id=191937
+
+ Reviewed by Wenson Hsieh.
+
+ * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+ (WTR::UIScriptController::drawSquareInEditableImage):
+ If the canvas already has a drawing, draw a new stroke on top of it
+ instead of removing the existing stroke.
+
2018-11-24 Wenson Hsieh <wenson_hs...@apple.com>
[Cocoa] Add WKWebView SPI to trigger and remove data detection
Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (238474 => 238475)
--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2018-11-25 12:05:02 UTC (rev 238474)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2018-11-25 12:11:16 UTC (rev 238475)
@@ -890,7 +890,7 @@
Class pkStrokeClass = NSClassFromString(@"PKStroke");
PKCanvasView *canvasView = findEditableImageCanvas();
- RetainPtr<PKDrawing> drawing = adoptNS([[pkDrawingClass alloc] init]);
+ RetainPtr<PKDrawing> drawing = canvasView.drawing ?: adoptNS([[pkDrawingClass alloc] init]);
RetainPtr<CGPathRef> path = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, 50, 50), NULL));
RetainPtr<PKInk> ink = [pkInkClass inkWithType:0 color:UIColor.greenColor weight:100.0];
RetainPtr<PKStroke> stroke = adoptNS([[pkStrokeClass alloc] _initWithPath:path.get() ink:ink.get() inputScale:1]);