Changeset 221177 in webkit


Ignore:
Timestamp:
Aug 24, 2017 7:05:54 PM (7 years ago)
Author:
Chris Dumez
Message:

[Directory Upload] Add basic support for input.webkitdirectory
https://bugs.webkit.org/show_bug.cgi?id=175950
<rdar://problem/33951915>

Reviewed by Geoffrey Garen.

Source/WebCore:

Add basic support for input.webkitdirectory attribute, as per:

The following is supported:

  • input.webkitdirectory IDL and content attributes
  • The webkitdirectory content attribute is properly consulted to communicate to the client that the file picker should allow selecting directories.
  • When WebCore gets the list of selected files from the file picker, it properly resolves folders in a background thread to properly initialize input.files before firing the 'change' event at the input element.
  • When resolving files in a directory, we ignore both hidden files and symbolic links for security reasons. I did not check symlinks but Firefox and Chrome both seem to upload hidden files (such as .DS_Store files).
  • File.webkitRelativePath IDL attribute is properly populated for files coming from a selected directory.
  • Form submission just works because it relies on input.files being properly populated. No change needed in this area.

What is not supported:

  • input.webkitEntries IDL attribute.
  • FileSystemEntry / FileSystemDirectoryEntry / FileSystemDirectoryReader / FileSystemFileEntry / FileSystem IDL interfaces.
  • dataTransferItem.webkitGetAsEntry() for proper drag and drop support.

Those will be taken care of in follow-up patches.

The feature is currently behind an experimental feature flag, disabled by
default.

Tests: fast/forms/file/webkitdirectory-drag-folder.html

fast/forms/file/webkitdirectory-open-panel.html

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • fileapi/File.cpp:

(WebCore::File::createWithRelativePath):

  • fileapi/File.h:
  • fileapi/File.idl:
  • html/FileInputType.cpp:

(WebCore::FileInputType::~FileInputType):
(WebCore::FileInputType::handleDOMActivateEvent):
(WebCore::FileInputType::allowsDirectories const):
(WebCore::FileInputType::filesChosen):

  • html/FileInputType.h:
  • html/FileListCreator.cpp: Added.

(WebCore::appendDirectoryFiles):
(WebCore::FileListCreator::FileListCreator):
(WebCore::FileListCreator::createFileList):
(WebCore::FileListCreator::cancel):

  • html/FileListCreator.h: Copied from Source/WebKit/UIProcess/API/APIOpenPanelParameters.h.

(WebCore::FileListCreator::create):

  • html/HTMLAttributeNames.in:
  • html/HTMLInputElement.idl:
  • page/Settings.in:
  • platform/FileChooser.h:

(WebCore::FileChooserFileInfo::isolatedCopy const):

  • platform/FileMetadata.h:
  • platform/FileSystem.cpp:

(WebCore::fileIsDirectory):

  • platform/FileSystem.h:
  • platform/glib/FileSystemGlib.cpp:

(WebCore::getFileMetadata):

  • platform/posix/FileSystemPOSIX.cpp:

(WebCore::getFileMetadata):

  • platform/win/FileSystemWin.cpp:

(WebCore::getFileMetadata):

Source/WebKit:

Add private API to toggle Directory Upload support.

Add new member to WKOpenPanelParameters to communicate to the
client that the file picker should allow selecting directories.

  • Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<FileChooserSettings>::encode):
(IPC::ArgumentCoder<FileChooserSettings>::decode):

  • Shared/WebPreferencesDefinitions.h:
  • UIProcess/API/APIOpenPanelParameters.h:

(API::OpenPanelParameters::allowDirectories const):

  • UIProcess/API/C/WKOpenPanelParametersRef.cpp:

(WKOpenPanelParametersGetAllowsDirectories):

  • UIProcess/API/C/WKOpenPanelParametersRef.h:
  • UIProcess/API/C/WKPreferences.cpp:

(WKPreferencesSetDirectoryUploadEnabled):
(WKPreferencesGetDirectoryUploadEnabled):

  • UIProcess/API/C/WKPreferencesRefPrivate.h:
  • UIProcess/API/Cocoa/WKOpenPanelParameters.h:
  • UIProcess/API/Cocoa/WKOpenPanelParameters.mm:

(-[WKOpenPanelParameters allowsDirectories]):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::updatePreferences):

Source/WebKitLegacy/mac:

Add private API to toggle Directory Upload support on Mac WebKit1.

  • WebView/WebPreferenceKeysPrivate.h:
  • WebView/WebPreferences.mm:

(+[WebPreferences initialize]):
(-[WebPreferences setDirectoryUploadEnabled:]):
(-[WebPreferences directoryUploadEnabled]):

  • WebView/WebPreferencesPrivate.h:
  • WebView/WebView.mm:

(-[WebView _preferencesChanged:]):

Tools:

  • DumpRenderTree/mac/DumpRenderTree.mm:

(resetWebPreferencesToConsistentValues):

  • WebKitTestRunner/TestController.cpp:

(WTR::TestController::resetPreferencesToConsistentValues):
Enable Directory Upload feature for testing, given that it is currently disabled by default.

(WTR::runOpenPanel):
Print additional text when directories are allowed to extend testing coverage.

LayoutTests:

