Title: [198092] trunk
Revision
198092
Author
wei...@apple.com
Date
2016-03-13 21:43:58 -0700 (Sun, 13 Mar 2016)

Log Message

Implement unprivileged execCommand("copy") and execCommand("cut")
<rdar://problem/24354406>
https://bugs.webkit.org/show_bug.cgi?id=146336

Reviewed by Dean Jackson.

Source/WebCore:

Test: editing/execCommand/clipboard-access-with-user-gesture.html

* WebCore.xcodeproj/project.pbxproj:
Add new files.

* editing/ClipboardAccessPolicy.h:
Added.

* editing/EditorCommand.cpp:
(WebCore::defaultValueForSupportedCopyCut):
(WebCore::supportedCopyCut):
Match other browsers and allow the copy and cut commands
to be executed when there is a user gesture.

* page/Settings.h:
Add include of ClipboardAccessPolicy.h.

* page/Settings.in:
Add new setting for ClipboardAccessPolicy

LayoutTests:

* editing/execCommand/clipboard-access-with-user-gesture-expected.txt: Added.
* editing/execCommand/clipboard-access-with-user-gesture.html: Added.
Add test for using execCommand("copy") and execCommand("cut") during a user gesture.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (198091 => 198092)


--- trunk/LayoutTests/ChangeLog	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/LayoutTests/ChangeLog	2016-03-14 04:43:58 UTC (rev 198092)
@@ -1,3 +1,15 @@
+2016-03-13  Sam Weinig  <s...@webkit.org>
+
+        Implement unprivileged execCommand("copy") and execCommand("cut")
+        <rdar://problem/24354406>
+        https://bugs.webkit.org/show_bug.cgi?id=146336
+
+        Reviewed by Dean Jackson.
+
+        * editing/execCommand/clipboard-access-with-user-gesture-expected.txt: Added.
+        * editing/execCommand/clipboard-access-with-user-gesture.html: Added.
+        Add test for using execCommand("copy") and execCommand("cut") during a user gesture.
+
 2016-03-13  Dean Jackson  <d...@apple.com>
 
         DRT should enable WebGL by default on Mac

Added: trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture-expected.txt (0 => 198092)


--- trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture-expected.txt	2016-03-14 04:43:58 UTC (rev 198092)
@@ -0,0 +1,121 @@
+This test checks that _javascript_ programs can execute copy and paste commands, but only during a user gesture.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Testing copying an editableParagraph range without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying an editableParagraph caret without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying an non-editable range without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying an non-editable caret without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying an editable plaint-text range without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying an editable plaint-text caret without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing copying when there is no selection without a user gesture.
+PASS document.queryCommandEnabled('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.queryCommandSupported('copy') is false
+PASS eventSeen['copy'] is false
+PASS document.execCommand('copy') is false
+PASS eventSeen['copy'] is false
+
+Testing cutting an editableParagraph range without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting an editableParagraph caret without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting an non-editable range without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting an non-editable caret without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting an editable plaint-text range without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting an editable plaint-text caret without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+
+Testing cutting when there is no selection without a user gesture.
+PASS document.queryCommandEnabled('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.queryCommandSupported('cut') is false
+PASS eventSeen['cut'] is false
+PASS document.execCommand('cut') is false
+PASS eventSeen['cut'] is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture.html (0 => 198092)


--- trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/clipboard-access-with-user-gesture.html	2016-03-14 04:43:58 UTC (rev 198092)
@@ -0,0 +1,275 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<script>
+
+description("This test checks that _javascript_ programs can execute copy and paste commands, but only during a user gesture.");
+
+// Override the test runner default befavior of allowing all keyboard access, and act more like
+// a browser.
+if (window.testRunner)
+    window.testRunner.setJavaScriptCanAccessClipboard(false);
+
+function clearSelectionContainer()
+{
+    var container = document.getElementById('container');
+    if (container)
+        container.remove();
+}
+
+function resetSelectionContainer()
+{
+    clearSelectionContainer();
+
+    var container = document.createElement("div");
+    container.id = "container";
+
+    var nonEditableParagraph = document.createElement("p");
+    nonEditableParagraph.id = "nonEditableParagraph";
+    nonEditableParagraph.appendChild(document.createTextNode("x"));
+    container.appendChild(nonEditableParagraph);
+
+    var editableParagraph = document.createElement("p");
+    editableParagraph.id = "editableParagraph";
+    editableParagraph.appendChild(document.createTextNode("x"));
+    editableParagraph.setAttribute("contentEditable", "true");
+    container.appendChild(editableParagraph);
+
+    var editablePlainTextParagraph = document.createElement("p");
+    editablePlainTextParagraph.id = "editablePlainTextParagraph";
+    editablePlainTextParagraph.appendChild(document.createTextNode("x"));
+    editablePlainTextParagraph.setAttribute("contentEditable", "plaintext-only");
+    container.appendChild(editablePlainTextParagraph);
+
+    document.body.appendChild(container);
+}
+
+function makeSelection(elementId, selectionStart, selectionEnd)
+{
+    resetSelectionContainer();
+
+    var selection = window.getSelection();
+    selection.removeAllRanges();
+
+    var element = document.getElementById(elementId);
+
+    var range = document.createRange();
+    range.setStart(element.firstChild, selectionStart);
+    range.setEnd(element.firstChild, selectionEnd);
+    selection.addRange(range);
+}
+
+var eventSeen = {
+    "copy": false,
+    "cut": false,
+    "beforecopy": false,
+    "beforecut": false
+}
+
+function resetSeenFlags()
+{
+    eventSeen.copy = false;
+    eventSeen.cut = false;
+    eventSeen.beforecopy = false;
+    eventSeen.beforecut = false;
+}
+
+document.body._oncopy_ = function(event)
+{
+    eventSeen["copy"] = true;
+}
+
+document.body._oncut_ = function()
+{
+    eventSeen["cut"] = true;
+}
+
+document.body._onbeforecopy_ = function()
+{
+    eventSeen["beforecopy"] = true;
+}
+
+document.body._onbeforecut_ = function()
+{
+    eventSeen["beforecut"] = true;
+}
+
+function test(command, enabledExpected, supportedExpected, executedExpected)
+{
+    resetSeenFlags();
+    shouldBe("document.queryCommandEnabled('" + command +"')", "" + enabledExpected);
+    shouldBeFalse("eventSeen['" + command +"']");
+
+    resetSeenFlags();
+    shouldBe("document.queryCommandSupported('" + command +"')", "" + supportedExpected);
+    shouldBeFalse("eventSeen['" + command +"']");
+
+    resetSeenFlags();
+    shouldBe("document.execCommand('" + command +"')", "" + executedExpected);
+    shouldBe("eventSeen['" + command +"']", "" + executedExpected);
+}
+
+function header(msg)
+{
+    debug("");
+    debug(msg);
+}
+
+var buttonForCopy = document.createElement("button");
+buttonForCopy.id = "copyButton";
+buttonForCopy.textContent = "Copy";
+buttonForCopy._onclick_ = function()
+{
+    header("Testing copying an editableParagraph range in a user gesture.")
+    makeSelection("editableParagraph", 0, 1);
+    test("copy", true, true, true);
+
+    header("Testing copying an editableParagraph caret in a user gesture.")
+    makeSelection("editableParagraph", 0, 0);
+    test("copy", false, true, true);
+
+    header("Testing copying an non-editable range in a user gesture.")
+    makeSelection("nonEditableParagraph", 0, 1);
+    test("copy", true, true, true);
+
+    header("Testing copying an non-editable caret in a user gesture.")
+    makeSelection("nonEditableParagraph", 0, 0);
+    test("copy", false, true, true);
+
+    header("Testing copying an editable plaint-text range in a user gesture.")
+    makeSelection("editablePlainTextParagraph", 0, 1);
+    test("copy", true, true, true);
+
+    header("Testing copying an editable plaint-text caret in a user gesture.")
+    makeSelection("editablePlainTextParagraph", 0, 0);
+    test("copy", false, true, true);
+
+    header("Testing copying when there is no selection in a user gesture.")
+    window.getSelection().removeAllRanges();
+    test("copy", false, true, true);
+
+    clearSelectionContainer();
+}
+document.body.appendChild(buttonForCopy);
+
+var buttonForCut = document.createElement("button");
+buttonForCut.id = "cutButton";
+buttonForCut.textContent = "Cut";
+buttonForCut._onclick_ = function()
+{
+    header("Testing cutting an editableParagraph range in a user gesture.")
+    makeSelection("editableParagraph", 0, 1);
+    test("cut", true, true, true);
+
+    header("Testing cutting an editableParagraph caret in a user gesture.")
+    makeSelection("editableParagraph", 0, 0);
+    test("cut", false, true, true);
+
+    header("Testing cutting an non-editable range in a user gesture.")
+    makeSelection("nonEditableParagraph", 0, 1);
+    test("cut", false, true, true);
+
+    header("Testing cutting an non-editable caret in a user gesture.")
+    makeSelection("nonEditableParagraph", 0, 0);
+    test("cut", false, true, true);
+
+    header("Testing cutting an editable plaint-text range in a user gesture.")
+    makeSelection("editablePlainTextParagraph", 0, 1);
+    test("cut", true, true, true);
+
+    header("Testing cutting an editable plaint-text caret in a user gesture.")
+    makeSelection("editablePlainTextParagraph", 0, 0);
+    test("cut", false, true, true);
+
+    header("Testing cutting when there is no selection in a user gesture.")
+    window.getSelection().removeAllRanges();
+    test("cut", false, true, true);
+
+    clearSelectionContainer();
+}
+document.body.appendChild(buttonForCut);
+
+// First test copy/cut without user gestures.
+header("Testing copying an editableParagraph range without a user gesture.")
+makeSelection("editableParagraph", 0, 1);
+test("copy", false, false, false);
+
+header("Testing copying an editableParagraph caret without a user gesture.")
+makeSelection("editableParagraph", 0, 0);
+test("copy", false, false, false);
+
+header("Testing copying an non-editable range without a user gesture.")
+makeSelection("nonEditableParagraph", 0, 1);
+test("copy", false, false, false);
+
+header("Testing copying an non-editable caret without a user gesture.")
+makeSelection("nonEditableParagraph", 0, 0);
+test("copy", false, false, false);
+
+header("Testing copying an editable plaint-text range without a user gesture.")
+makeSelection("editablePlainTextParagraph", 0, 1);
+test("copy", false, false, false);
+
+header("Testing copying an editable plaint-text caret without a user gesture.")
+makeSelection("editablePlainTextParagraph", 0, 0);
+test("copy", false, false, false);
+
+header("Testing copying when there is no selection without a user gesture.")
+window.getSelection().removeAllRanges();
+test("copy", false, false, false);
+
+clearSelectionContainer();
+
+header("Testing cutting an editableParagraph range without a user gesture.")
+makeSelection("editableParagraph", 0, 1);
+test("cut", false, false, false);
+
+header("Testing cutting an editableParagraph caret without a user gesture.")
+makeSelection("editableParagraph", 0, 0);
+test("cut", false, false, false);
+
+header("Testing cutting an non-editable range without a user gesture.")
+makeSelection("nonEditableParagraph", 0, 1);
+test("cut", false, false, false);
+
+header("Testing cutting an non-editable caret without a user gesture.")
+makeSelection("nonEditableParagraph", 0, 0);
+test("cut", false, false, false);
+
+header("Testing cutting an editable plaint-text range without a user gesture.")
+makeSelection("editablePlainTextParagraph", 0, 1);
+test("cut", false, false, false);
+
+header("Testing cutting an editable plaint-text caret without a user gesture.")
+makeSelection("editablePlainTextParagraph", 0, 0);
+test("cut", false, false, false);
+
+header("Testing cutting when there is no selection without a user gesture.")
+window.getSelection().removeAllRanges();
+test("cut", false, false, false);
+
+clearSelectionContainer();
+
+// Then test copy/cut with user gestures.
+if (window.testRunner) {
+    function clickButton(button)
+    {
+        eventSender.mouseMoveTo(button.offsetLeft + button.offsetWidth / 2, button.offsetTop + button.offsetHeight / 2);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+
+    clickButton(buttonForCopy);
+    clickButton(buttonForCut);
+
+    buttonForCopy.remove();
+    buttonForCut.remove();
+}
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (198091 => 198092)


--- trunk/Source/WebCore/ChangeLog	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/Source/WebCore/ChangeLog	2016-03-14 04:43:58 UTC (rev 198092)
@@ -1,3 +1,31 @@
+2016-03-13  Sam Weinig  <s...@webkit.org>
+
+        Implement unprivileged execCommand("copy") and execCommand("cut")
+        <rdar://problem/24354406>
+        https://bugs.webkit.org/show_bug.cgi?id=146336
+
+        Reviewed by Dean Jackson.
+
+        Test: editing/execCommand/clipboard-access-with-user-gesture.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new files.
+
+        * editing/ClipboardAccessPolicy.h:
+        Added.
+
+        * editing/EditorCommand.cpp:
+        (WebCore::defaultValueForSupportedCopyCut):
+        (WebCore::supportedCopyCut):
+        Match other browsers and allow the copy and cut commands
+        to be executed when there is a user gesture.
+
+        * page/Settings.h:
+        Add include of ClipboardAccessPolicy.h.
+
+        * page/Settings.in:
+        Add new setting for ClipboardAccessPolicy
+
 2016-03-13  Ryosuke Niwa  <rn...@webkit.org>
 
         REGRESSION (r190840): crash inside details element's slotNameFunction

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (198091 => 198092)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-03-14 04:43:58 UTC (rev 198092)
@@ -2733,6 +2733,7 @@
 		7C33F35A1B4A044800502CAF /* JSCharacterDataCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C33F3581B4A044800502CAF /* JSCharacterDataCustom.cpp */; };
 		7C33F35E1B4A04CE00502CAF /* JSDocumentTypeCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C33F35C1B4A04CE00502CAF /* JSDocumentTypeCustom.cpp */; };
 		7C33F3621B4A050400502CAF /* JSDocumentFragmentCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C33F3601B4A050400502CAF /* JSDocumentFragmentCustom.cpp */; };
