Przeglądaj źródła

Ladybird/AppKit: Implement <input type=file> file type filtering

Timothy Flynn 1 rok temu
rodzic
commit
3a8bde9ef2

+ 39 - 1
Ladybird/AppKit/UI/LadybirdWebView.mm

@@ -18,6 +18,7 @@
 #import <Application/ApplicationDelegate.h>
 #import <UI/Event.h>
 #import <UI/LadybirdWebView.h>
+#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
 #import <Utilities/Conversions.h>
 
 #if !__has_feature(objc_arc)
@@ -626,7 +627,7 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_
         [panel makeKeyAndOrderFront:nil];
     };
 
-    m_web_view_bridge->on_request_file_picker = [self](auto const&, auto allow_multiple_files) {
+    m_web_view_bridge->on_request_file_picker = [self](auto const& accepted_file_types, auto allow_multiple_files) {
         auto* panel = [NSOpenPanel openPanel];
         [panel setCanChooseFiles:YES];
         [panel setCanChooseDirectories:NO];
@@ -639,6 +640,43 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_
             [panel setMessage:@"Select file"];
         }
 
+        NSMutableArray<UTType*>* accepted_file_filters = [NSMutableArray array];
+
+        for (auto const& filter : accepted_file_types.filters) {
+            filter.visit(
+                [&](Web::HTML::FileFilter::FileType type) {
+                    switch (type) {
+                    case Web::HTML::FileFilter::FileType::Audio:
+                        [accepted_file_filters addObject:UTTypeAudio];
+                        break;
+                    case Web::HTML::FileFilter::FileType::Image:
+                        [accepted_file_filters addObject:UTTypeImage];
+                        break;
+                    case Web::HTML::FileFilter::FileType::Video:
+                        [accepted_file_filters addObject:UTTypeVideo];
+                        break;
+                    }
+                },
+                [&](Web::HTML::FileFilter::MimeType const& filter) {
+                    auto* ns_mime_type = Ladybird::string_to_ns_string(filter.value);
+
+                    if (auto* ut_type = [UTType typeWithMIMEType:ns_mime_type]) {
+                        [accepted_file_filters addObject:ut_type];
+                    }
+                },
+                [&](Web::HTML::FileFilter::Extension const& filter) {
+                    auto* ns_extension = Ladybird::string_to_ns_string(filter.value);
+
+                    if (auto* ut_type = [UTType typeWithFilenameExtension:ns_extension]) {
+                        [accepted_file_filters addObject:ut_type];
+                    }
+                });
+        }
+
+        // FIXME: Create an accessory view to allow selecting the active file filter.
+        [panel setAllowedContentTypes:accepted_file_filters];
+        [panel setAllowsOtherFileTypes:YES];
+
         [panel beginSheetModalForWindow:[self window]
                       completionHandler:^(NSInteger result) {
                           Vector<Web::HTML::SelectedFile> selected_files;

+ 1 - 1
Ladybird/CMakeLists.txt

@@ -149,7 +149,7 @@ elseif (APPLE)
         AppKit/Utilities/Conversions.mm
     )
     target_include_directories(ladybird PRIVATE AppKit)
-    target_link_libraries(ladybird PRIVATE "-framework Cocoa" LibUnicode)
+    target_link_libraries(ladybird PRIVATE "-framework Cocoa -framework UniformTypeIdentifiers" LibUnicode)
     target_compile_options(ladybird PRIVATE
         -fobjc-arc
         -Wno-deprecated-anon-enum-enum-conversion # Required for CGImageCreate

+ 4 - 1
Meta/gn/secondary/Ladybird/BUILD.gn

@@ -134,7 +134,10 @@ executable("ladybird_executable") {
       "//Userland",
     ]
 
-    frameworks = [ "Cocoa.framework" ]
+    frameworks = [
+      "Cocoa.framework",
+      "UniformTypeIdentifiers.framework",
+    ]
   }
 
   if (current_os != "mac") {