From c25321e44707253381c2ab92033e8d57ff00c746 Mon Sep 17 00:00:00 2001 From: Sungbin Jo Date: Wed, 12 Aug 2020 12:39:50 +0200 Subject: [PATCH] Add utility functions and new xwidget commands Co-authored-by: Jaesup Kwak * 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 download event. * src/xwidget.c src/xwidget.h (store_xwidget_download_callback_event): New function. --- etc/NEWS | 3 +++ lisp/xwidget.el | 32 ++++++++++++++++++++++++++++++++ src/nsxwidget.m | 12 ++++++++++++ src/xwidget.c | 20 ++++++++++++++++++++ src/xwidget.h | 5 +++++ 5 files changed, 72 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index cfe180ff688..b25e43bb9b0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -986,6 +986,9 @@ If Emacs was built with xwidget support, you can access the embedded webkit browser with 'M-x xwidget-webkit-browse-url'. Viewing two instances of xwidget webkit is not supported. +*** Downloading files from xwidget-webkit is now supported. +The new variable 'xwidget-webkit-download-dir' says where to download to. + *** New functions for xwidget-webkit mode 'xwidget-webkit-clone-and-split-below', 'xwidget-webkit-clone-and-split-right'. diff --git a/lisp/xwidget.el b/lisp/xwidget.el index e38bd1b32fb..074320855c5 100644 --- a/lisp/xwidget.el +++ b/lisp/xwidget.el @@ -288,6 +288,12 @@ XWIDGET instance, XWIDGET-EVENT-TYPE depends on the originating xwidget." (xwidget-webkit-show-id-or-named-element xwidget (match-string 1 strarg))))) + ;; TODO: Response handling other than download. + ((eq xwidget-event-type 'download-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 url mime-type file-name))) ((eq xwidget-event-type 'javascript-callback) (let ((proc (nth 3 last-input-event)) (arg (nth 4 last-input-event))) @@ -308,6 +314,32 @@ If non-nil, plugins are enabled. Otherwise, disabled.")) ;; Keep track of [vh]scroll when switching buffers (image-mode-setup-winprops)) +;;; Download, save as file. + +(defcustom xwidget-webkit-download-dir "~/Downloads/" + "Directory where download file saved." + :version "27.1" + :type 'file) + +(defun xwidget-webkit-save-as-file (url mime-type file-name) + "For XWIDGET webkit, save URL of MIME-TYPE to location specified by user. +FILE-NAME combined with `xwidget-webkit-download-dir' is the default file name +of the prompt when reading. When the file name the user specified is a +directory, URL is saved at the specified directory as FILE-NAME." + (let ((save-name (read-file-name + (format "Save URL `%s' of type `%s' in file/directory: " + url mime-type) + xwidget-webkit-download-dir + (when file-name + (expand-file-name + file-name + xwidget-webkit-download-dir))))) + (if (file-directory-p save-name) + (setq save-name + (expand-file-name (file-name-nondirectory file-name) save-name))) + (setq xwidget-webkit-download-dir (file-name-directory save-name)) + (url-copy-file url save-name t))) + ;;; Bookmarks integration (defcustom xwidget-webkit-bookmark-jump-new-session nil diff --git a/src/nsxwidget.m b/src/nsxwidget.m index 8643ba24d80..2277cc97d55 100644 --- a/src/nsxwidget.m +++ b/src/nsxwidget.m @@ -121,6 +121,18 @@ decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { + if (!navigationResponse.canShowMIMEType) + { + NSString *url = navigationResponse.response.URL.absoluteString; + NSString *mimetype = navigationResponse.response.MIMEType; + NSString *filename = navigationResponse.response.suggestedFilename; + decisionHandler (WKNavigationResponsePolicyCancel); + store_xwidget_download_callback_event (self.xw, + url.UTF8String, + mimetype.UTF8String, + filename.UTF8String); + return; + } decisionHandler (WKNavigationResponsePolicyAllow); self.urlScriptBlocked[navigationResponse.response.URL] = diff --git a/src/xwidget.c b/src/xwidget.c index d5c229c2b19..c61f5bef88d 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -258,6 +258,26 @@ store_xwidget_event_string (struct xwidget *xw, const char *eventname, kbd_buffer_store_event (&event); } +void +store_xwidget_download_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 ("download-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, diff --git a/src/xwidget.h b/src/xwidget.h index 29f1153206f..40ad8ae8334 100644 --- a/src/xwidget.h +++ b/src/xwidget.h @@ -154,6 +154,11 @@ void store_xwidget_event_string (struct xwidget *xw, const char *eventname, const char *eventstr); +void store_xwidget_download_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); -- 2.39.5