+		7C3A91E61C963B8800D1A7E3 /* ClipboardAccessPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3A91E51C963B8800D1A7E3 /* ClipboardAccessPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C3B79711908757B00B47A2D /* UserMessageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C3B796F1908757B00B47A2D /* UserMessageHandler.cpp */; };
 		7C3B79721908757B00B47A2D /* UserMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3B79701908757B00B47A2D /* UserMessageHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C3E510A18DF8F3500C112F7 /* HTMLConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3E510818DF8F3500C112F7 /* HTMLConverter.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -10369,6 +10370,7 @@
 		7C33F3581B4A044800502CAF /* JSCharacterDataCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCharacterDataCustom.cpp; sourceTree = "<group>"; };
 		7C33F35C1B4A04CE00502CAF /* JSDocumentTypeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDocumentTypeCustom.cpp; sourceTree = "<group>"; };
 		7C33F3601B4A050400502CAF /* JSDocumentFragmentCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDocumentFragmentCustom.cpp; sourceTree = "<group>"; };
+		7C3A91E51C963B8800D1A7E3 /* ClipboardAccessPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClipboardAccessPolicy.h; sourceTree = "<group>"; };
 		7C3B796F1908757B00B47A2D /* UserMessageHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMessageHandler.cpp; sourceTree = "<group>"; };
 		7C3B79701908757B00B47A2D /* UserMessageHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMessageHandler.h; sourceTree = "<group>"; };
 		7C3E510818DF8F3500C112F7 /* HTMLConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLConverter.h; sourceTree = "<group>"; };
@@ -18844,6 +18846,7 @@
 				93309D8A099E64910056E581 /* ApplyStyleCommand.h */,
 				93309D8B099E64910056E581 /* BreakBlockquoteCommand.cpp */,
 				93309D8C099E64910056E581 /* BreakBlockquoteCommand.h */,
