all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jaesup Kwak <veshboo@gmail.com>
To: 29565@debbugs.gnu.org
Subject: bug#29565: [PATCH] Support file download and upload (Bug#29565)
Date: Thu, 21 Dec 2017 13:12:53 +0900	[thread overview]
Message-ID: <CAADX8xLnQVB-RAixAreKsONKNoMYkJ-wY41-WfDaW-nwkLhMHw@mail.gmail.com> (raw)
In-Reply-To: <CAADX8xLDj_vWMhEHV0PhfucjuWm7OHXe8Cg2mjVnxZGE-z3O+w@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 690 bytes --]

For the MIME types, which ns xwidget webkit cannot show in a view,
'xwidget-webkit-save-as-file' is called via 'response-callback' event.

Ns xwidget webkit presents file open panel to select upload files.

Tighter check for javascript availability.

* lisp/xwidget.el
(xwidget-webkit-callback): Add case for 'response-callback' event.
(xwidget-webkit-download-dir): New variable.
(xwidget-webkit-save-as-file): New function.
* src/nsxwidget.m
(XwWebView::decidePolicyForNavigationResponse): Store the event.  And
tighter check for javascript availability.
(XwWebView::runOpenPanelWithParameters): Select upload files.
* src/xwidget.c
(store_xwidget_response_callback_event): New function.

