emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 286467a 27/35: Add functions for performing searches on xwidgets


From: Lars Ingebrigtsen
Subject: master 286467a 27/35: Add functions for performing searches on xwidgets
Date: Sat, 6 Nov 2021 22:01:59 -0400 (EDT)

branch: master
commit 286467a6b1bff1d7b7bebe285538fb9a67084f01
Author: Po Lu <luangruo@yahoo.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Add functions for performing searches on xwidgets
    
    * etc/NEWS:
    * doc/lispref/display.texi: Document changes.
    
    * src/xwidget.c (Fxwidget_webkit_search)
    (Fxwidget_webkit_next_result)
    (Fxwidget_webkit_previous_result)
    (Fxwidget_wenkit_finish_search): New functions.
    
    (syms_of_xwidget): Define new built-ins.
    (kill_buffer_xwidgets): Free search query if present.
    * src/xwidget.h (struct xwidget): Add field for search query.
---
 doc/lispref/display.texi |  40 ++++++++++++
 etc/NEWS                 |   5 ++
 src/xwidget.c            | 167 +++++++++++++++++++++++++++++++++++++++++++++++
 src/xwidget.h            |   1 +
 4 files changed, 213 insertions(+)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 2fb89d7..b780263 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -6896,6 +6896,46 @@ through Lisp code, and as such shouldn't require this 
function to be
 sent.
 @end defun
 
+@defun xwidget-webkit-search query xwidget &optional case-insensitive 
backwards wrap-around
+Start an incremental search on the WebKit widget @var{xwidget} with
+the string @var{query} as a query.  @var{case-insensitive} denotes
+whether or not the search is case-insensitive, @var{backwards}
+determines if the search is performed backwards towards the start of
+the document, and @var{wrap-around} determines whether or not the
+search terminates at the end of the document.
+
+If the function is called while a search query is already present,
+then the query specified here will replace the existing query.
+
+To stop a search query, use @code{xwidget-webkit-finish-search}.
+@end defun
+
+@defun xwidget-webkit-next-result xwidget
+Display the next search result in @var{xwidget}.  This function will
+error unless a search query has already been started in @var{xwidget}
+through @code{xwidget-webkit-search}.
+
+If @code{wrap-around} was non-nil when @code{xwidget-webkit-search}
+was called, then the search will restart from the beginning of the
+document if the end is reached.
+@end defun
+
+@defun xwidget-webkit-previous-result xwidget
+Display the previous search result in @var{xwidget}.  This function
+will error unless a search query has already been started in
+@var{xwidget} through @code{xwidget-webkit-search}.
+
+If @code{wrap-around} was non-nil when @code{xwidget-webkit-search}
+was called, then the search will restart from the end of the
+document if the beginning is reached.
+@end defun
+
+@defun xwidget-webkit-finish-search xwidget
+Finish a search operation started with @code{xwidget-webkit-search} in
+@var{xwidget}.  If there is no query currently ongoing, then this
+function will error.
+@end defun
+
 @node Buttons
 @section Buttons
 @cindex buttons in buffers
diff --git a/etc/NEWS b/etc/NEWS
index 9a660ed..f5295dd 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -741,6 +741,11 @@ what the widget will actually receive.
 On GTK+, only key and function key events are implemented.
 
 +++