Add layout test coverage for input.webkitdirectory. It covers both
the file picker and the drag and drop code paths.

  • fast/forms/file/resources/testFiles/file1.txt: Added.
  • fast/forms/file/resources/testFiles/file2.txt: Added.
  • fast/forms/file/resources/testFiles/subfolder1/file3.txt: Added.
  • fast/forms/file/resources/testFiles/subfolder2/file4.txt: Added.
  • fast/forms/file/resources/testFiles/subfolder2/subfolder2a/file5.txt: Added.
  • fast/forms/file/webkitdirectory-drag-folder-expected.txt: Added.
  • fast/forms/file/webkitdirectory-drag-folder.html: Added.
  • fast/forms/file/webkitdirectory-open-panel-expected.txt: Added.
  • fast/forms/file/webkitdirectory-open-panel.html: Added.
  • platform/mac-wk1/fast/forms/file/webkitdirectory-open-panel-expected.txt: Added.
  • platform/wk2/TestExpectations:
Location:
trunk
Files:
17 added
39 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r221173 r221177  
     12017-08-24  Chris Dumez  <cdumez@apple.com>
     2
     3        [Directory Upload] Add basic support for input.webkitdirectory
     4        https://bugs.webkit.org/show_bug.cgi?id=175950
     5        <rdar://problem/33951915>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add layout test coverage for input.webkitdirectory. It covers both
     10        the file picker and the drag and drop code paths.
     11
     12        * fast/forms/file/resources/testFiles/file1.txt: Added.
     13        * fast/forms/file/resources/testFiles/file2.txt: Added.
     14        * fast/forms/file/resources/testFiles/subfolder1/file3.txt: Added.
     15        * fast/forms/file/resources/testFiles/subfolder2/file4.txt: Added.
     16        * fast/forms/file/resources/testFiles/subfolder2/subfolder2a/file5.txt: Added.
     17        * fast/forms/file/webkitdirectory-drag-folder-expected.txt: Added.
     18        * fast/forms/file/webkitdirectory-drag-folder.html: Added.
     19        * fast/forms/file/webkitdirectory-open-panel-expected.txt: Added.
     20        * fast/forms/file/webkitdirectory-open-panel.html: Added.
     21        * platform/mac-wk1/fast/forms/file/webkitdirectory-open-panel-expected.txt: Added.
     22        * platform/wk2/TestExpectations:
     23
    1242017-08-24  Ryan Haddad  <ryanhaddad@apple.com>
    225
  • trunk/LayoutTests/platform/wk2/TestExpectations

    r221101 r221177  
    604604fast/forms/file/recover-file-input-in-unposted-form.html
    605605fast/forms/file/selected-files-from-history-state.html
     606fast/forms/file/webkitdirectory-drag-folder.html
    606607fast/history/page-cache-createObjectURL.html
    607608fast/workers/worker-copy-shared-blob-url.html
  • trunk/Source/WebCore/CMakeLists.txt

    r221135 r221177  
    17401740    html/EmailInputType.cpp
    17411741    html/FTPDirectoryDocument.cpp
     1742    html/FileListCreator.cpp
    17421743    html/FileInputType.cpp
    17431744    html/FormAssociatedElement.cpp
  • trunk/Source/WebCore/ChangeLog

    r221173 r221177  
     12017-08-24  Chris Dumez  <cdumez@apple.com>
     2
     3        [Directory Upload] Add basic support for input.webkitdirectory
     4        https://bugs.webkit.org/show_bug.cgi?id=175950
     5        <rdar://problem/33951915>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add basic support for input.webkitdirectory attribute, as per:
     10        - https://wicg.github.io/entries-api/#html-forms
     11
     12        The following is supported:
     13        - input.webkitdirectory IDL and content attributes
     14        - The webkitdirectory content attribute is properly consulted
     15          to communicate to the client that the file picker should
     16          allow selecting directories.
     17        - When WebCore gets the list of selected files from the file picker,
     18          it properly resolves folders in a background thread to properly
     19          initialize input.files before firing the 'change' event at the
     20          input element.
     21        - When resolving files in a directory, we ignore both hidden files and
     22          symbolic links for security reasons. I did not check symlinks but Firefox
     23          and Chrome both seem to upload hidden files (such as .DS_Store files).
     24        - File.webkitRelativePath IDL attribute is properly populated for
     25          files coming from a selected directory.
     26        - Form submission just works because it relies on input.files being
     27          properly populated. No change needed in this area.
     28
     29        What is not supported:
     30        - input.webkitEntries IDL attribute.
     31        - FileSystemEntry / FileSystemDirectoryEntry / FileSystemDirectoryReader
     32          /  FileSystemFileEntry / FileSystem IDL interfaces.
     33        - dataTransferItem.webkitGetAsEntry() for proper drag and drop support.
     34
     35        Those will be taken care of in follow-up patches.
     36
     37        The feature is currently behind an experimental feature flag, disabled by
     38        default.
     39
     40        Tests: fast/forms/file/webkitdirectory-drag-folder.html
     41               fast/forms/file/webkitdirectory-open-panel.html
     42
     43        * CMakeLists.txt:
     44        * WebCore.xcodeproj/project.pbxproj:
     45        * fileapi/File.cpp:
     46        (WebCore::File::createWithRelativePath):
     47        * fileapi/File.h:
     48        * fileapi/File.idl:
     49        * html/FileInputType.cpp:
     50        (WebCore::FileInputType::~FileInputType):
     51        (WebCore::FileInputType::handleDOMActivateEvent):
     52        (WebCore::FileInputType::allowsDirectories const):
     53        (WebCore::FileInputType::filesChosen):
     54        * html/FileInputType.h:
     55        * html/FileListCreator.cpp: Added.
     56        (WebCore::appendDirectoryFiles):
     57        (WebCore::FileListCreator::FileListCreator):
     58        (WebCore::FileListCreator::createFileList):
     59        (WebCore::FileListCreator::cancel):
     60        * html/FileListCreator.h: Copied from Source/WebKit/UIProcess/API/APIOpenPanelParameters.h.
     61        (WebCore::FileListCreator::create):
     62        * html/HTMLAttributeNames.in:
     63        * html/HTMLInputElement.idl:
     64        * page/Settings.in:
     65        * platform/FileChooser.h:
     66        (WebCore::FileChooserFileInfo::isolatedCopy const):
     67        * platform/FileMetadata.h:
     68        * platform/FileSystem.cpp:
     69        (WebCore::fileIsDirectory):
     70        * platform/FileSystem.h:
     71        * platform/glib/FileSystemGlib.cpp:
     72        (WebCore::getFileMetadata):
     73        * platform/posix/FileSystemPOSIX.cpp:
     74        (WebCore::getFileMetadata):
     75        * platform/win/FileSystemWin.cpp:
     76        (WebCore::getFileMetadata):
     77
    1782017-08-24  Ryan Haddad  <ryanhaddad@apple.com>
    279
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r221112 r221177  
    34263426                8358CB701C53277500E0C2D8 /* JSXMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F570AD1C53268E007FD6CB /* JSXMLDocument.h */; };
    34273427                835D363719FF6193004C93AB /* StyleBuilderCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 835D363619FF6193004C93AB /* StyleBuilderCustom.h */; };
     3428                835D54C41F4DE53800E60671 /* FileListCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 835D54C11F4DE53400E60671 /* FileListCreator.cpp */; };
     3429                835D54C51F4DE53800E60671 /* FileListCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 835D54C21F4DE53400E60671 /* FileListCreator.h */; };
    34283430                8367587E1C56E99B008A1087 /* JSHTMLDataElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 834B86A91C56E93E00F3F0E3 /* JSHTMLDataElement.cpp */; };
    34293431                8367587F1C56E99B008A1087 /* JSHTMLDataElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B86A81C56E93E00F3F0E3 /* JSHTMLDataElement.h */; };
     
    1154811550                835657C61ECAB0E800CDE72D /* JSDOMMatrixInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMMatrixInit.cpp; sourceTree = "<group>"; };
    1154911551                835D363619FF6193004C93AB /* StyleBuilderCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilderCustom.h; sourceTree = "<group>"; };
     11552                835D54C11F4DE53400E60671 /* FileListCreator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileListCreator.cpp; sourceTree = "<group>"; };
     11553                835D54C21F4DE53400E60671 /* FileListCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileListCreator.h; sourceTree = "<group>"; };
    1155011554                835F8B261D2D90BA00E408EC /* Slotable.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Slotable.idl; sourceTree = "<group>"; };
    1155111555                8369E58F1AFDD0300087DF68 /* NonDocumentTypeChildNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = NonDocumentTypeChildNode.idl; sourceTree = "<group>"; };
     
    2029020294                                F55B3D891251F12D003EF269 /* FileInputType.cpp */,
    2029120295                                F55B3D8A1251F12D003EF269 /* FileInputType.h */,
     20296                                835D54C11F4DE53400E60671 /* FileListCreator.cpp */,
     20297                                835D54C21F4DE53400E60671 /* FileListCreator.h */,
    2029220298                                4A0DA2FC129B241900AB61E1 /* FormAssociatedElement.cpp */,
    2029320299                                4A0DA2FD129B241900AB61E1 /* FormAssociatedElement.h */,
     
    2739827404                                F55B3DBE1251F12D003EF269 /* FileInputType.h in Headers */,
    2739927405                                976D6C86122B8A3D001FD1F7 /* FileList.h in Headers */,
     27406                                835D54C51F4DE53800E60671 /* FileListCreator.h in Headers */,
    2740027407                                4689F1AF1267BAE100E8D380 /* FileMetadata.h in Headers */,
    2740127408                                7A09CEF11F02069B00E93BDB /* FileMonitor.h in Headers */,
     
    3139531402                                F55B3DBD1251F12D003EF269 /* FileInputType.cpp in Sources */,
    3139631403                                976D6C85122B8A3D001FD1F7 /* FileList.cpp in Sources */,
     31404                                835D54C41F4DE53800E60671 /* FileListCreator.cpp in Sources */,
    3139731405                                7A32D7481F020EFF00162C44 /* FileMonitor.cpp in Sources */,
    3139831406                                7A32D7471F020EED00162C44 /* FileMonitorCocoa.mm in Sources */,
  • trunk/Source/WebCore/fileapi/File.cpp

    r209184 r221177  
    3737
    3838namespace WebCore {
     39
     40Ref<File> File::createWithRelativePath(const String& path, const String& relativePath)
     41{
     42    auto file = File::create(path);
     43    file->setRelativePath(relativePath);
     44    return file;
     45}
    3946
    4047File::File(const String& path)
  • trunk/Source/WebCore/fileapi/File.h

    r209184 r221177  
    6666    }
    6767
     68    static Ref<File> createWithRelativePath(const String& path, const String& relativePath);
     69
    6870    bool isFile() const override { return true; }
    6971
    7072    const String& path() const { return m_path; }
     73    const String& relativePath() const { return m_relativePath; }
     74    void setRelativePath(const String& relativePath) { m_relativePath = relativePath; }
    7175    const String& name() const { return m_name; }
    7276    WEBCORE_EXPORT double lastModified() const;
     
    9195
    9296    String m_path;
     97    String m_relativePath;
    9398    String m_name;
    9499
  • trunk/Source/WebCore/fileapi/File.idl

    r218495 r221177  
    3636    readonly attribute DOMString name;
    3737    readonly attribute long long lastModified;
     38
     39    // https://wicg.github.io/entries-api/#file-interface
     40    [EnabledAtRuntime=DirectoryUpload, ImplementedAs=relativePath] readonly attribute USVString webkitRelativePath;
    3841};
    3942
  • trunk/Source/WebCore/html/FileInputType.cpp

    r215385 r221177  
    2929#include "File.h"
    3030#include "FileList.h"
     31#include "FileListCreator.h"
    3132#include "FileSystem.h"
    3233#include "FormController.h"
     
    3940#include "LocalizedStrings.h"
    4041#include "RenderFileUploadControl.h"
     42#include "RuntimeEnabledFeatures.h"
    4143#include "ScriptController.h"
     44#include "Settings.h"
    4245#include "ShadowRoot.h"
    4346#include <wtf/TypeCasts.h>
     
    98101FileInputType::~FileInputType()
    99102{
     103    if (m_fileListCreator)
     104        m_fileListCreator->cancel();
     105
    100106    if (m_fileChooser)
    101107        m_fileChooser->invalidate();
     
    192198        FileChooserSettings settings;
    193199        HTMLInputElement& input = element();
     200        settings.allowsDirectories = allowsDirectories();
    194201        settings.allowsMultipleFiles = input.hasAttributeWithoutSynchronization(multipleAttr);
    195202        settings.acceptMIMETypes = input.acceptMIMETypes();
     
    255262}
    256263
    257 Ref<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files)
    258 {
    259     Vector<RefPtr<File>> fileObjects;
    260     fileObjects.reserveInitialCapacity(files.size());
    261     for (auto& info : files)
    262         fileObjects.uncheckedAppend(File::createWithName(info.path, info.displayName));
    263     return FileList::create(WTFMove(fileObjects));
    264 }
    265 
    266264bool FileInputType::isFileUpload() const
    267265{
     
    327325
    328326    m_fileChooser = FileChooser::create(this, settings);
     327}
     328
     329bool FileInputType::allowsDirectories() const
     330{
     331    if (!RuntimeEnabledFeatures::sharedFeatures().directoryUploadEnabled())
     332        return false;
     333    return element().hasAttributeWithoutSynchronization(webkitdirectoryAttr);
    329334}
    330335
     
    384389        m_displayString = displayString;
    385390
    386     setFiles(createFileList(paths), icon ? RequestIcon::No : RequestIcon::Yes);
     391    if (m_fileListCreator)
     392        m_fileListCreator->cancel();
     393
     394    auto shouldResolveDirectories = allowsDirectories() ? FileListCreator::ShouldResolveDirectories::Yes : FileListCreator::ShouldResolveDirectories::No;
     395    auto shouldRequestIcon = icon ? RequestIcon::Yes : RequestIcon::No;
     396    m_fileListCreator = FileListCreator::create(paths, shouldResolveDirectories, [this, shouldRequestIcon](Ref<FileList>&& fileList) {
     397        setFiles(WTFMove(fileList), shouldRequestIcon);
     398        m_fileListCreator = nullptr;
     399    });
    387400
    388401    if (icon)
  • trunk/Source/WebCore/html/FileInputType.h

    r215385 r221177  
    4141class DragData;
    4242class FileList;
     43class FileListCreator;
    4344class Icon;
    4445
     
    8586    void iconLoaded(RefPtr<Icon>&&) final;
    8687
    87     static Ref<FileList> createFileList(const Vector<FileChooserFileInfo>&);
    8888    void requestIcon(const Vector<String>&);
    8989
    9090    void applyFileChooserSettings(const FileChooserSettings&);
     91
     92    bool allowsDirectories() const;
    9193
    9294    RefPtr<FileChooser> m_fileChooser;
     
    9496
    9597    Ref<FileList> m_fileList;
     98    RefPtr<FileListCreator> m_fileListCreator;
    9699    RefPtr<Icon> m_icon;
    97100    String m_displayString;
  • trunk/Source/WebCore/html/FileListCreator.h

    r221176 r221177  
    11/*
    2  * Copyright (C) 2010 Apple Inc. All rights reserved.
    3  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
     2 * Copyright (C) 2017 Apple Inc. All rights reserved.
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    2726#pragma once
    2827
    29 #include "APIObject.h"
    30 #include <WebCore/FileChooser.h>
     28#include <wtf/Function.h>
     29#include <wtf/Ref.h>
     30#include <wtf/ThreadSafeRefCounted.h>
     31#include <wtf/Vector.h>
     32#include <wtf/WorkQueue.h>
    3133
    32 namespace API {
     34namespace WebCore {
    3335
    34 class Array;
     36struct FileChooserFileInfo;
     37class FileList;
    3538
    36 class OpenPanelParameters : public API::ObjectImpl<API::Object::Type::OpenPanelParameters> {
     39class FileListCreator : public ThreadSafeRefCounted<FileListCreator> {
    3740public:
    38     static Ref<OpenPanelParameters> create(const WebCore::FileChooserSettings&);
    39     ~OpenPanelParameters();
     41    using CompletionHandler = WTF::Function<void(Ref<FileList>&&)>;
    4042
    41     bool allowMultipleFiles() const { return m_settings.allowsMultipleFiles; }
    42     Ref<API::Array> acceptMIMETypes() const;
    43     Ref<API::Array> acceptFileExtensions() const;
    44     Ref<API::Array> selectedFileNames() const;
    45 #if ENABLE(MEDIA_CAPTURE)
    46     WebCore::MediaCaptureType mediaCaptureType() const;
    47 #endif
     43    enum class ShouldResolveDirectories { No, Yes };
     44    static Ref<FileListCreator> create(const Vector<FileChooserFileInfo>& paths, ShouldResolveDirectories shouldResolveDirectories, CompletionHandler&& completionHandler)
     45    {
     46        return adoptRef(*new FileListCreator(paths, shouldResolveDirectories, WTFMove(completionHandler)));
     47    }
     48
     49    ~FileListCreator();
     50
     51    void cancel();
    4852
    4953private:
    50     explicit OpenPanelParameters(const WebCore::FileChooserSettings&);
     54    FileListCreator(const Vector<FileChooserFileInfo>& paths, ShouldResolveDirectories, CompletionHandler&&);
    5155
    52     WebCore::FileChooserSettings m_settings;
     56    template<ShouldResolveDirectories shouldResolveDirectories>
     57    static Ref<FileList> createFileList(const Vector<FileChooserFileInfo>&);
     58
     59    RefPtr<WorkQueue> m_workQueue;
     60    CompletionHandler m_completionHander;
    5361};
    5462
    55 } // namespace API
     63}
  • trunk/Source/WebCore/html/HTMLAttributeNames.in

    r218809 r221177  
    382382webkitallowfullscreen
    383383webkitattachmentpath
     384webkitdirectory
    384385width
    385386wrap
  • trunk/Source/WebCore/html/HTMLInputElement.idl

    r215330 r221177  
    9393    // See http://www.w3.org/TR/html-media-capture/
    9494    [Conditional=MEDIA_CAPTURE, Reflect] attribute DOMString capture;
     95
     96    // https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory
     97    [Reflect, EnabledAtRuntime=DirectoryUpload] attribute boolean webkitdirectory;
     98    // In Chrome & Firefox, webkitEntries is only populated if webkitdirectory is not set and the files were
     99    // dragged and dropped (not when the element is clicked).
     100    // [EnabledAtRuntime=DirectoryUpload] readonly attribute FrozenArray<FileSystemEntry> webkitEntries;
    95101};
  • trunk/Source/WebCore/page/RuntimeEnabledFeatures.h

    r220627 r221177  
    7474    bool customElementsEnabled() const { return m_areCustomElementsEnabled; }
    7575
     76    void setDirectoryUploadEnabled(bool isEnabled) { m_isDirectoryUploadEnabled = isEnabled; }
     77    bool directoryUploadEnabled() const { return m_isDirectoryUploadEnabled; }
     78
    7679    void setDataTransferItemsEnabled(bool areEnabled) { m_areDataTransferItemsEnabled = areEnabled; }
    7780    bool dataTransferItemsEnabled() const { return m_areDataTransferItemsEnabled; }
     
    232235    bool m_isShadowDOMEnabled { true };
    233236    bool m_areCustomElementsEnabled { true };
     237    bool m_isDirectoryUploadEnabled { false };
    234238    bool m_areDataTransferItemsEnabled { false };
    235239    bool m_inputEventsEnabled { true };
  • trunk/Source/WebCore/platform/FileChooser.h

    r220135 r221177  
    5353    }
    5454
     55    FileChooserFileInfo isolatedCopy() const
     56    {
     57        return { path.isolatedCopy(), displayName.isolatedCopy() };
     58    }
     59
    5560    const String path;
    5661    const String displayName;
     
    5863
    5964struct FileChooserSettings {
    60     bool allowsMultipleFiles;
     65    bool allowsDirectories { false };
     66    bool allowsMultipleFiles { false };
    6167    Vector<String> acceptMIMETypes;
    6268    Vector<String> acceptFileExtensions;
    6369    Vector<String> selectedFiles;
    6470#if ENABLE(MEDIA_CAPTURE)
    65     MediaCaptureType mediaCaptureType;
     71    MediaCaptureType mediaCaptureType { MediaCaptureTypeNone };
    6672#endif
    6773};
  • trunk/Source/WebCore/platform/FileMetadata.h

    r156692 r221177  
    3838
    3939struct FileMetadata {
     40    FileMetadata() = default;
     41
    4042    // The last modification time of the file, in seconds.
    4143    // The value 0.0 means that the time is not set.
    42     double modificationTime;
     44    double modificationTime { invalidFileTime() };
    4345
    4446    // The length of the file in bytes.
    4547    // The value -1 means that the length is not set.
    46     long long length;
     48    long long length { -1 };
    4749
    48     enum Type {
    49         TypeUnknown = 0,
    50         TypeFile,
    51         TypeDirectory
    52     };
     50    bool isHidden { false };
    5351
    54     Type type;
    55 
    56     FileMetadata() : modificationTime(invalidFileTime()), length(-1), type(TypeUnknown) { }
     52    enum Type { TypeUnknown, TypeFile, TypeDirectory, TypeSymbolicLink };
     53    Type type { TypeUnknown };
    5754};
    5855
  • trunk/Source/WebCore/platform/FileSystem.cpp

    r219297 r221177  
    2828#include "FileSystem.h"
    2929
     30#include "FileMetadata.h"
    3031#include "ScopeGuard.h"
    3132#include <wtf/HexNumber.h>
     
    351352}
    352353
     354bool fileIsDirectory(const String& path)
     355{
     356    FileMetadata metadata;
     357    if (!getFileMetadata(path, metadata))
     358        return false;
     359    return metadata.type == FileMetadata::TypeDirectory;
     360}
     361
    353362} // namespace WebCore
  • trunk/Source/WebCore/platform/FileSystem.h

    r219297 r221177  
    100100WEBCORE_EXPORT bool getFileCreationTime(const String&, time_t& result); // Not all platforms store file creation time.
    101101bool getFileMetadata(const String&, FileMetadata&);
     102bool fileIsDirectory(const String&);
    102103WEBCORE_EXPORT String pathByAppendingComponent(const String& path, const String& component);
    103104String lastComponentOfPathIgnoringTrailingSlash(const String& path);
  • trunk/Source/WebCore/platform/glib/FileSystemGlib.cpp

    r219384 r221177  
    161161        return false;
    162162
     163    String filename = pathGetFileName(path);
     164    metadata.isHidden = !filename.isEmpty() && filename[0] == '.';
    163165    metadata.modificationTime = statResult.st_mtime;
    164166    metadata.length = statResult.st_size;
    165     metadata.type = S_ISDIR(statResult.st_mode) ? FileMetadata::TypeDirectory : FileMetadata::TypeFile;
     167    if (S_ISDIR(statResult.st_mode))
     168        metadata.type = FileMetadata::TypeDirectory;
     169    else if (S_ISLNK(statResult.st_mode))
     170        metadata.type = FileMetadata::TypeSymbolicLink;
     171    else
     172        metadata.type = FileMetadata::TypeFile;
    166173    return true;
    167174}
  • trunk/Source/WebCore/platform/posix/FileSystemPOSIX.cpp

    r218901 r221177  
    250250        return false;
    251251
     252    String filename = pathGetFileName(path);
     253
    252254    metadata.modificationTime = fileInfo.st_mtime;
     255    metadata.isHidden = !filename.isEmpty() && filename[0] == '.';
    253256    metadata.length = fileInfo.st_size;
    254     metadata.type = S_ISDIR(fileInfo.st_mode) ? FileMetadata::TypeDirectory : FileMetadata::TypeFile;
     257    if (S_ISDIR(fileInfo.st_mode))
     258        metadata.type = FileMetadata::TypeDirectory;
     259    else if (S_ISLNK(fileInfo.st_mode))
     260        metadata.type = FileMetadata::TypeSymbolicLink;
     261    else
     262        metadata.type = FileMetadata::TypeFile;
    255263    return true;
    256264}
  • trunk/Source/WebCore/platform/win/FileSystemWin.cpp

    r219858 r221177  
    153153    getFileModificationTimeFromFindData(findData, modificationTime);
    154154    metadata.modificationTime = modificationTime;
    155 
     155    metadata.isHidden = findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN;
    156156    metadata.type = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FileMetadata::TypeDirectory : FileMetadata::TypeFile;
    157157
  • trunk/Source/WebKit/ChangeLog

    r221175 r221177  
     12017-08-24  Chris Dumez  <cdumez@apple.com>
     2
     3        [Directory Upload] Add basic support for input.webkitdirectory
     4        https://bugs.webkit.org/show_bug.cgi?id=175950
     5        <rdar://problem/33951915>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add private API to toggle Directory Upload support.
     10
     11        Add new member to WKOpenPanelParameters to communicate to the
     12        client that the file picker should allow selecting directories.
     13
     14        * Shared/WebCoreArgumentCoders.cpp:
     15        (IPC::ArgumentCoder<FileChooserSettings>::encode):
     16        (IPC::ArgumentCoder<FileChooserSettings>::decode):
     17        * Shared/WebPreferencesDefinitions.h:
     18        * UIProcess/API/APIOpenPanelParameters.h:
     19        (API::OpenPanelParameters::allowDirectories const):
     20        * UIProcess/API/C/WKOpenPanelParametersRef.cpp:
     21        (WKOpenPanelParametersGetAllowsDirectories):
     22        * UIProcess/API/C/WKOpenPanelParametersRef.h:
     23        * UIProcess/API/C/WKPreferences.cpp:
     24        (WKPreferencesSetDirectoryUploadEnabled):
     25        (WKPreferencesGetDirectoryUploadEnabled):
     26        * UIProcess/API/C/WKPreferencesRefPrivate.h:
     27        * UIProcess/API/Cocoa/WKOpenPanelParameters.h:
     28        * UIProcess/API/Cocoa/WKOpenPanelParameters.mm:
     29        (-[WKOpenPanelParameters allowsDirectories]):
     30        * WebProcess/WebPage/WebPage.cpp:
     31        (WebKit::WebPage::updatePreferences):
     32
    1332017-08-24  Youenn Fablet  <youenn@apple.com>
    234
  • trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp

    r221165 r221177  
    17131713void ArgumentCoder<FileChooserSettings>::encode(Encoder& encoder, const FileChooserSettings& settings)
    17141714{
     1715    encoder << settings.allowsDirectories;
    17151716    encoder << settings.allowsMultipleFiles;
    17161717    encoder << settings.acceptMIMETypes;
     
    17241725bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSettings& settings)
    17251726{
     1727    if (!decoder.decode(settings.allowsDirectories))
     1728        return false;
    17261729    if (!decoder.decode(settings.allowsMultipleFiles))
    17271730        return false;
  • trunk/Source/WebKit/Shared/WebPreferencesDefinitions.h

    r221041 r221177  
    376376    macro(WebGL2Enabled, webGL2Enabled, Bool, bool, false, "WebGL 2.0", "WebGL 2 prototype") \
    377377    macro(WebGPUEnabled, webGPUEnabled, Bool, bool, false, "WebGPU", "WebGPU prototype") \
     378    macro(DirectoryUploadEnabled, directoryUploadEnabled, Bool, bool, false, "Directory Upload", "input.webkitdirectory") \
    378379    macro(AsyncFrameScrollingEnabled, asyncFrameScrollingEnabled, Bool, bool, false, "Async Frame Scrolling", "Perform frame scrolling in a dedicated thread or process") \
    379380    \
  • trunk/Source/WebKit/UIProcess/API/APIOpenPanelParameters.h

    r220135 r221177  
    3939    ~OpenPanelParameters();
    4040
     41    bool allowDirectories() const { return m_settings.allowsDirectories; }
    4142    bool allowMultipleFiles() const { return m_settings.allowsMultipleFiles; }
    4243    Ref<API::Array> acceptMIMETypes() const;
  • trunk/Source/WebKit/UIProcess/API/C/WKOpenPanelParametersRef.cpp

    r220135 r221177  
    3939}
    4040
     41bool WKOpenPanelParametersGetAllowsDirectories(WKOpenPanelParametersRef parametersRef)
     42{
     43    return toImpl(parametersRef)->allowDirectories();
     44}
     45
    4146bool WKOpenPanelParametersGetAllowsMultipleFiles(WKOpenPanelParametersRef parametersRef)
    4247{
  • trunk/Source/WebKit/UIProcess/API/C/WKOpenPanelParametersRef.h

    r220135 r221177  
    4040WK_EXPORT WKTypeID WKOpenPanelParametersGetTypeID();
    4141
     42WK_EXPORT bool WKOpenPanelParametersGetAllowsDirectories(WKOpenPanelParametersRef parameters);
    4243WK_EXPORT bool WKOpenPanelParametersGetAllowsMultipleFiles(WKOpenPanelParametersRef parameters);
    4344
  • trunk/Source/WebKit/UIProcess/API/C/WKPreferences.cpp

    r220787 r221177  
    841841}
    842842
     843void WKPreferencesSetDirectoryUploadEnabled(WKPreferencesRef preferencesRef, bool flag)
     844{
     845    toImpl(preferencesRef)->setDirectoryUploadEnabled(flag);
     846}
     847
     848bool WKPreferencesGetDirectoryUploadEnabled(WKPreferencesRef preferencesRef)
     849{
     850    return toImpl(preferencesRef)->directoryUploadEnabled();
     851}
     852
    843853void WKPreferencesSetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef, bool flag)
    844854{
  • trunk/Source/WebKit/UIProcess/API/C/WKPreferencesRefPrivate.h

    r220787 r221177  
    208208WK_EXPORT bool WKPreferencesGetBeaconAPIEnabled(WKPreferencesRef);
    209209
     210// Defaults to false.
     211WK_EXPORT void WKPreferencesSetDirectoryUploadEnabled(WKPreferencesRef, bool flag);
     212WK_EXPORT bool WKPreferencesGetDirectoryUploadEnabled(WKPreferencesRef);
     213
    210214// Defaults to false on iOS, true elsewhere.
    211215WK_EXPORT void WKPreferencesSetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef, bool flag);
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.h

    r205559 r221177  
    4141@property (nonatomic, readonly) BOOL allowsMultipleSelection;
    4242
     43/*! @abstract Whether the file upload control supports selecting directories.
     44 */
     45@property (nonatomic, readonly) BOOL allowsDirectories WK_API_AVAILABLE(macosx(WK_MAC_TBA));
     46
    4347@end
    4448
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKOpenPanelParameters.mm

    r202793 r221177  
    3636}
    3737
     38- (BOOL)allowsDirectories
     39{
     40    return _openPanelParameters->allowDirectories();
     41}
     42
    3843#pragma mark WKObject protocol implementation
    3944
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r221068 r221177  
    33683368    RuntimeEnabledFeatures::sharedFeatures().setCredentialManagementEnabled(store.getBoolValueForKey(WebPreferencesKey::credentialManagementEnabledKey()));
    33693369    RuntimeEnabledFeatures::sharedFeatures().setIsSecureContextAttributeEnabled(store.getBoolValueForKey(WebPreferencesKey::isSecureContextAttributeEnabledKey()));
     3370    RuntimeEnabledFeatures::sharedFeatures().setDirectoryUploadEnabled(store.getBoolValueForKey(WebPreferencesKey::directoryUploadEnabledKey()));
    33703371
    33713372    bool processSuppressionEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r221064 r221177  
     12017-08-24  Chris Dumez  <cdumez@apple.com>
     2
     3        [Directory Upload] Add basic support for input.webkitdirectory
     4        https://bugs.webkit.org/show_bug.cgi?id=175950
     5        <rdar://problem/33951915>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add private API to toggle Directory Upload support on Mac WebKit1.
     10
     11        * WebView/WebPreferenceKeysPrivate.h:
     12        * WebView/WebPreferences.mm:
     13        (+[WebPreferences initialize]):
     14        (-[WebPreferences setDirectoryUploadEnabled:]):
     15        (-[WebPreferences directoryUploadEnabled]):
     16        * WebView/WebPreferencesPrivate.h:
     17        * WebView/WebView.mm:
     18        (-[WebView _preferencesChanged:]):
     19
    1202017-08-22  Wenson Hsieh  <wenson_hsieh@apple.com>
    221
  • trunk/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h

    r220627 r221177  
    177177#define WebKitReadableByteStreamAPIEnabledPreferenceKey @"WebKitReadableByteStreamAPIEnabled"
    178178#define WebKitDownloadAttributeEnabledPreferenceKey @"WebKitDownloadAttributeEnabled"
     179#define WebKitDirectoryUploadEnabledPreferenceKey @"WebKitDirectoryUploadEnabled"
    179180#define WebKitCSSGridLayoutEnabledPreferenceKey @"WebKitCSSGridLayoutEnabled"
    180181#define WebKitVisualViewportEnabledPreferenceKey @"WebKitVisualViewportEnabled"
  • trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm

    r220627 r221177  
    643643        [NSNumber numberWithBool:NO], WebKitDownloadAttributeEnabledPreferenceKey,
    644644#endif
     645        [NSNumber numberWithBool:NO], WebKitDirectoryUploadEnabledPreferenceKey,
    645646        [NSNumber numberWithBool:YES], WebKitCSSGridLayoutEnabledPreferenceKey,
    646647#if ENABLE(WEB_ANIMATIONS)
     
    30363037}
    30373038
     3039- (void)setDirectoryUploadEnabled:(BOOL)flag
     3040{
     3041    [self _setBoolValue:flag forKey:WebKitDirectoryUploadEnabledPreferenceKey];
     3042}
     3043
     3044- (BOOL)directoryUploadEnabled
     3045{
     3046    return [self _boolValueForKey:WebKitDirectoryUploadEnabledPreferenceKey];
     3047}
     3048
    30383049- (BOOL)isCSSGridLayoutEnabled
    30393050{
  • trunk/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h

    r220627 r221177  
    553553- (BOOL)downloadAttributeEnabled;
    554554
     555- (void)setDirectoryUploadEnabled:(BOOL)flag;
     556- (BOOL)directoryUploadEnabled;
     557
    555558- (void)setCSSGridLayoutEnabled:(BOOL)flag;
    556559- (BOOL)isCSSGridLayoutEnabled;
  • trunk/Source/WebKitLegacy/mac/WebView/WebView.mm

    r220979 r221177  
    30343034    RuntimeEnabledFeatures::sharedFeatures().setCredentialManagementEnabled(preferences.credentialManagementEnabled);
    30353035    RuntimeEnabledFeatures::sharedFeatures().setIsSecureContextAttributeEnabled(preferences.isSecureContextAttributeEnabled);
     3036    RuntimeEnabledFeatures::sharedFeatures().setDirectoryUploadEnabled([preferences directoryUploadEnabled]);
    30363037
    30373038#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
  • trunk/Tools/ChangeLog

    r221172 r221177  
     12017-08-24  Chris Dumez  <cdumez@apple.com>
     2
     3        [Directory Upload] Add basic support for input.webkitdirectory
     4        https://bugs.webkit.org/show_bug.cgi?id=175950
     5        <rdar://problem/33951915>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        * DumpRenderTree/mac/DumpRenderTree.mm:
     10        (resetWebPreferencesToConsistentValues):
     11        * WebKitTestRunner/TestController.cpp:
     12        (WTR::TestController::resetPreferencesToConsistentValues):
     13        Enable Directory Upload feature for testing, given that it is currently disabled by default.
     14
     15        (WTR::runOpenPanel):
     16        Print additional text when directories are allowed to extend testing coverage.
     17
    1182017-08-24  Alex Christensen  <achristensen@webkit.org>
    219
  • trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm

    r220627 r221177  
    958958
    959959    [preferences setDownloadAttributeEnabled:YES];
     960    [preferences setDirectoryUploadEnabled:YES];
    960961
    961962    [preferences setHiddenPageDOMTimerThrottlingEnabled:NO];
  • trunk/Tools/WebKitTestRunner/TestController.cpp

    r220787 r221177  
    152152{
    153153    printf("OPEN FILE PANEL\n");
     154    if (WKOpenPanelParametersGetAllowsDirectories(parameters))
     155        printf("-> DIRECTORIES ARE ALLOWED\n");
    154156    WKArrayRef fileURLs = TestController::singleton().openPanelFileURLs();
    155157    if (!fileURLs || !WKArrayGetSize(fileURLs)) {
     
    723725    WKPreferencesSetInlineMediaPlaybackRequiresPlaysInlineAttribute(preferences, false);
    724726    WKPreferencesSetBeaconAPIEnabled(preferences, true);
     727    WKPreferencesSetDirectoryUploadEnabled(preferences, true);
    725728
    726729    WKCookieManagerDeleteAllCookies(WKContextGetCookieManager(m_context.get()));
Note: See TracChangeset for help on using the changeset viewer.