+				7C3A91E51C963B8800D1A7E3 /* ClipboardAccessPolicy.h */,
 				93309D8D099E64910056E581 /* CompositeEditCommand.cpp */,
 				93309D8E099E64910056E581 /* CompositeEditCommand.h */,
 				D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */,
@@ -26499,6 +26502,7 @@
 				BC46C1FB0C0DDC8F0020CFC3 /* JSCSSCharsetRule.h in Headers */,
 				409EBDC316B7F3A600CBA3FC /* JSCSSFontFaceLoadEvent.h in Headers */,
 				BC46C1FD0C0DDC8F0020CFC3 /* JSCSSFontFaceRule.h in Headers */,
+				7C3A91E61C963B8800D1A7E3 /* ClipboardAccessPolicy.h in Headers */,
 				BC46C1FF0C0DDC8F0020CFC3 /* JSCSSImportRule.h in Headers */,
 				316FE0720E6CCBEE00BF6088 /* JSCSSKeyframeRule.h in Headers */,
 				316FE0740E6CCBEE00BF6088 /* JSCSSKeyframesRule.h in Headers */,

Added: trunk/Source/WebCore/editing/ClipboardAccessPolicy.h (0 => 198092)


--- trunk/Source/WebCore/editing/ClipboardAccessPolicy.h	                        (rev 0)
+++ trunk/Source/WebCore/editing/ClipboardAccessPolicy.h	2016-03-14 04:43:58 UTC (rev 198092)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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. AND ITS CONTRIBUTORS ``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 ITS 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
+
+namespace WebCore {
+
+enum class ClipboardAccessPolicy {
+    Allow,
+    Deny,
+    RequiresUserGesture
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/editing/EditorCommand.cpp (198091 => 198092)


--- trunk/Source/WebCore/editing/EditorCommand.cpp	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/Source/WebCore/editing/EditorCommand.cpp	2016-03-14 04:43:58 UTC (rev 198092)
@@ -57,6 +57,7 @@
 #include "StyleProperties.h"
 #include "TypingCommand.h"
 #include "UnlinkCommand.h"
+#include "UserGestureIndicator.h"
 #include "UserTypingGestureIndicator.h"
 #include "htmlediting.h"
 #include "markup.h"
@@ -1157,12 +1158,31 @@
     return false;
 }
 
+static bool defaultValueForSupportedCopyCut(Frame& frame)
+{
+    auto& settings = frame.settings();
+    if (settings._javascript_CanAccessClipboard())
+        return true;
+    
+    switch (settings.clipboardAccessPolicy()) {
+    case ClipboardAccessPolicy::Allow:
+        return true;
+    case ClipboardAccessPolicy::Deny:
+        return false;
+    case ClipboardAccessPolicy::RequiresUserGesture:
+        return UserGestureIndicator::processingUserGesture();
+    }
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 static bool supportedCopyCut(Frame* frame)
 {
     if (!frame)
         return false;
 
-    bool defaultValue = frame->settings()._javascript_CanAccessClipboard();
+    bool defaultValue = defaultValueForSupportedCopyCut(*frame);
 
     EditorClient* client = frame->editor().client();
     return client ? client->canCopyCut(frame, defaultValue) : defaultValue;

Modified: trunk/Source/WebCore/page/Settings.h (198091 => 198092)


--- trunk/Source/WebCore/page/Settings.h	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/Source/WebCore/page/Settings.h	2016-03-14 04:43:58 UTC (rev 198092)
@@ -27,13 +27,14 @@
 #ifndef Settings_h
 #define Settings_h
 
+#include "ClipboardAccessPolicy.h"
 #include "EditingBehaviorTypes.h"
 #include "IntSize.h"
-#include "URL.h"
 #include "SecurityOrigin.h"
 #include "SettingsMacros.h"
 #include "TextFlags.h"
 #include "Timer.h"
+#include "URL.h"
 #include <chrono>
 #include <runtime/RuntimeFlags.h>
 #include <unicode/uscript.h>

Modified: trunk/Source/WebCore/page/Settings.in (198091 => 198092)


--- trunk/Source/WebCore/page/Settings.in	2016-03-14 03:58:26 UTC (rev 198091)
+++ trunk/Source/WebCore/page/Settings.in	2016-03-14 04:43:58 UTC (rev 198092)
@@ -53,6 +53,7 @@
 _javascript_CanAccessClipboard initial=false
 shouldPrintBackgrounds initial=false
 usesDashboardBackwardCompatibilityMode initial=false, conditional=DASHBOARD_SUPPORT
+clipboardAccessPolicy type=ClipboardAccessPolicy, initial=ClipboardAccessPolicy::RequiresUserGesture
 
 textAreasAreResizable initial=false, setNeedsStyleRecalcInAllFrames=1
 authorAndUserStylesEnabled initial=true, setNeedsStyleRecalcInAllFrames=1
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to