+** New functions for performing searches on WebKit xwidgets.
+Some new functions, such as `xwidget-webkit-search', have been added
+for performing searches on WebKit xwidgets.
+
++++
 ** `load-changed' xwidget events are now more detailed.
 In particular, they can now have different arguments based on the
 state of the WebKit widget.  `load-finished' is sent when a load has
diff --git a/src/xwidget.c b/src/xwidget.c
index 36e8cab..10bb4ac 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -142,6 +142,7 @@ Returns the newly constructed xwidget, or nil if 
construction fails.  */)
   xw->widgetwindow_osr = NULL;
   xw->widget_osr = NULL;
   xw->hit_result = 0;
+  xw->find_text = NULL;
   if (EQ (xw->type, Qwebkit))
     {
       block_input ();
@@ -1759,6 +1760,166 @@ DEFUN ("xwidget-query-on-exit-flag",
   return (XXWIDGET (xwidget)->kill_without_query ? Qnil : Qt);
 }
 
+DEFUN ("xwidget-webkit-search", Fxwidget_webkit_search, Sxwidget_webkit_search,
+       2, 5, 0,
+       doc: /* Begin an incremental search operation in an xwidget.
+QUERY should be a string containing the text to search for.  XWIDGET
+should be a WebKit xwidget where the search will take place.  When the
+search operation is complete, callers should also call
+`xwidget-webkit-finish-search' to complete the search operation.
+
+CASE-INSENSITIVE, when non-nil, will cause the search to ignore the
+case of characters inside QUERY.  BACKWARDS, when non-nil, will cause
+the search to proceed towards the beginning of the widget's contents.
+WRAP-AROUND, when nil, will cause the search to stop upon hitting the
+end of the widget's contents.
+
+It is OK to call this function even when a search is already in
+progress.  In that case, the previous search query will be replaced
+with QUERY.  */)
+  (Lisp_Object query, Lisp_Object xwidget, Lisp_Object case_insensitive,
+   Lisp_Object backwards, Lisp_Object wrap_around)
+{
+#ifdef USE_GTK
+  WebKitWebView *webview;
+  WebKitFindController *controller;
+  WebKitFindOptions opt;
+  struct xwidget *xw;
+  gchar *g_query;
+#endif
+
+  CHECK_STRING (query);
+  CHECK_XWIDGET (xwidget);
+
+#ifdef USE_GTK
+  xw = XXWIDGET (xwidget);
+  webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+  query = ENCODE_UTF_8 (query);
+  opt = WEBKIT_FIND_OPTIONS_NONE;
+  g_query = xstrdup (SSDATA (query));
+
+  if (!NILP (case_insensitive))
+    opt |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+  if (!NILP (backwards))
+    opt |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+  if (!NILP (wrap_around))
+    opt |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+
+  if (xw->find_text)
+    xfree (xw->find_text);
+  xw->find_text = g_query;
+
+  block_input ();
+  controller = webkit_web_view_get_find_controller (webview);
+  webkit_find_controller_search (controller, g_query, opt, G_MAXUINT);
+  unblock_input ();
+#endif
+
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-next-result", Fxwidget_webkit_next_result,
+       Sxwidget_webkit_next_result, 1, 1, 0,
+       doc: /* Show the next result matching the current search query.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'.  */)
+  (Lisp_Object xwidget)
+{
+  struct xwidget *xw;
+#ifdef USE_GTK
+  WebKitWebView *webview;
+  WebKitFindController *controller;
+#endif
+
+  CHECK_XWIDGET (xwidget);
+  xw = XXWIDGET (xwidget);
+
+  if (!xw->find_text)
+    error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+  block_input ();
+  webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+  controller = webkit_web_view_get_find_controller (webview);
+  webkit_find_controller_search_next (controller);
+  unblock_input ();
+#endif
+
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-previous-result", Fxwidget_webkit_previous_result,
+       Sxwidget_webkit_previous_result, 1, 1, 0,
+       doc: /* Show the previous result matching the current search query.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'.  */)
+  (Lisp_Object xwidget)
+{
+  struct xwidget *xw;
+#ifdef USE_GTK
+  WebKitWebView *webview;
+  WebKitFindController *controller;
+#endif
+
+  CHECK_XWIDGET (xwidget);
+  xw = XXWIDGET (xwidget);
+
+  if (!xw->find_text)
+    error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+  block_input ();
+  webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+  controller = webkit_web_view_get_find_controller (webview);
+  webkit_find_controller_search_previous (controller);
+
+  if (xw->find_text)
+    {
+      xfree (xw->find_text);
+      xw->find_text = NULL;
+    }
+  unblock_input ();
+#endif
+
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-finish-search", Fxwidget_webkit_finish_search,
+       Sxwidget_webkit_finish_search, 1, 1, 0,
+       doc: /* Finish XWIDGET's search operation.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'.  */)
+  (Lisp_Object xwidget)
+{
+  struct xwidget *xw;
+#ifdef USE_GTK
+  WebKitWebView *webview;
+  WebKitFindController *controller;
+#endif
+
+  CHECK_XWIDGET (xwidget);
+  xw = XXWIDGET (xwidget);
+
+  if (!xw->find_text)
+    error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+  block_input ();
+  webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+  controller = webkit_web_view_get_find_controller (webview);
+  webkit_find_controller_search_finish (controller);
+  unblock_input ();
+#endif
+
+  return Qnil;
+}
+
 void
 syms_of_xwidget (void)
 {
@@ -1792,6 +1953,10 @@ syms_of_xwidget (void)
   defsubr (&Sxwidget_buffer);
   defsubr (&Sset_xwidget_plist);
   defsubr (&Sxwidget_perform_lispy_event);
+  defsubr (&Sxwidget_webkit_search);
+  defsubr (&Sxwidget_webkit_finish_search);
+  defsubr (&Sxwidget_webkit_next_result);
+  defsubr (&Sxwidget_webkit_previous_result);
 
   DEFSYM (QCxwidget, ":xwidget");
   DEFSYM (QCtitle, ":title");
@@ -2050,6 +2215,8 @@ kill_buffer_xwidgets (Lisp_Object buffer)
             gtk_widget_destroy (xw->widget_osr);
             gtk_widget_destroy (xw->widgetwindow_osr);
           }
+       if (xw->find_text)
+         xfree (xw->find_text);
        if (!NILP (xw->script_callbacks))
          for (ptrdiff_t idx = 0; idx < ASIZE (xw->script_callbacks); idx++)
            {
diff --git a/src/xwidget.h b/src/xwidget.h
index 8b3aef5..3bab6d5 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -68,6 +68,7 @@ struct xwidget
   GtkWidget *widget_osr;
   GtkWidget *widgetwindow_osr;
   guint hit_result;
+  gchar *find_text;
 #elif defined (NS_IMPL_COCOA)
 # ifdef __OBJC__
   /* For offscreen widgets, unused if not osr.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]