[-- Attachment #1.2: Type: text/html, Size: 935 bytes --]

[-- Attachment #2: 0001-Support-file-download-and-upload-Bug-29565.patch --]
[-- Type: application/octet-stream, Size: 7189 bytes --]

From b5e3db090f43734c365f86d92cae1107f8df5398 Mon Sep 17 00:00:00 2001
From: Jaesup Kwak <veshboo@gmail.com>
Date: Thu, 21 Dec 2017 12:36:51 +0900
Subject: [PATCH] Support file download and upload (Bug#29565)

For the MIME types, which ns xwidget webkit cannot show in a view,
'xwidget-webkit-save-as-file' is called via 'response-callback' event.

Ns xwidget webkit presents file open panel to select upload files.

Tighter check for javascript availability.

* lisp/xwidget.el
(xwidget-webkit-callback): Add case for 'response-callback' event.
(xwidget-webkit-download-dir): New variable.
(xwidget-webkit-save-as-file): New function.
* src/nsxwidget.m
(XwWebView::decidePolicyForNavigationResponse): Store the event.  And
tighter check for javascript availability.
(XwWebView::runOpenPanelWithParameters): Select upload files.
* src/xwidget.c
(store_xwidget_response_callback_event): New function.
---
 lisp/xwidget.el | 23 +++++++++++++++++++++++
 src/nsxwidget.m | 36 ++++++++++++++++++++++++++++++++++--
 src/xwidget.c   | 20 ++++++++++++++++++++
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index 901a6be9a2..6c88262e43 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -84,6 +84,7 @@ xwidget-at
 (require 'browse-url)
 (require 'image-mode);;for some image-mode alike functionality
 (require 'seq)
+(require 'url-handlers)
 
 ;;;###autoload
 (defun xwidget-webkit-browse-url (url &optional new-session)
@@ -289,6 +290,12 @@ xwidget-webkit-callback
                    (xwidget-webkit-show-id-or-named-element
                     xwidget
                     (match-string 1 strarg)))))
+;;; TODO: Response handling other than download.
+            ((eq xwidget-event-type 'response-callback)
+             (let ((url  (nth 3 last-input-event))
+                   (mime-type (nth 4 last-input-event))
+                   (file-name (nth 5 last-input-event)))
+               (xwidget-webkit-save-as-file xwidget url mime-type file-name)))
             ((eq xwidget-event-type 'javascript-callback)
              (let ((proc (nth 3 last-input-event))
                    (arg  (nth 4 last-input-event)))
@@ -317,6 +324,22 @@ xwidget-webkit-mode
     ;; Keep track of [vh]scroll when switching buffers
     (image-mode-setup-winprops))
 
+;;; Download, save as file.
+
+(defvar xwidget-webkit-download-dir "~/Downloads/"
+  "Directory where download file saved.")
+
+(defun xwidget-webkit-save-as-file (xwidget url mime-type &optional file-name)
+  "For XWIDGET webkit, save URL resource of MIME-TYPE as FILE-NAME."
+  (ignore xwidget) ;; Not used currently
+  (let ((save-name (read-file-name
+                    (format "Save '%s' file as: " mime-type)
+                    xwidget-webkit-download-dir file-name nil file-name)))
+    (if (file-directory-p save-name)
+        (setq save-name (concat (file-name-as-directory save-name) file-name)))
+    (setq xwidget-webkit-download-dir (file-name-directory save-name))
+    (url-copy-file url save-name t)))
+
 ;;; Bookmarks integration
 
 (defvar xwidget-webkit-bookmark-jump-new-session nil
diff --git a/src/nsxwidget.m b/src/nsxwidget.m
index ee295518b8..22baaecedf 100644
--- a/src/nsxwidget.m
+++ b/src/nsxwidget.m
@@ -33,6 +33,11 @@ void store_xwidget_event_string (struct xwidget *xw,
                                  const char *eventname,
                                  const char *eventstr);
 
+void store_xwidget_response_callback_event (struct xwidget *xw,
+                                            const char *url,
+                                            const char *mimetype,
+                                            const char *filename);
+
 void store_xwidget_js_callback_event (struct xwidget *xw,
                                       Lisp_Object proc,
                                       Lisp_Object argument);
@@ -142,7 +147,15 @@ - (void)webView:(WKWebView *)webView
 {
   if (!navigationResponse.canShowMIMEType)
     {
-      /* TODO: download using NSURLxxx?  */
+      NSString *url = navigationResponse.response.URL.absoluteString;
+      NSString *mimetype = navigationResponse.response.MIMEType;
+      NSString *filename = navigationResponse.response.suggestedFilename;
+      decisionHandler (WKNavigationResponsePolicyCancel);
+      store_xwidget_response_callback_event (self.xw,
+                                             url.UTF8String,
+                                             mimetype.UTF8String,
+                                             filename.UTF8String);
+      return;
     }
   decisionHandler (WKNavigationResponsePolicyAllow);
 
@@ -157,7 +170,10 @@ - (void)webView:(WKWebView *)webView
         {
           /* TODO: Sloppy parsing of 'Content-Security-Policy' value.  */
           NSRange sandbox = [value rangeOfString:@"sandbox"];
-          if (sandbox.location != NSNotFound)
+          if (sandbox.location != NSNotFound
+              && (sandbox.location == 0
+                  || [value characterAtIndex:(sandbox.location - 1)] == ' '
+                  || [value characterAtIndex:(sandbox.location - 1)] == ';'))
             {
               NSRange allowScripts = [value rangeOfString:@"allow-scripts"];
               if (allowScripts.location == NSNotFound
@@ -181,6 +197,22 @@ - (WKWebView *)webView:(WKWebView *)webView
   return nil;
 }
 
+/* Open panel for file upload.  */
+- (void)webView:(WKWebView *)webView
+runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters
+initiatedByFrame:(WKFrameInfo *)frame
+completionHandler:(void (^)(NSArray<NSURL *> *URLs))completionHandler
+{
+  NSOpenPanel *openPanel = [NSOpenPanel openPanel];
+  openPanel.canChooseFiles = YES;
+  openPanel.canChooseDirectories = NO;
+  openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection;
+  if ([openPanel runModal] == NSModalResponseOK)
+    completionHandler (openPanel.URLs);
+  else
+    completionHandler (nil);
+}
+
 /* By forwarding mouse events to emacs view (frame)
    - Mouse click in webview selects the window contains the webview.
    - Correct mouse hand/arrow/I-beam is displayed (TODO: not perfect yet).
diff --git a/src/xwidget.c b/src/xwidget.c
index 60e8260377..c6a8218c56 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -255,6 +255,26 @@ store_xwidget_event_string (struct xwidget *xw, const char *eventname,
   kbd_buffer_store_event (&event);
 }
 
+void
+store_xwidget_response_callback_event (struct xwidget *xw,
+                                       const char *url,
+                                       const char *mimetype,
+                                       const char *filename)
+{
+  struct input_event event;
+  Lisp_Object xwl;
+  XSETXWIDGET (xwl, xw);
+  EVENT_INIT (event);
+  event.kind = XWIDGET_EVENT;
+  event.frame_or_window = Qnil;
+  event.arg = list5 (intern ("response-callback"),
+                     xwl,
+                     build_string (url),
+                     build_string (mimetype),
+                     build_string (filename));
+  kbd_buffer_store_event (&event);
+}
+
 void
 store_xwidget_js_callback_event (struct xwidget *xw,
                                  Lisp_Object proc,
-- 
2.15.0


  parent reply	other threads:[~2017-12-21  4:12 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-04 16:44 bug#29565: [PATCH] Support xwidget webkit for macOS X Jaesup Kwak
2017-12-04 20:59 ` Alan Third
2017-12-05  6:01   ` Jaesup Kwak
2017-12-05  7:55     ` Jaesup Kwak
2017-12-05 20:00       ` Alan Third
2017-12-06  5:59         ` Jaesup Kwak
2017-12-06  6:20           ` Jaesup Kwak
2017-12-13 11:15 ` Jaesup Kwak
2017-12-13 11:27 ` Jaesup Kwak
2017-12-13 16:13 ` Jaesup Kwak
2017-12-15  2:01 ` Jaesup Kwak
2017-12-15  2:27 ` Jaesup Kwak
2017-12-15 16:06 ` Jaesup Kwak
2017-12-20  2:39 ` bug#29565: [PATCH] Fix compile failure for GTK xwidget (Bug#29565) Jaesup Kwak
2017-12-20  8:25 ` bug#29565: [PATCH] Enable plugins for ns xwidget webkit (Bug#29565) Jaesup Kwak
2017-12-21  4:12 ` Jaesup Kwak [this message]
2018-03-30 11:48 ` bug#29565: [PATCH] Support xwidget webkit for macOS X Alan Third
2018-03-30 12:19   ` Jaesup Kwak
2019-09-28 23:52 ` Stefan Kangas
2020-08-10 13:55   ` Lars Ingebrigtsen
2020-08-10 19:06     ` Alan Third
2020-08-11 11:04       ` Lars Ingebrigtsen
2020-08-11 15:22         ` Eli Zaretskii
2020-08-11 16:26           ` Lars Ingebrigtsen
2020-08-11 18:28             ` Eli Zaretskii
2020-08-11 19:26               ` Lars Ingebrigtsen
2020-08-11 19:33                 ` Eli Zaretskii
2020-08-12 10:44                   ` Lars Ingebrigtsen
2020-08-11 19:56             ` Alan Third
2020-08-11 19:58               ` Lars Ingebrigtsen
2020-08-11 20:18                 ` Alan Third
2020-08-11 20:29                   ` Lars Ingebrigtsen
2020-08-11 20:35                     ` Alan Third
2020-08-11 20:50                     ` Lars Ingebrigtsen
2020-08-12  3:46                       ` Unknown
2020-08-12 10:05                         ` Lars Ingebrigtsen
2020-08-12 16:34                           ` Alan Third
2020-08-12  2:26       ` Richard Stallman
2020-08-12  4:13         ` Eli Zaretskii
2020-08-12  4:27           ` Eli Zaretskii
2020-08-13  3:43           ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAADX8xLnQVB-RAixAreKsONKNoMYkJ-wY41-WfDaW-nwkLhMHw@mail.gmail.com \
    --to=veshboo@gmail.com \
    --cc=29565@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.