Hello community, here is the log from the commit of package vimb for openSUSE:Factory checked in at 2019-07-30 12:39:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/vimb (Old) and /work/SRC/openSUSE:Factory/.vimb.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "vimb" Tue Jul 30 12:39:16 2019 rev:3 rq:719740 version:3.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/vimb/vimb.changes 2019-03-27 16:22:04.635521340 +0100 +++ /work/SRC/openSUSE:Factory/.vimb.new.4126/vimb.changes 2019-07-30 12:39:21.378934067 +0200 @@ -1,0 +2,19 @@ +Tue Jul 30 04:41:40 UTC 2019 - mvetter@suse.com + +- Update to 3.5.0: + Added: + * Add external download command #543 #348. + * Added ephemeral mode by new option --incognito#562. + Changed: + * Hinting shows the current focused elements URI in the statusbar. + * Show error if printing with :hardcopy fails #564. + Fixed: + * Fixed compilation if source is not in a git repo (Thanks to Patrick Steinhardt). + * Fixed partial hidden hint labels on top of screen. + * Fix segfault on open in new tabe from context menu #556. + * Fix "... (null)" shown in title during url sanitization. + Removed: + * Setting private-browsing was removed in favor of --incognito option. +- Remove vim-3.4.0-fixbuild.patch: included upstream + +------------------------------------------------------------------- Old: ---- 3.4.0.tar.gz vim-3.4.0-fixbuild.patch New: ---- 3.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ vimb.spec ++++++ --- /var/tmp/diff_new_pack.LcUHzd/_old 2019-07-30 12:39:22.254933921 +0200 +++ /var/tmp/diff_new_pack.LcUHzd/_new 2019-07-30 12:39:22.254933921 +0200 @@ -17,15 +17,13 @@ Name: vimb -Version: 3.4.0 +Version: 3.5.0 Release: 0 Summary: The vim-like browser License: GPL-3.0-or-later Group: Productivity/Networking/Web/Browsers URL: https://fanglingsu.github.io/vimb/ Source: https://github.com/fanglingsu/vimb/archive/%{version}.tar.gz -# FIX-UPSTREAM - mvetter@suse.com - https://github.com/fanglingsu/vimb/pull/552 -Patch0: vim-3.4.0-fixbuild.patch BuildRequires: gtk3-devel BuildRequires: webkit2gtk3-devel >= 2.20 @@ -35,7 +33,6 @@ %prep %setup -q -%patch0 -p1 %build make %{?_smp_mflags} ++++++ 3.4.0.tar.gz -> 3.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/CHANGELOG.md new/vimb-3.5.0/CHANGELOG.md --- old/vimb-3.4.0/CHANGELOG.md 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/CHANGELOG.md 2019-07-29 22:03:20.000000000 +0200 @@ -11,6 +11,21 @@ ### Fixed ### Removed +## [3.5.0] - 2019-07-29 +### Added +* Add external download command #543 #348. +* Added ephemeral mode by new option `--incognito` #562. +### Changed +* Hinting shows the current focused elements URI in the statusbar. +* Show error if printing with `:hardcopy` fails #564. +### Fixed +* Fixed compilation if source is not in a git repo (Thanks to Patrick Steinhardt). +* Fixed partial hidden hint labels on top of screen. +* Fix segfault on open in new tabe from context menu #556. +* Fix "... (null)" shown in title during url sanitization. +### Removed +* Setting `private-browsing` was removed in favor of `--incognito` option. + ## [3.4.0] - 2019-03-26 ### Added * Allow to show video in fullscreen, without statusbar and inputbox, if requested. @@ -241,7 +256,8 @@ cookie file * Fixed none POSIX `echo -n` call -[Unreleased]: https://github.com/fanglingsu/vimb/compare/3.3.0...master +[Unreleased]: https://github.com/fanglingsu/vimb/compare/3.5.0...master +[3.5.0]: https://github.com/fanglingsu/vimb/compare/3.4.0...3.5.0 [3.4.0]: https://github.com/fanglingsu/vimb/compare/3.3.0...3.4.0 [3.3.0]: https://github.com/fanglingsu/vimb/compare/3.2.0...3.3.0 [3.2.0]: https://github.com/fanglingsu/vimb/compare/3.1.0...3.2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/Makefile new/vimb-3.5.0/Makefile --- old/vimb-3.4.0/Makefile 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/Makefile 2019-07-29 22:03:20.000000000 +0200 @@ -1,9 +1,9 @@ -version = 3.4.0 +version = 3.5.0 include config.mk all: version.h src.subdir-all -version.h: Makefile .git/index +version.h: Makefile $(wildcard .git/index) @echo "create $@" $(Q)v="$$(git describe --tags 2>/dev/null)"; \ echo "#define VERSION \"$${v:-$(version)}\"" > $@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/doc/vimb.1 new/vimb-3.5.0/doc/vimb.1 --- old/vimb-3.4.0/doc/vimb.1 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/doc/vimb.1 2019-07-29 22:03:20.000000000 +0200 @@ -37,6 +37,9 @@ .I WINID of an XEmbed-aware application, that Vimb will use as its parent. .TP +.B "\-i, \-\-incognito" +Start an instance with user data read-only (see \fIFILES\fP section). +.TP .B "\-h, \-\-help" Show help options. .TP @@ -836,7 +839,7 @@ .RE .TP .BI ":sh[ellcmd]! " cmd -Like :sh[ellcmd], but asyncron. +Like :sh[ellcmd] but asynchronous. .sp Example: .EX @@ -1044,6 +1047,29 @@ .B dns-prefetching (bool) Indicates if Vimb prefetches domain names. .TP +.B download-command (string) +A command with placeholder '%s' that will be invoked to download a URI in +case 'download-use-external' is enabled. +.RS +.TP +The following additional environment variable are available: +.PD 0 +.TP +.B $VIMB_URI +The URI of the current opened page, normally the page where the download was +started from, also known as referer. +.TP +.B $VIMB_DOWNLOAD_PATH +Setting value of 'download-path' which would be used normally for downloads. +.PD +.PP +Example: +.PD 0 +.IP ":set download-command=/bin/sh -c ""cd '$VIMB_DOWNLOAD_PATH' \ +&& curl -sLJOC - -e '$VIMB_URI' %s""" +.PD +.RE +.TP .B download-path (string) Path to the default download directory. If no download directory is set, download will be written into current @@ -1051,6 +1077,11 @@ The following pattern will be expanded if the download is started '~/', '~user', '$VAR' and '${VAR}'. .TP +.B download-use-external (bool) +Indicates if the external download tool set as 'download-command' should be +used to handle downloads. +If this is disabled Vimb will handle the download. +.TP .B editor-command (string) Command with placeholder '%s' called if form field is opened with $EDITOR to spawn the editor-like `x-terminal-emulator -e vim %s'. @@ -1149,6 +1180,7 @@ .B history-max-items (int) Maximum number of unique items stored in search-, command or URI history. If history-max-items is set to 0, the history file will not be changed. +This setting has no effect if option \-\-incognito is set. .TP .B home-page (string) Homepage that vimb opens if started without a URI. @@ -1225,12 +1257,6 @@ .B print-backgrounds (bool) Whether background images should be drawn during printing. .TP -.B private-browsing (bool) -Whether to enable private browsing mode. -This suppresses printing of messages into JavaScript Console. -At the time this is the only way to force WebKit to -not allow a page to store data in the windows sessionStorage. -.TP .B plugins (bool) Determines whether or not plugins on the page are enabled. .TP @@ -1361,22 +1387,30 @@ .TP .I cookies.db Sqlite cookie storage. +This file will not be touched if option \-\-incognito is set. .TP .I closed Holds the URIs of last closed browser windows. +This file will not be touched if option \-\-incognito is set. .TP .I history This file holds the history of unique opened URIs. +This file will not be touched if option \-\-incognito is set. +.TP +.I bookmark +This file holds the list of bookmarked URIs with tags. .TP .I command This file holds the history of commands and search queries performed via input box. +This file will not be touched if option \-\-incognito is set. .TP .I queue Holds the read it later queue filled by `qpush'. .TP .I search This file holds the history of search queries. +This file will not be touched if option \-\-incognito is set. .TP .I scripts.js This file can be used to run user scripts, that are injected into every page diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/bookmark.c new/vimb-3.5.0/src/bookmark.c --- old/vimb-3.4.0/src/bookmark.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/bookmark.c 2019-07-29 22:03:20.000000000 +0200 @@ -236,7 +236,12 @@ static GList *load(const char *file) { - return util_file_to_unique_list(file, (Util_Content_Func)line_to_bookmark, 0); + char **lines; + GList *list; + lines = util_get_lines(file); + list = util_strv_to_unique_list(lines, (Util_Content_Func)line_to_bookmark, 0); + g_strfreev(lines); + return list; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/ex.c new/vimb-3.5.0/src/ex.c --- old/vimb-3.4.0/src/ex.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/ex.c 2019-07-29 22:03:20.000000000 +0200 @@ -140,6 +140,7 @@ static void on_eval_script_finished(GDBusProxy *proxy, GAsyncResult *result, Client *c); static VbCmdResult ex_clearcache(Client *c, const ExArg *arg); static VbCmdResult ex_hardcopy(Client *c, const ExArg *arg); +static void print_failed_cb(WebKitPrintOperation* op, GError *err, Client *c); static VbCmdResult ex_map(Client *c, const ExArg *arg); static VbCmdResult ex_unmap(Client *c, const ExArg *arg); static VbCmdResult ex_normal(Client *c, const ExArg *arg); @@ -858,12 +859,17 @@ return CMD_SUCCESS; } +/** + * Opens the gtk print dialog. + */ static VbCmdResult ex_hardcopy(Client *c, const ExArg *arg) { WebKitPrintOperation *op = webkit_print_operation_new(c->webview); GtkPrintSettings *settings = gtk_print_settings_new(); - gtk_print_settings_set(settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME, c->state.title); + + g_signal_connect(op, "failed", G_CALLBACK(print_failed_cb), c); + webkit_print_operation_set_print_settings(op, settings); webkit_print_operation_run_dialog(op, NULL); g_object_unref(op); @@ -872,6 +878,14 @@ return CMD_SUCCESS; } +/** + * Callback called when printing failed. + */ +static void print_failed_cb(WebKitPrintOperation* op, GError *err, Client *c) +{ + vb_echo(c, MSG_ERROR, FALSE, "print failed: %s", err->message); +} + static VbCmdResult ex_map(Client *c, const ExArg *arg) { if (!arg->lhs->len || !arg->rhs->len) { @@ -956,7 +970,7 @@ return command_queue(c, &a) ? CMD_SUCCESS | CMD_KEEPINPUT - : CMD_ERROR | CMD_KEEPINPUT; + : CMD_ERROR; } #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/file-storage.c new/vimb-3.5.0/src/file-storage.c --- old/vimb-3.4.0/src/file-storage.c 1970-01-01 01:00:00.000000000 +0100 +++ new/vimb-3.5.0/src/file-storage.c 2019-07-29 22:03:20.000000000 +0200 @@ -0,0 +1,151 @@ +/** + * vimb - a webkit based vim like browser. + * + * Copyright (C) 2012-2019 Daniel Carl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include <glib.h> +#include <stdio.h> +#include <sys/file.h> +#include <glib/gstdio.h> + +#include "file-storage.h" + +struct filestorage { + char *file_path; + gboolean readonly; + GString *str; +}; + +/** + * Create new file storage instance for given directory and filename. If the + * file does not exists in the directory and give mode is not 0 the file is + * created with the given mode. + * + * The returned FileStorage must be freed by file_storage_free(). + * + * @dir: Directory in which the file is searched. + * @filename: Filename to built the absolute path with. + * @mode: Mode (file permission as chmod(2)) used for the file when + * creating it. If 0 the file is not created and the storage is + * used in read only mode - no data written to the file. + */ +FileStorage *file_storage_new(const char *dir, const char *filename, gboolean readonly) +{ + FileStorage *storage; + + storage = g_slice_new(FileStorage); + storage->readonly = readonly; + storage->file_path = g_build_filename(dir, filename, NULL); + + /* Use gstring as storage in case when the file is used read only. */ + if (storage->readonly) { + storage->str = g_string_new(NULL); + } else { + storage->str = NULL; + } + + return storage; +} + +/** + * Free memory for given file storage. + */ +void file_storage_free(FileStorage *storage) +{ + if (storage) { + g_free(storage->file_path); + if (storage->str) { + g_string_free(storage->str, TRUE); + } + g_slice_free(FileStorage, storage); + } +} + +/** + * Append new data to file. + * + * @fileStorage: FileStorage to append the data to + * @format: Format string used to process va_list + */ +gboolean file_storage_append(FileStorage *storage, const char *format, ...) +{ + FILE *f; + va_list args; + + g_assert(storage); + + /* Write data to in memory list in case the file storage is read only. */ + if (storage->readonly) { + va_start(args, format); + g_string_append_vprintf(storage->str, format, args); + va_end(args); + return TRUE; + } + if ((f = fopen(storage->file_path, "a+"))) { + flock(fileno(f), LOCK_EX); + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + flock(fileno(f), LOCK_UN); + fclose(f); + return TRUE; + } + + return FALSE; +} + +/** + * Retrieves all the lines from file storage. + * + * The result have to be freed by g_strfreev(). + */ +char **file_storage_get_lines(FileStorage *storage) +{ + char *fullcontent = NULL; + char *content = NULL; + char **lines = NULL; + + g_file_get_contents(storage->file_path, &content, NULL, NULL); + + if (storage->str && storage->str->len) { + if (content) { + fullcontent = g_strconcat(content, storage->str->str, NULL); + lines = g_strsplit(fullcontent, "\n", -1); + g_free(fullcontent); + } else { + lines = g_strsplit(storage->str->str, "\n", -1); + } + } else { + lines = g_strsplit(content ? content : "", "\n", -1); + } + + if (content) { + g_free(content); + } + + return lines; +} + +const char *file_storage_get_path(FileStorage *storage) +{ + return storage->file_path; +} + +gboolean file_storage_is_readonly(FileStorage *storage) +{ + return storage->readonly; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/file-storage.h new/vimb-3.5.0/src/file-storage.h --- old/vimb-3.4.0/src/file-storage.h 1970-01-01 01:00:00.000000000 +0100 +++ new/vimb-3.5.0/src/file-storage.h 2019-07-29 22:03:20.000000000 +0200 @@ -0,0 +1,33 @@ +/** + * vimb - a webkit based vim like browser. + * + * Copyright (C) 2012-2019 Daniel Carl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef _FILE_STORAGE_H +#define _FILE_STORAGE_H + +#include <glib.h> + +typedef struct filestorage FileStorage; +FileStorage *file_storage_new(const char *dir, const char *filename, int mode); +void file_storage_free(FileStorage *storage); +gboolean file_storage_append(FileStorage *storage, const char *format, ...); +char **file_storage_get_lines(FileStorage *storage); +const char *file_storage_get_path(FileStorage *storage); +gboolean file_storage_is_readonly(FileStorage *storage); + +#endif /* end of include guard: _FILE_STORAGE_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/hints.c new/vimb-3.5.0/src/hints.c --- old/vimb-3.4.0/src/hints.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/hints.c 2019-07-29 22:03:20.000000000 +0200 @@ -308,16 +308,28 @@ char *value = NULL; if (!return_value) { - return FALSE; + goto error; } g_variant_get(return_value, "(bs)", &success, &value); if (!success || !strncmp(value, "ERROR:", 6)) { - return FALSE; + goto error; } - - /* following return values mark fired hints */ - if (!strncmp(value, "DONE:", 5)) { + if (!strncmp(value, "OVER:", 5)) { + /* If focused elements src is given fire mouse-target-changed signal + * to show its uri in the statusbar. */ + if (*(value + 7)) { + /* We get OVER:{I,A}:element-url so we use byte 6 to check for the + * hinted element type image I or link A. */ + if (*(value + 5) == 'I') { + vb_statusbar_show_hover_url(c, LINK_TYPE_IMAGE, value + 7); + } else { + vb_statusbar_show_hover_url(c, LINK_TYPE_LINK, value + 7); + } + } else { + goto error; + } + } else if (!strncmp(value, "DONE:", 5)) { fire_timeout(c, FALSE); /* Change to normal mode only if we are currently in command mode and * we are not in g-mode hinting. This is required to not switch to @@ -397,6 +409,10 @@ } return TRUE; + +error: + vb_statusbar_show_hover_url(c, LINK_TYPE_NONE, NULL); + return FALSE; } static void fire_timeout(Client *c, gboolean on) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/history.c new/vimb-3.5.0/src/history.c --- old/vimb-3.4.0/src/history.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/history.c 2019-07-29 22:03:20.000000000 +0200 @@ -27,8 +27,9 @@ #include "history.h" #include "main.h" #include "util.h" +#include "file-storage.h" -#define HIST_FILE(t) (vb.files[file_map[t]]) +#define HIST_STORAGE(t) (vb.storage[storage_map[t]]) typedef struct { char *first; char *second; @@ -37,14 +38,14 @@ static gboolean history_item_contains_all_tags(History *item, char **query, guint qlen); static void free_history(History *item); static History *line_to_history(const char *uri, const char *title); -static GList *load(const char *file); +static GList *load(FileStorage *s); static void write_to_file(GList *list, const char *file); /* map history types to files */ -static const int file_map[HISTORY_LAST] = { - FILES_COMMAND, - FILES_SEARCH, - FILES_HISTORY +static const int storage_map[HISTORY_LAST] = { + STORAGE_COMMAND, + STORAGE_SEARCH, + STORAGE_HISTORY }; extern struct Vimb vb; @@ -53,18 +54,18 @@ */ void history_add(Client *c, HistoryType type, const char *value, const char *additional) { - const char *file; + FileStorage *s; /* Don't write a history entry if the history max size is set to 0. */ if (!vb.config.history_max) { return; } - file = HIST_FILE(type); + s = HIST_STORAGE(type); if (additional) { - util_file_append(file, "%s\t%s\n", value, additional); + file_storage_append(s, "%s\t%s\n", value, additional); } else { - util_file_append(file, "%s\n", value); + file_storage_append(s, "%s\n", value); } } @@ -74,7 +75,7 @@ */ void history_cleanup(void) { - const char *file; + FileStorage *s; GList *list; /* don't cleanup the history file if history max size is 0 */ @@ -83,10 +84,12 @@ } for (HistoryType i = HISTORY_FIRST; i < HISTORY_LAST; i++) { - file = HIST_FILE(i); - list = load(file); - write_to_file(list, file); - g_list_free_full(list, (GDestroyNotify)free_history); + s = HIST_STORAGE(i); + if (!file_storage_is_readonly(s)) { + list = load(s); + write_to_file(list, file_storage_get_path(s)); + g_list_free_full(list, (GDestroyNotify)free_history); + } } } @@ -99,7 +102,7 @@ GtkTreeIter iter; History *item; - src = load(HIST_FILE(type)); + src = load(HIST_STORAGE(type)); src = g_list_reverse(src); if (!input || !*input) { /* without any tags return all items */ @@ -168,12 +171,12 @@ switch (type) { case INPUT_COMMAND: - src = load(HIST_FILE(HISTORY_COMMAND)); + src = load(HIST_STORAGE(HISTORY_COMMAND)); break; case INPUT_SEARCH_FORWARD: case INPUT_SEARCH_BACKWARD: - src = load(HIST_FILE(HISTORY_SEARCH)); + src = load(HIST_STORAGE(HISTORY_SEARCH)); break; default: @@ -241,10 +244,12 @@ * * Returned list must be freed with (GDestroyNotify)free_history. */ -static GList *load(const char *file) +static GList *load(FileStorage *s) { - return util_file_to_unique_list( - file, (Util_Content_Func)line_to_history, vb.config.history_max + return util_strv_to_unique_list( + file_storage_get_lines(s), + (Util_Content_Func)line_to_history, + vb.config.history_max ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/main.c new/vimb-3.5.0/src/main.c --- old/vimb-3.4.0/src/main.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/main.c 2019-07-29 22:03:20.000000000 +0200 @@ -46,6 +46,7 @@ #include "shortcut.h" #include "util.h" #include "autocmd.h" +#include "file-storage.h" static void client_destroy(Client *c); static Client *client_new(WebKitWebView *webview); @@ -63,6 +64,9 @@ static void on_webctx_init_web_extension(WebKitWebContext *webctx, gpointer data); static gboolean on_webdownload_decide_destination(WebKitDownload *download, gchar *suggested_filename, Client *c); +static void on_webdownload_response_received(WebKitDownload *download, + GParamSpec *ps, Client *c); +static void spawn_download_command(Client *c, WebKitURIResponse *response); static void on_webdownload_failed(WebKitDownload *download, GError *error, Client *c); static void on_webdownload_finished(WebKitDownload *download, Client *c); @@ -639,6 +643,39 @@ } /** + * Show the given url on the left of statusbar. + */ +void vb_statusbar_show_hover_url(Client *c, VbLinkType type, const char *uri) +{ + char *sanitized_uri, + *msg; + const char *type_label; + + /* No uri given - show the current URI. */ + if (!uri || !*uri) { + update_urlbar(c); + return; + } + + switch (type) { + case LINK_TYPE_LINK: + type_label = "Link: "; + break; + case LINK_TYPE_IMAGE: + type_label = "Image: "; + break; + default: + return; + } + + sanitized_uri = util_sanitize_uri(uri); + msg = g_strconcat(type_label, uri, NULL); + gtk_label_set_text(GTK_LABEL(c->statusbar.left), msg); + g_free(msg); + g_free(sanitized_uri); +} + +/** * Destroys given client and removed it from client queue. If no client is * there in queue, quit the gtk main loop. */ @@ -990,6 +1027,7 @@ #ifndef FEATURE_NO_XEMBED + (vb.embed ? 2 : 0) #endif + + (vb.incognito ? 1 : 0) + (vb.profile ? 2 : 0) + (vb.no_maximize ? 1 : 0), sizeof(char *) @@ -1009,6 +1047,9 @@ cmd[i++] = xid; } #endif + if (vb.incognito) { + cmd[i++] = "-i"; + } if (vb.profile) { cmd[i++] = "-p"; cmd[i++] = vb.profile; @@ -1037,15 +1078,19 @@ autocmd_run(c, AU_DOWNLOAD_STARTED, uri, NULL); #endif - g_signal_connect(download, "decide-destination", G_CALLBACK(on_webdownload_decide_destination), c); - g_signal_connect(download, "failed", G_CALLBACK(on_webdownload_failed), c); - g_signal_connect(download, "finished", G_CALLBACK(on_webdownload_finished), c); - g_signal_connect(download, "received-data", G_CALLBACK(on_webdownload_received_data), c); + if (GET_BOOL(c, "download-use-external")) { + g_signal_connect(download, "notify::response", G_CALLBACK(on_webdownload_response_received), c); + } else { + g_signal_connect(download, "decide-destination", G_CALLBACK(on_webdownload_decide_destination), c); + g_signal_connect(download, "failed", G_CALLBACK(on_webdownload_failed), c); + g_signal_connect(download, "finished", G_CALLBACK(on_webdownload_finished), c); + g_signal_connect(download, "received-data", G_CALLBACK(on_webdownload_received_data), c); - c->state.downloads = g_list_append(c->state.downloads, download); + c->state.downloads = g_list_append(c->state.downloads, download); - /* to reflect the correct download count */ - vb_statusbar_update(c); + /* to reflect the correct download count */ + vb_statusbar_update(c); + } } /** @@ -1087,6 +1132,48 @@ return vb_download_set_destination(c, download, suggested_filename, NULL); } +static void on_webdownload_response_received(WebKitDownload *download, + GParamSpec *ps, Client *c) +{ + spawn_download_command(c, webkit_download_get_response(download)); + webkit_download_cancel(download); +} + +static void spawn_download_command(Client *c, WebKitURIResponse *response) +{ + char *cmd; + char **argv, **envp; + int argc; + GError *error = NULL; + + cmd = g_strdup_printf(GET_CHAR(c, "download-command"), + webkit_uri_response_get_uri(response)); + + if (!g_shell_parse_argv(cmd, &argc, &argv, &error)) { + g_warning("Could not parse download-command '%s': %s", + cmd, + error->message); + g_error_free(error); + g_free(cmd); + return; + } + + envp = g_get_environ(); + envp = g_environ_setenv(envp, "VIMB_DOWNLOAD_PATH", + GET_CHAR(c, "download-path"), TRUE); + + if (g_spawn_async(NULL, argv, envp, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { + vb_echo(c, MSG_NORMAL, FALSE, "Download started"); + } else { + vb_echo(c, MSG_ERROR, TRUE, "Could not start download"); + g_warning("%s", error->message); + g_clear_error(&error); + } + g_free(cmd); + g_strfreev(envp); + g_strfreev(argv); +} + /** * Callback for the webkit download failed signal. * This signal is emitted when an error occurs during the download operation. @@ -1347,18 +1434,25 @@ WebKitLoadEvent event, Client *c) { GTlsCertificateFlags tlsflags; + const char *raw_uri; char *uri = NULL; + raw_uri = webkit_web_view_get_uri(webview); + if (raw_uri) { + uri = util_sanitize_uri(raw_uri); + } + switch (event) { case WEBKIT_LOAD_STARTED: #ifdef FEATURE_AUTOCMD - autocmd_run(c, AU_LOAD_STARTED, webkit_web_view_get_uri(webview), NULL); + autocmd_run(c, AU_LOAD_STARTED, raw_uri, NULL); #endif /* update load progress in statusbar */ c->state.progress = 0; vb_statusbar_update(c); - uri = util_sanitize_uri(webkit_web_view_get_uri(webview)); - set_title(c, uri); + if (uri) { + set_title(c, uri); + } /* Make sure hinting is cleared before the new page is loaded. * Without that vimb would still be in hinting mode after hinting * was started and some links was clicked my mouse. Even if there @@ -1379,13 +1473,12 @@ * right place to remove the flag. */ c->mode->flags &= ~FLAG_IGNORE_FOCUS; #ifdef FEATURE_AUTOCMD - autocmd_run(c, AU_LOAD_COMMITTED, webkit_web_view_get_uri(webview), NULL); + autocmd_run(c, AU_LOAD_COMMITTED, raw_uri, NULL); #endif /* save the current URI in register % */ - uri = util_sanitize_uri(webkit_web_view_get_uri(webview)); vb_register_add(c, '%', uri); /* check if tls is on and the page is trusted */ - if (g_str_has_prefix(uri, "https://")) { + if (uri && g_str_has_prefix(uri, "https://")) { if (webkit_web_view_get_tls_info(webview, NULL, &tlsflags) && tlsflags) { set_statusbar_style(c, STATUS_SSL_INVALID); } else { @@ -1405,12 +1498,11 @@ break; case WEBKIT_LOAD_FINISHED: - uri = util_sanitize_uri(webkit_web_view_get_uri(webview)); #ifdef FEATURE_AUTOCMD - autocmd_run(c, AU_LOAD_FINISHED, webkit_web_view_get_uri(webview), NULL); + autocmd_run(c, AU_LOAD_FINISHED, raw_uri, NULL); #endif c->state.progress = 100; - if (strncmp(uri, "about:", 6)) { + if (uri && strncmp(uri, "about:", 6)) { history_add(c, HISTORY_URL, uri, webkit_web_view_get_title(webview)); } break; @@ -1429,9 +1521,6 @@ static void on_webview_mouse_target_changed(WebKitWebView *webview, WebKitHitTestResult *result, guint modifiers, Client *c) { - char *msg; - char *uri; - /* Save the hitTestResult to have this later available for events that * don't support this. */ if (c->state.hit_test_result) { @@ -1440,20 +1529,14 @@ c->state.hit_test_result = g_object_ref(result); if (webkit_hit_test_result_context_is_link(result)) { - uri = util_sanitize_uri(webkit_hit_test_result_get_link_uri(result)); - msg = g_strconcat("Link: ", uri, NULL); - gtk_label_set_text(GTK_LABEL(c->statusbar.left), msg); - g_free(msg); - g_free(uri); + vb_statusbar_show_hover_url(c, LINK_TYPE_LINK, + webkit_hit_test_result_get_link_uri(result)); } else if (webkit_hit_test_result_context_is_image(result)) { - uri = util_sanitize_uri(webkit_hit_test_result_get_image_uri(result)); - msg = g_strconcat("Image: ", uri, NULL); - gtk_label_set_text(GTK_LABEL(c->statusbar.left), msg); - g_free(msg); - g_free(uri); + vb_statusbar_show_hover_url(c, LINK_TYPE_LINK, + webkit_hit_test_result_get_image_uri(result)); } else { /* No link under cursor - show the current URI. */ - update_urlbar(c); + vb_statusbar_show_hover_url(c, LINK_TYPE_NONE, NULL); } } @@ -1492,6 +1575,7 @@ if (c->state.uri) { g_free(c->state.uri); } + c->state.uri = util_sanitize_uri(webkit_web_view_get_uri(c->webview)); update_urlbar(c); @@ -1689,6 +1773,9 @@ /* free memory of other components */ util_cleanup(); + for (i = 0; i < STORAGE_LAST; i++) { + file_storage_free(vb.storage[i]); + } for (i = 0; i < FILES_LAST; i++) { if (vb.files[i]) { g_free(vb.files[i]); @@ -1715,25 +1802,32 @@ vb.files[FILES_CONFIG] = g_strdup(rp); free(rp); } else { - vb.files[FILES_CONFIG] = util_get_filepath(path, "config", FALSE, 0600); + vb.files[FILES_CONFIG] = g_build_filename(path, "config", NULL); } /* Setup those files that are use multiple time during runtime */ - vb.files[FILES_CLOSED] = util_get_filepath(path, "closed", TRUE, 0600); - vb.files[FILES_COOKIE] = util_get_filepath(path, "cookies.db", TRUE, 0600); - vb.files[FILES_USER_STYLE] = util_get_filepath(path, "style.css", FALSE, 0600); - vb.files[FILES_SCRIPT] = util_get_filepath(path, "scripts.js", FALSE, 0600); - vb.files[FILES_HISTORY] = util_get_filepath(path, "history", TRUE, 0600); - vb.files[FILES_COMMAND] = util_get_filepath(path, "command", TRUE, 0600); - vb.files[FILES_BOOKMARK] = util_get_filepath(path, "bookmark", TRUE, 0600); - vb.files[FILES_QUEUE] = util_get_filepath(path, "queue", TRUE, 0600); - vb.files[FILES_SEARCH] = util_get_filepath(path, "search", TRUE, 0600); + if (!vb.incognito) { + vb.files[FILES_CLOSED] = g_build_filename(path, "closed", NULL); + vb.files[FILES_COOKIE] = g_build_filename(path, "cookies.db", NULL); + } + vb.files[FILES_BOOKMARK] = g_build_filename(path, "bookmark", NULL); + vb.files[FILES_QUEUE] = g_build_filename(path, "queue", NULL); + vb.files[FILES_SCRIPT] = g_build_filename(path, "scripts.js", NULL); + vb.files[FILES_USER_STYLE] = g_build_filename(path, "style.css", NULL); + + vb.storage[STORAGE_HISTORY] = file_storage_new(path, "history", vb.incognito); + vb.storage[STORAGE_COMMAND] = file_storage_new(path, "command", vb.incognito); + vb.storage[STORAGE_SEARCH] = file_storage_new(path, "search", vb.incognito); g_free(path); /* Use seperate rendering processed for the webview of the clients in the * current instance. This must be called as soon as possible according to * the documentation. */ - ctx = webkit_web_context_get_default(); + if (vb.incognito) { + ctx = webkit_web_context_new_ephemeral(); + } else { + ctx = webkit_web_context_get_default(); + } webkit_web_context_set_process_model(ctx, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); webkit_web_context_set_cache_model(ctx, WEBKIT_CACHE_MODEL_WEB_BROWSER); @@ -1988,6 +2082,7 @@ GOptionEntry opts[] = { {"config", 'c', 0, G_OPTION_ARG_FILENAME, &vb.configfile, "Custom configuration file", NULL}, {"embed", 'e', 0, G_OPTION_ARG_STRING, &winid, "Reparents to window specified by xid", NULL}, + {"incognito", 'i', 0, G_OPTION_ARG_NONE, &vb.incognito, "Run with user data read-only", NULL}, {"profile", 'p', 0, G_OPTION_ARG_CALLBACK, (GOptionArgFunc*)profileOptionArgFunc, "Profile name", NULL}, {"version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Print version", NULL}, {"no-maximize", 0, 0, G_OPTION_ARG_NONE, &vb.no_maximize, "Do no attempt to maximize window", NULL}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/main.h new/vimb-3.5.0/src/main.h --- old/vimb-3.4.0/src/main.h 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/main.h 2019-07-29 22:03:20.000000000 +0200 @@ -26,6 +26,7 @@ #include <webkit2/webkit2.h> #include "shortcut.h" #include "handler.h" +#include "file-storage.h" #include "config.h" @@ -105,17 +106,29 @@ enum { FILES_BOOKMARK, FILES_CLOSED, - FILES_COMMAND, FILES_CONFIG, FILES_COOKIE, - FILES_HISTORY, FILES_QUEUE, FILES_SCRIPT, - FILES_SEARCH, FILES_USER_STYLE, FILES_LAST }; +enum { + STORAGE_CLOSED, + STORAGE_COMMAND, + STORAGE_CONFIG, + STORAGE_HISTORY, + STORAGE_SEARCH, + STORAGE_LAST +}; + +typedef enum { + LINK_TYPE_NONE, + LINK_TYPE_LINK, + LINK_TYPE_IMAGE, +} VbLinkType; + typedef struct Client Client; typedef struct State State; typedef struct Map Map; @@ -262,6 +275,7 @@ GHashTable *modes; /* all available browser main modes */ char *configfile; /* config file given as option on startup */ char *files[FILES_LAST]; + FileStorage *storage[STORAGE_LAST]; char *profile; /* profile name */ struct { guint history_max; @@ -269,6 +283,7 @@ } config; GtkCssProvider *style_provider; gboolean no_maximize; + gboolean incognito; }; gboolean vb_download_set_destination(Client *c, WebKitDownload *download, @@ -290,6 +305,7 @@ void vb_register_add(Client *c, char buf, const char *value); const char *vb_register_get(Client *c, char buf); void vb_statusbar_update(Client *c); +void vb_statusbar_show_hover_url(Client *c, VbLinkType type, const char *uri); void vb_gui_style_update(Client *c, const char *name, const char *value); #endif /* end of include guard: _MAIN_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/scripts/hints.css new/vimb-3.5.0/src/scripts/hints.css --- old/vimb-3.4.0/src/scripts/hints.css 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/scripts/hints.css 2019-07-29 22:03:20.000000000 +0200 @@ -1,5 +1,4 @@ span[vimbhint^='label']{ - -webkit-transform:translate(-4px,-4px); background-color:#fff; border:1px solid #444; color:#000; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/scripts/hints.js new/vimb-3.5.0/src/scripts/hints.js --- old/vimb-3.4.0/src/scripts/hints.js 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/scripts/hints.js 2019-07-29 22:03:20.000000000 +0200 @@ -175,8 +175,8 @@ label = labelTmpl.cloneNode(false); label.style.display = "none"; - label.style.left = rect.left + "px"; - label.style.top = rect.top + "px"; + label.style.left = Math.max(rect.left - 4, 0) + "px"; + label.style.top = Math.max(rect.top - 4, 0) + "px"; /* if hinted element is an image - show title or alt of the image in hint label */ /* this allows to see how to filter for the image */ @@ -348,7 +348,7 @@ idx = 0; } } - focusHint(idx); + return focusHint(idx); } function fire() { @@ -423,8 +423,11 @@ } /* get the new active hint */ if ((activeHint = validHints[newIdx])) { + var e = activeHint.e; activeHint.focus(); - mouseEvent(activeHint.e, "mouseover"); + mouseEvent(e, "mouseover"); + + return "OVER:" + (e instanceof HTMLImageElement ? "I:" : "A:") + getSrc(e); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/setting.c new/vimb-3.5.0/src/setting.c --- old/vimb-3.4.0/src/setting.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/setting.c 2019-07-29 22:03:20.000000000 +0200 @@ -116,7 +116,6 @@ setting_add(c, "plugins", TYPE_BOOLEAN, &on, webkit, 0, "enable-plugins"); setting_add(c, "prevent-newwindow", TYPE_BOOLEAN, &off, internal, 0, &c->config.prevent_newwindow); setting_add(c, "print-backgrounds", TYPE_BOOLEAN, &on, webkit, 0, "print-backgrounds"); - setting_add(c, "private-browsing", TYPE_BOOLEAN, &off, webkit, 0, "enable-private-browsing"); setting_add(c, "sans-serif-font", TYPE_CHAR, &"sans-serif", webkit, 0, "sans-serif-font-family"); setting_add(c, "scripts", TYPE_BOOLEAN, &on, webkit, 0, "enable-javascript"); setting_add(c, "serif-font", TYPE_CHAR, &"serif", webkit, 0, "serif-font-family"); @@ -150,6 +149,8 @@ i = 100; setting_add(c, "default-zoom", TYPE_INTEGER, &i, default_zoom, 0, NULL); setting_add(c, "download-path", TYPE_CHAR, &"~/", NULL, 0, NULL); + setting_add(c, "download-command", TYPE_CHAR, &"/bin/sh -c \"curl -sLJOC - -e '$VIMB_URI' %s\"", NULL, 0, NULL); + setting_add(c, "download-use-external", TYPE_BOOLEAN, &off, NULL, 0, NULL); setting_add(c, "incsearch", TYPE_BOOLEAN, &off, internal, 0, &c->config.incsearch); i = 10; /* TODO should be global and not overwritten by a new client */ @@ -158,7 +159,7 @@ setting_add(c, "spell-checking", TYPE_BOOLEAN, &off, webkit_spell_checking, 0, NULL); setting_add(c, "spell-checking-languages", TYPE_CHAR, &"en_US", webkit_spell_checking_language, FLAG_LIST|FLAG_NODUP, NULL); - /* gui style settings vimb3 */ + /* gui style settings vimb */ setting_add(c, "completion-css", TYPE_CHAR, &"color:#fff;background-color:#656565;font:" SETTING_GUI_FONT_NORMAL, gui_style, 0, NULL); setting_add(c, "completion-hover-css", TYPE_CHAR, &"background-color:#777;", gui_style, 0, NULL); setting_add(c, "completion-selected-css", TYPE_CHAR, &"color:#f6f3e8;background-color:#888;", gui_style, 0, NULL); @@ -672,7 +673,7 @@ ucm = webkit_web_view_get_user_content_manager(c->webview); - if (enabled && vb.files[FILES_USER_STYLE]) { + if (enabled) { if (g_file_get_contents(vb.files[FILES_USER_STYLE], &source, NULL, NULL)) { style = webkit_user_style_sheet_new( source, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, @@ -683,7 +684,7 @@ webkit_user_style_sheet_unref(style); g_free(source); } else { - g_warning("Could not reed style file: %s", vb.files[FILES_USER_STYLE]); + g_message("Could not reed style file: %s", vb.files[FILES_USER_STYLE]); } } else { webkit_user_content_manager_remove_all_style_sheets(ucm); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/util.c new/vimb-3.5.0/src/util.c --- old/vimb-3.4.0/src/util.c 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/util.c 2019-07-29 22:03:20.000000000 +0200 @@ -430,41 +430,6 @@ } /** - * Buil the path from given directory and filename and checks if the file - * exists. If the file does not exists and the create option is not set, this - * function returns NULL. - * If the file exists or the create option was given the full generated path - * is returned as newly allocated string. - * - * The return value must be freed with g_free. - * - * @dir: Directory in which the file is searched. - * @filename: Filename to built the absolute path with. - * @create: If TRUE, the file is created if it does not already exist. - * @mode: Mode (file permission as chmod(2)) used for the file when creating it. - */ -char *util_get_filepath(const char *dir, const char *filename, gboolean create, int mode) -{ - char *fullpath; - - /* Built the full path out of config dir and given file name. */ - fullpath = g_build_filename(dir, filename, NULL); - - if (g_file_test(fullpath, G_FILE_TEST_IS_REGULAR)) { - return fullpath; - } else if (create) { - /* If create option was given - create the file. */ - fclose(fopen(fullpath, "a")); - g_chmod(fullpath, mode); - return fullpath; - } - - g_free(fullpath); - return NULL; -} - - -/** * Retrieves the file content as lines. * * The result have to be freed by g_strfreev(). @@ -478,7 +443,7 @@ return NULL; } - if ((content = util_get_file_contents(filename, NULL))) { + if (g_file_get_contents(filename, &content, NULL, NULL)) { /* split the file content into lines */ lines = g_strsplit(content, "\n", -1); g_free(content); @@ -491,20 +456,18 @@ * based on the lines comparing all chars until the next <tab> char or end of * line. * - * @filename: file to read items from * @func: Function to parse a single line to item. * @max_items: maximum number of items that are returned, use 0 for * unlimited items */ -GList *util_file_to_unique_list(const char *filename, Util_Content_Func func, +GList *util_strv_to_unique_list(char **lines, Util_Content_Func func, guint max_items) { - char *line, **lines; + char *line; int i, len; GList *gl = NULL; GHashTable *ht; - lines = util_get_lines(filename); if (!lines) { return NULL; } @@ -556,7 +519,6 @@ } } - g_strfreev(lines); g_hash_table_destroy(ht); return gl; @@ -821,7 +783,7 @@ /** * Strips password from a uri. * - * Return newly allocated string. + * Return newly allocated string or NULL. */ char *util_sanitize_uri(const char *uri_str) { @@ -829,8 +791,14 @@ char *sanitized_uri; char *for_display; + if (!uri_str) { + return NULL; + } #if WEBKIT_CHECK_VERSION(2, 24, 0) for_display = webkit_uri_for_display(uri_str); + if (!for_display) { + for_display = g_strdup(uri_str); + } #else for_display = g_strdup(uri_str); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/src/util.h new/vimb-3.5.0/src/util.h --- old/vimb-3.4.0/src/util.h 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/src/util.h 2019-07-29 22:03:20.000000000 +0200 @@ -43,9 +43,8 @@ char *util_get_config_dir(void); char *util_get_file_contents(const char *filename, gsize *length); gboolean util_file_set_content(const char *file, const char *contents); -char *util_get_filepath(const char *dir, const char *filename, gboolean create, int mode); char **util_get_lines(const char *filename); -GList *util_file_to_unique_list(const char *filename, Util_Content_Func func, +GList *util_strv_to_unique_list(char **lines, Util_Content_Func func, guint max_items); gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src); gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/tests/.gitignore new/vimb-3.5.0/tests/.gitignore --- old/vimb-3.4.0/tests/.gitignore 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/tests/.gitignore 2019-07-29 22:03:20.000000000 +0200 @@ -1 +1,2 @@ /test-* +!/test-*.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/tests/Makefile new/vimb-3.5.0/tests/Makefile --- old/vimb-3.4.0/tests/Makefile 2019-03-26 23:47:03.000000000 +0100 +++ new/vimb-3.5.0/tests/Makefile 2019-07-29 22:03:20.000000000 +0200 @@ -4,7 +4,8 @@ TEST_PROGS = test-util \ test-shortcut \ - test-handler + test-handler \ + test-file-storage all: $(TEST_PROGS) $(Q)LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):." gtester --verbose $(TEST_PROGS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vimb-3.4.0/tests/test-file-storage.c new/vimb-3.5.0/tests/test-file-storage.c --- old/vimb-3.4.0/tests/test-file-storage.c 1970-01-01 01:00:00.000000000 +0100 +++ new/vimb-3.5.0/tests/test-file-storage.c 2019-07-29 22:03:20.000000000 +0200 @@ -0,0 +1,147 @@ +/** + * vimb - a webkit based vim like browser. + * + * Copyright (C) 2012-2019 Daniel Carl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include <src/file-storage.h> +#include <gio/gio.h> +#include <stdio.h> + +static char *pwd; +static char *none_existing_file = "_absent.txt"; +static char *created_file = "_created.txt"; +static char *existing_file = "_existent.txt"; + +static void test_ephemeral_no_file(void) +{ + FileStorage *s; + char **lines; + char *file_path; + + file_path = g_build_filename(pwd, none_existing_file, NULL); + + /* make sure the file does not exist */ + remove(file_path); + s = file_storage_new(pwd, none_existing_file, TRUE); + g_assert_nonnull(s); + g_assert_cmpstr(file_path, ==, file_storage_get_path(s)); + g_assert_true(file_storage_is_readonly(s)); + + /* empty file storage */ + lines = file_storage_get_lines(s); + g_assert_cmpint(g_strv_length(lines), ==, 0); + g_strfreev(lines); + + file_storage_append(s, "-%s\n", "foo"); + file_storage_append(s, "-%s\n", "bar"); + + /* File must not be created on appending data to storage */ + g_assert_false(g_file_test(file_path, G_FILE_TEST_IS_REGULAR)); + + lines = file_storage_get_lines(s); + g_assert_cmpint(g_strv_length(lines), ==, 3); + g_assert_cmpstr(lines[0], ==, "-foo"); + g_assert_cmpstr(lines[1], ==, "-bar"); + g_strfreev(lines); + file_storage_free(s); + g_free(file_path); +} + +static void test_file_created(void) +{ + FileStorage *s; + char *file_path; + + file_path = g_build_filename(pwd, created_file, NULL); + remove(file_path); + + g_assert_false(g_file_test(file_path, G_FILE_TEST_IS_REGULAR)); + s = file_storage_new(pwd, created_file, FALSE); + g_assert_false(file_storage_is_readonly(s)); + g_assert_cmpstr(file_path, ==, file_storage_get_path(s)); + + /* check that file is created only on first write */ + g_assert_false(g_file_test(file_path, G_FILE_TEST_IS_REGULAR)); + file_storage_append(s, ""); + g_assert_true(g_file_test(file_path, G_FILE_TEST_IS_REGULAR)); + + file_storage_free(s); + g_free(file_path); +} + +static void test_ephemeral_with_file(void) +{ + FileStorage *s; + char *file_path; + char **lines; + char *content = NULL; + gboolean result; + + file_path = g_build_filename(pwd, existing_file, NULL); + + s = file_storage_new(pwd, existing_file, TRUE); + g_assert_nonnull(s); + g_assert_true(file_storage_is_readonly(s)); + g_assert_cmpstr(file_path, ==, file_storage_get_path(s)); + + /* file does not exists yet */ + lines = file_storage_get_lines(s); + g_assert_cmpint(g_strv_length(lines), ==, 0); + g_strfreev(lines); + + /* empty file storage but file with two lines */ + result = g_file_set_contents(file_path, "one\n", -1, NULL); + g_assert_true(result); + lines = file_storage_get_lines(s); + g_assert_cmpint(g_strv_length(lines), ==, 2); + g_strfreev(lines); + + file_storage_append(s, "%s\n", "two ephemeral"); + + lines = file_storage_get_lines(s); + g_assert_cmpint(g_strv_length(lines), ==, 3); + g_assert_cmpstr(lines[0], ==, "one"); + g_assert_cmpstr(lines[1], ==, "two ephemeral"); + g_strfreev(lines); + + /* now make sure the file was not changed */ + g_file_get_contents(file_path, &content, NULL, NULL); + g_assert_cmpstr(content, ==, "one\n"); + + file_storage_free(s); + g_free(file_path); +} + +int main(int argc, char *argv[]) +{ + int result; + g_test_init(&argc, &argv, NULL); + + pwd = g_get_current_dir(); + + g_test_add_func("/test-file-storage/ephemeral-no-file", test_ephemeral_no_file); + g_test_add_func("/test-file-storage/file-created", test_file_created); + g_test_add_func("/test-file-storage/ephemeral-with-file", test_ephemeral_with_file); + + result = g_test_run(); + + remove(existing_file); + remove(created_file); + g_free(pwd); + + return result; +}