2009-06-24 Dan Bernstein <mitz@apple.com>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2009 09:24:33 +0000 (09:24 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2009 09:24:33 +0000 (09:24 +0000)
        Reviewed by Simon Fraser.

        - test for <rdar://problem/7001817> REGRESSION (r41902): Base position
          track at UCSC Genome Browser doesn't work because image map prevents
          img from hit-testing

        * fast/replaced/image-map-2-expected.txt: Added.
        * fast/replaced/image-map-2.html: Added.

2009-05-21  Eric Seidel  <eric@webkit.org>

        Reviewed by Maciej Stachowiak.

        Expose files in the clipboard in ondrop events
        https://bugs.webkit.org/show_bug.cgi?id=25916

        Make it possible for applications like gmail to implement
        drag and drop of attachments onto email messages.

        This patch exposes an event.dataTransfer.files accessor
        on the drop event.  No information is exposed during dragover.
        This follows the HTML 5 drag and drop security model:
        http://www.w3.org/TR/html5/editing.html#security-risks-in-the-drag-and-drop-model
        The test http/tests/security/clipboard/clipboard-file-access.html
        verifies this behavior.

        Internet Explorer shows historical documentation of supporting
        getData('File') as a way of exposing files on the pasteboard.  The current version of their docs:
        http://msdn.microsoft.com/en-us/library/ms537658(VS.85).aspx
        has removed this reference (as far as I can tell IE never implemented it)
        I have a printed copy of that URL from 2008 on my desk describing getData('File') in IE.
        IE does not follow the HTML5 clipboard security model and always allows access to the full clipboard, even on dragover.

        I choose not to use IE's getData('File') and instead added .files
        so that the accessor could have a type, matching WebKit's existing
        .files accessor on HTMLInputElement.

        Mozilla has equivalent file access:
        event.dataTransfer.mozGetDataAt("application/x-moz-file", 0);
        which also does not return a typed value.
        https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types#Dragging_Files

        This is only implemented for Mac WebKit.  All other platforms (including Apple's Win WebKit)
        have incomplete Clipboard implementations and will require experts from those platforms
        to add this functionality.  Right now they all have Clipboard*::files() methods which call notImplemented();

        Test: http/tests/security/clipboard/clipboard-file-access.html

        * dom/Clipboard.h:
        * dom/Clipboard.idl:
        * platform/chromium/ClipboardChromium.cpp:
        (WebCore::ClipboardChromium::files):
        * platform/chromium/ClipboardChromium.h:
        * platform/gtk/ClipboardGtk.cpp:
        (WebCore::ClipboardGtk::files):
        * platform/gtk/ClipboardGtk.h:
        * platform/mac/ClipboardMac.h:
        * platform/mac/ClipboardMac.mm:
        (WebCore::absoluteURLsFromPasteboardFilenames):
        (WebCore::absoluteURLsFromPasteboard):
        (WebCore::ClipboardMac::files):
        * platform/qt/ClipboardQt.cpp:
        (WebCore::ClipboardQt::files):
        * platform/qt/ClipboardQt.h:
        * platform/win/ClipboardWin.cpp:
        (WebCore::ClipboardWin::files):
        * platform/win/ClipboardWin.h:
        * platform/wx/ClipboardWx.cpp:
        (WebCore::ClipboardWx::files):
        * platform/wx/ClipboardWx.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@45168 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/security/clipboard/clipboard-file-access-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/clipboard/clipboard-file-access.html [new file with mode: 0644]
LayoutTests/http/tests/security/clipboard/resources/TEMPLATE.html [new file with mode: 0644]
LayoutTests/http/tests/security/clipboard/resources/apple.gif [new file with mode: 0644]
LayoutTests/http/tests/security/clipboard/resources/clipboard-file-access.js [new file with mode: 0644]
LayoutTests/http/tests/security/clipboard/resources/mozilla.gif [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/Clipboard.h
WebCore/dom/Clipboard.idl
WebCore/platform/chromium/ClipboardChromium.cpp
WebCore/platform/chromium/ClipboardChromium.h
WebCore/platform/gtk/ClipboardGtk.cpp
WebCore/platform/gtk/ClipboardGtk.h
WebCore/platform/mac/ClipboardMac.h
WebCore/platform/mac/ClipboardMac.mm
WebCore/platform/qt/ClipboardQt.cpp
WebCore/platform/qt/ClipboardQt.h
WebCore/platform/win/ClipboardWin.cpp
WebCore/platform/win/ClipboardWin.h
WebCore/platform/wx/ClipboardWx.cpp
WebCore/platform/wx/ClipboardWx.h

index 04084d8..838dd85 100644 (file)
         * fast/dom/event-attribute-availability-expected.txt:
         * fast/dom/resources/event-attribute-availability.js:
 
+2009-05-21  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Maciej Stachowiak.
+
+        Expose files in the clipboard in ondrop events.
+        https://bugs.webkit.org/show_bug.cgi?id=25916
+
+        File.fileSize subtests fail due to limitations of DRT during http tests:
+        https://bugs.webkit.org/show_bug.cgi?id=25909
+
+        Directory subtests fail until correct of directory File tests is decided by:
+        https://bugs.webkit.org/show_bug.cgi?id=25879
+
+        * http/tests/security/clipboard/clipboard-file-access-expected.txt: Added.
+        * http/tests/security/clipboard/clipboard-file-access.html: Added.
+        * http/tests/security/clipboard/resources/TEMPLATE.html: Added.
+        * http/tests/security/clipboard/resources/apple.gif: Copied from LayoutTests/editing/pasteboard/resources/apple.gif.
+        * http/tests/security/clipboard/resources/clipboard-file-access.js: Added.
+        (var):
+        (moveMouseToCenterOfElement):
+        (dragFilesOntoDragTarget):
+        (fileListShouldBe):
+        (draggingPathsShouldResultInFiles):
+        (runTest):
+        * http/tests/security/clipboard/resources/mozilla.gif: Copied from LayoutTests/editing/pasteboard/resources/mozilla.gif.
+
 2009-06-22  David Levin  <levin@chromium.org>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/http/tests/security/clipboard/clipboard-file-access-expected.txt b/LayoutTests/http/tests/security/clipboard/clipboard-file-access-expected.txt
new file mode 100644 (file)
index 0000000..733752f
--- /dev/null
@@ -0,0 +1,77 @@
+Tests access to event.dataTransfer.files
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Dragging no files should return an empty file list (arbitrary implementation detail):
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+PASS event.dataTransfer.files.length is 0
+Dragging a single (non-existant) file onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+PASS event.dataTransfer.files.length is 1
+PASS event.dataTransfer.files[0].fileName is "DRTFakeFile"
+PASS event.dataTransfer.files[0].fileSize is 0
+FIXME: File.fileSize always returns 0 for files dropped by eventSender.beginDragWithFiles from http tests:  https://bugs.webkit.org/show_bug.cgi?id=25909
+Dragging a real file onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+PASS event.dataTransfer.files.length is 1
+PASS event.dataTransfer.files[0].fileName is "apple.gif"
+FAIL event.dataTransfer.files[0].fileSize should be 1476. Was 0.
+Dragging two files onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+PASS event.dataTransfer.files.length is 2
+PASS event.dataTransfer.files[0].fileName is "apple.gif"
+FAIL event.dataTransfer.files[0].fileSize should be 1476. Was 0.
+PASS event.dataTransfer.files[1].fileName is "mozilla.gif"
+FAIL event.dataTransfer.files[1].fileSize should be 2593. Was 0.
+Dragging two files in reverse alphabetical order onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+PASS event.dataTransfer.files.length is 2
+PASS event.dataTransfer.files[0].fileName is "mozilla.gif"
+FAIL event.dataTransfer.files[0].fileSize should be 2593. Was 0.
+PASS event.dataTransfer.files[1].fileName is "apple.gif"
+FAIL event.dataTransfer.files[1].fileSize should be 1476. Was 0.
+FIXME: We should not allow element to accept drops including directories unless https://bugs.webkit.org/show_bug.cgi?id=25879 is fixed to make directory File objects useful from JavaScript.  The page is given File objects corresponding to directories, but form submission and xhr.send() will fail.
+Dragging a directory onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+FAIL event.dataTransfer.files.length should be 0. Was 1.
+Dragging a file and a directory onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+FAIL event.dataTransfer.files.length should be 0. Was 2.
+Dragging a directory and a file onto an element:
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On dragover:
+PASS event.dataTransfer.files.length is 0
+On drop:
+FAIL event.dataTransfer.files.length should be 0. Was 2.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/security/clipboard/clipboard-file-access.html b/LayoutTests/http/tests/security/clipboard/clipboard-file-access.html
new file mode 100644 (file)
index 0000000..1e325ae
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js-test-resources/js-test-style.css">
+<script src="../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/clipboard-file-access.js"></script>
+<script src="../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/clipboard/resources/TEMPLATE.html b/LayoutTests/http/tests/security/clipboard/resources/TEMPLATE.html
new file mode 100644 (file)
index 0000000..7c2e409
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js-test-resources/js-test-style.css">
+<script src="../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="YOUR_JS_FILE_HERE"></script>
+<script src="../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/clipboard/resources/apple.gif b/LayoutTests/http/tests/security/clipboard/resources/apple.gif
new file mode 100644 (file)
index 0000000..55844c8
Binary files /dev/null and b/LayoutTests/http/tests/security/clipboard/resources/apple.gif differ
diff --git a/LayoutTests/http/tests/security/clipboard/resources/clipboard-file-access.js b/LayoutTests/http/tests/security/clipboard/resources/clipboard-file-access.js
new file mode 100644 (file)
index 0000000..06d435b
--- /dev/null
@@ -0,0 +1,118 @@
+description("Tests access to event.dataTransfer.files");
+
+var dragTarget = document.createElement("div");
+dragTarget.innerHTML = "Drag here"
+dragTarget.style.backgroundColor = "blue";
+dragTarget.style.width = "100px";
+dragTarget.style.height = "100px";
+// Important that we put this at the top of the doc so that logging does not cause it to go out of view (and be undragable)
+document.body.insertBefore(dragTarget, document.body.firstChild);
+
+dragTarget.addEventListener("dragentered", function() {
+    event.dataTransfer.dropEffect = "copy";
+    event.preventDefault();
+}, false);
+
+dragTarget.addEventListener("dragover", function() {
+    debug("On dragover:")
+    fileListShouldBe("event.dataTransfer.files", []);
+    event.preventDefault();
+}, false);
+
+var expectedFilesOnDrop;
+dragTarget.addEventListener("drop", function() {
+    debug("On drop:")
+    fileListShouldBe("event.dataTransfer.files", expectedFilesOnDrop);
+    event.preventDefault();
+}, false);
+
+function moveMouseToCenterOfElement(element)
+{
+    var centerX = element.offsetLeft + element.offsetWidth / 2;
+    var centerY = element.offsetTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(centerX, centerY);
+}
+
+function dragFilesOntoDragTarget(files) {
+    eventSender.beginDragWithFiles(files);
+    moveMouseToCenterOfElement(dragTarget);
+    eventSender.mouseUp();
+}
+
+function fileListShouldBe(fileListString, filesArray)
+{
+    shouldBe(fileListString + ".length", "" + filesArray.length);
+    for (var x = 0; x < filesArray.length; x++) {
+        var fileValueString = fileListString + "[" + x + "]";
+        shouldBeEqualToString(fileValueString + ".fileName", filesArray[x]['name']);
+        shouldBe(fileValueString + ".fileSize", "" + filesArray[x]['size']);
+    }
+}
+
+function draggingPathsShouldResultInFiles(pathsArray, filesArray)
+{
+    expectedFilesOnDrop = filesArray;
+    dragFilesOntoDragTarget(pathsArray);
+}
+
+function testDraggingFiles(filesArray)
+{
+    // We could make a way to parse the filename from the path, and then only need to pass
+    // the path in the filesArray.
+    var pathsOnly = filesArray.map(function(fileSpec) { return fileSpec['path']; });
+    draggingPathsShouldResultInFiles(pathsOnly, filesArray);
+}
+
+function runTest()
+{
+    debug("Dragging no files should return an empty file list (arbitrary implementation detail):");
+    testDraggingFiles([]);
+
+    debug("Dragging a single (non-existant) file onto an element:");
+    testDraggingFiles([
+        { 'path': 'DRTFakeFile', 'name' : 'DRTFakeFile', 'size' : 0 }
+    ]);
+
+    debug("FIXME: File.fileSize always returns 0 for files dropped by eventSender.beginDragWithFiles from http tests:  https://bugs.webkit.org/show_bug.cgi?id=25909");
+
+    debug("Dragging a real file onto an element:");
+    testDraggingFiles([
+        { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 }
+    ]);
+
+    debug("Dragging two files onto an element:");
+    testDraggingFiles([
+        { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 },
+        { 'path': 'resources/mozilla.gif', 'name' : 'mozilla.gif', 'size' : 2593 }
+    ]);
+
+    debug("Dragging two files in reverse alphabetical order onto an element:");
+    testDraggingFiles([
+        { 'path': 'resources/mozilla.gif', 'name' : 'mozilla.gif', 'size' : 2593 },
+        { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 }
+    ]);
+
+    // Directory dragging behavior is covered by https://bugs.webkit.org/show_bug.cgi?id=25852 and https://bugs.webkit.org/show_bug.cgi?id=25879
+    debug("FIXME: We should not allow element to accept drops including directories unless https://bugs.webkit.org/show_bug.cgi?id=25879 is fixed to make directory File objects useful from JavaScript.  The page is given File objects corresponding to directories, but form submission and xhr.send() will fail.");
+    debug("Dragging a directory onto an element:");
+    draggingPathsShouldResultInFiles(['resources/directory-for-dragging'], []);
+
+    // Note: The order of selection in the Finder changes the order of file paths in the pasteboard
+    // thus it's important that we test different orders here as well (at least on the Mac)
+    // Both drops should be refused or succeed based on how https://bugs.webkit.org/show_bug.cgi?id=25879 is resolved.  Currently we expect drops to be refused.
+    debug("Dragging a file and a directory onto an element:");
+    draggingPathsShouldResultInFiles(['resources/apple.gif', 'resources/directory-for-dragging'], []);
+
+    debug("Dragging a directory and a file onto an element:")
+    draggingPathsShouldResultInFiles(['resources/directory-for-dragging', 'resources/apple.gif'], []);
+}
+
+if (window.eventSender) {
+    runTest();
+    // Clean up after ourselves
+    dragTarget.parentNode.removeChild(dragTarget);
+} else {
+    testFailed("This test is not interactive, please run using DumpRenderTree");
+}
+
+var successfullyParsed = true;
diff --git a/LayoutTests/http/tests/security/clipboard/resources/mozilla.gif b/LayoutTests/http/tests/security/clipboard/resources/mozilla.gif
new file mode 100644 (file)
index 0000000..509b30e
Binary files /dev/null and b/LayoutTests/http/tests/security/clipboard/resources/mozilla.gif differ
index f3a54e1..fa6ff03 100644 (file)
@@ -1,3 +1,65 @@
+2009-05-21  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Maciej Stachowiak.
+
+        Expose files in the clipboard in ondrop events
+        https://bugs.webkit.org/show_bug.cgi?id=25916
+
+        Make it possible for applications like gmail to implement
+        drag and drop of attachments onto email messages.
+
+        This patch exposes an event.dataTransfer.files accessor
+        on the drop event.  No information is exposed during dragover.
+        This follows the HTML 5 drag and drop security model:
+        http://www.w3.org/TR/html5/editing.html#security-risks-in-the-drag-and-drop-model
+        The test http/tests/security/clipboard/clipboard-file-access.html
+        verifies this behavior.
+
+        Internet Explorer shows historical documentation of supporting
+        getData('File') as a way of exposing files on the pasteboard.  The current version of their docs:
+        http://msdn.microsoft.com/en-us/library/ms537658(VS.85).aspx
+        has removed this reference (as far as I can tell IE never implemented it)
+        I have a printed copy of that URL from 2008 on my desk describing getData('File') in IE.
+        IE does not follow the HTML5 clipboard security model and always allows access to the full clipboard, even on dragover.
+
+        I choose not to use IE's getData('File') and instead added .files
+        so that the accessor could have a type, matching WebKit's existing
+        .files accessor on HTMLInputElement.
+
+        Mozilla has equivalent file access:
+        event.dataTransfer.mozGetDataAt("application/x-moz-file", 0);
+        which also does not return a typed value.
+        https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types#Dragging_Files
+
+        This is only implemented for Mac WebKit.  All other platforms (including Apple's Win WebKit)
+        have incomplete Clipboard implementations and will require experts from those platforms
+        to add this functionality.  Right now they all have Clipboard*::files() methods which call notImplemented();
+
+        Test: http/tests/security/clipboard/clipboard-file-access.html
+
+        * dom/Clipboard.h:
+        * dom/Clipboard.idl:
+        * platform/chromium/ClipboardChromium.cpp:
+        (WebCore::ClipboardChromium::files):
+        * platform/chromium/ClipboardChromium.h:
+        * platform/gtk/ClipboardGtk.cpp:
+        (WebCore::ClipboardGtk::files):
+        * platform/gtk/ClipboardGtk.h:
+        * platform/mac/ClipboardMac.h:
+        * platform/mac/ClipboardMac.mm:
+        (WebCore::absoluteURLsFromPasteboardFilenames):
+        (WebCore::absoluteURLsFromPasteboard):
+        (WebCore::ClipboardMac::files):
+        * platform/qt/ClipboardQt.cpp:
+        (WebCore::ClipboardQt::files):
+        * platform/qt/ClipboardQt.h:
+        * platform/win/ClipboardWin.cpp:
+        (WebCore::ClipboardWin::files):
+        * platform/win/ClipboardWin.h:
+        * platform/wx/ClipboardWx.cpp:
+        (WebCore::ClipboardWx::files):
+        * platform/wx/ClipboardWx.h:
+
 2009-06-25  Eric Seidel  <eric@webkit.org>
 
         No review, only completing revert of r45144.
index 7fb1938..0fea604 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace WebCore {
 
+    class FileList;
+
     // State available during IE's events for drag and drop and copy/paste
     class Clipboard : public RefCounted<Clipboard> {
     public:
@@ -53,7 +55,8 @@ namespace WebCore {
     
         // extensions beyond IE's API
         virtual HashSet<String> types() const = 0;
-    
+        virtual PassRefPtr<FileList> files() const = 0;
+
         IntPoint dragLocation() const { return m_dragLoc; }
         CachedImage* dragImage() const { return m_dragImage.get(); }
         virtual void setDragImage(CachedImage*, const IntPoint&) = 0;
index 6fe83f7..dc8677e 100644 (file)
@@ -34,6 +34,7 @@ module core {
                  attribute [ConvertNullStringTo=Undefined] DOMString dropEffect;
                  attribute [ConvertNullStringTo=Undefined] DOMString effectAllowed;
         readonly attribute [CustomGetter] Array types;
+        readonly attribute FileList files;
 
         [Custom] void clearData(in [Optional] DOMString type)
             raises(DOMException);
index 8f9ac7f..5355199 100644 (file)
@@ -175,6 +175,12 @@ HashSet<String> ClipboardChromium::types() const
     return results;
 }
 
+PassRefPtr<FileList> ClipboardChromium::files() const
+{
+    notImplemented();
+    return 0;
+}
+
 void ClipboardChromium::setDragImage(CachedImage* image, Node* node, const IntPoint& loc)
 {
     if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
index 0a83fd4..cf2f046 100644 (file)
@@ -59,7 +59,8 @@ namespace WebCore {
         bool setData(const String& type, const String& data);
 
         // extensions beyond IE's API
-        HashSet<String> types() const;
+        virtual HashSet<String> types() const;
+        virtual PassRefPtr<FileList> files() const;
 
         void setDragImage(CachedImage*, const IntPoint&);
         void setDragImageElement(Node*, const IntPoint&);
index 44aa7f7..83ce825 100644 (file)
@@ -69,6 +69,12 @@ HashSet<String> ClipboardGtk::types() const
     return HashSet<String>();
 }
 
+PassRefPtr<FileList> ClipboardGtk::files() const
+{
+    notImplemented();
+    return 0;
+}
+
 IntPoint ClipboardGtk::dragLocation() const
 {
     notImplemented();
index b8b4ddf..7314ae4 100644 (file)
@@ -47,7 +47,9 @@ namespace WebCore {
         String getData(const String&, bool&) const;
         bool setData(const String&, const String&);
 
-        HashSet<String> types() const;
+        virtual HashSet<String> types() const;
+        virtual PassRefPtr<FileList> files() const;
+
         IntPoint dragLocation() const;
         CachedImage* dragImage() const;
         void setDragImage(CachedImage*, const IntPoint&);
index db6ecb6..9bdd276 100644 (file)
@@ -41,6 +41,7 @@ class NSPasteboard;
 namespace WebCore {
 
 class Frame;
+class FileList;
 
 class ClipboardMac : public Clipboard, public CachedResourceClient {
 public:
@@ -60,6 +61,7 @@ public:
     
     // extensions beyond IE's API
     virtual HashSet<String> types() const;
+    virtual PassRefPtr<FileList> files() const;
 
     void setDragImage(CachedImage*, const IntPoint&);
     void setDragImageElement(Node *, const IntPoint&);
index d1b66a7..52bc952 100644 (file)
@@ -31,6 +31,7 @@
 #import "DragController.h"
 #import "Editor.h"
 #import "FoundationExtras.h"
+#import "FileList.h"
 #import "Frame.h"
 #import "Image.h"
 #import "Page.h"
@@ -139,7 +140,7 @@ void ClipboardMac::clearAllData()
     [m_pasteboard.get() declareTypes:[NSArray array] owner:nil];
 }
 
-static NSArray *absoluteURLsFromPasteboardFilenames(NSPasteboard* pasteboard, bool onlyFirstURL)
+static NSArray *absoluteURLsFromPasteboardFilenames(NSPasteboard* pasteboard, bool onlyFirstURL = false)
 {
     NSArray *fileList = [pasteboard propertyListForType:NSFilenamesPboardType];
 
@@ -163,7 +164,7 @@ static NSArray *absoluteURLsFromPasteboardFilenames(NSPasteboard* pasteboard, bo
     return urls;
 }
 
-static NSArray *absoluteURLsFromPasteboard(NSPasteboard* pasteboard, bool onlyFirstURL)
+static NSArray *absoluteURLsFromPasteboard(NSPasteboard* pasteboard, bool onlyFirstURL = false)
 {
     // NOTE: We must always check [availableTypes containsObject:] before accessing pasteboard data
     // or CoreFoundation will printf when there is not data of the corresponding type.
@@ -274,6 +275,26 @@ HashSet<String> ClipboardMac::types() const
     return result;
 }
 
+// FIXME: We could cache the computed fileList if necessary
+// Currently each access gets a new copy, setData() modifications to the
+// clipboard are not reflected in any FileList objects the page has accessed and stored
+PassRefPtr<FileList> ClipboardMac::files() const
+{
+    if (policy() != ClipboardReadable)
+        return FileList::create();
+
+    NSArray *absoluteURLs = absoluteURLsFromPasteboard(m_pasteboard.get());
+    NSUInteger count = [absoluteURLs count];
+
+    RefPtr<FileList> fileList = FileList::create();
+    for (NSUInteger x = 0; x < count; x++) {
+        NSURL *absoluteURL = [NSURL URLWithString:[absoluteURLs objectAtIndex:x]];
+        ASSERT([absoluteURL isFileURL]);
+        fileList->append(File::create([absoluteURL path]));
+    }
+    return fileList.release(); // We will always return a FileList, sometimes empty
+}
+
 // The rest of these getters don't really have any impact on security, so for now make no checks
 
 void ClipboardMac::setDragImage(CachedImage* img, const IntPoint &loc)
index 9c49594..0027a16 100644 (file)
@@ -178,6 +178,12 @@ HashSet<String> ClipboardQt::types() const
     return result;
 }
 
+PassRefPtr<FileList> ClipboardQt::files() const
+{
+    notImplemented();
+    return 0;
+}
+
 void ClipboardQt::setDragImage(CachedImage* image, const IntPoint& point) 
 {
     setDragImage(image, 0, point);
index caf040f..44324f2 100644 (file)
@@ -56,8 +56,9 @@ namespace WebCore {
         bool setData(const String& type, const String& data);
     
         // extensions beyond IE's API
-        HashSet<String> types() const;
-    
+        virtual HashSet<String> types() const;
+        virtual PassRefPtr<FileList> files() const;
+
         void setDragImage(CachedImage*, const IntPoint&);
         void setDragImageElement(Node*, const IntPoint&);
 
index 3547988..d756c46 100644 (file)
@@ -580,6 +580,12 @@ HashSet<String> ClipboardWin::types() const
     return results;
 }
 
+PassRefPtr<FileList> ClipboardWin::files() const
+{
+    notImplemented();
+    return 0;
+}
+
 void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
 {
     if (policy() != ClipboardImageWritable && policy() != ClipboardWritable) 
index ea1896e..6e60254 100644 (file)
@@ -57,7 +57,8 @@ namespace WebCore {
         bool setData(const String& type, const String& data);
     
         // extensions beyond IE's API
-        HashSet<String> types() const;
+        virtual HashSet<String> types() const;
+        virtual PassRefPtr<FileList> files() const;
     
         void setDragImage(CachedImage*, const IntPoint&);
         void setDragImageElement(Node*, const IntPoint&);
index 461cc66..220c7b5 100644 (file)
@@ -70,6 +70,12 @@ HashSet<String> ClipboardWx::types() const
     return result;
 }
 
+PassRefPtr<FileList> ClipboardWx::files() const
+{
+    notImplemented();
+    return 0;
+}
+
 IntPoint ClipboardWx::dragLocation() const 
 { 
     notImplemented();
index db5f7a8..5e3ba86 100644 (file)
@@ -46,7 +46,8 @@ namespace WebCore {
         bool setData(const String& type, const String& data);
     
         // extensions beyond IE's API
-        HashSet<String> types() const;
+        virtual HashSet<String> types() const;
+        virtual PassRefPtr<FileList> files() const;
     
         IntPoint dragLocation() const;
         CachedImage* dragImage() const;