26#include <dom/bindings/hubbub/parser.h>
44#define N_SEC_PER_DAY (60 * 60 * 24)
87 const char *extension =
"-bk";
91 len = strlen(
path) + strlen(extension);
93 joined = malloc(len + 1);
98 if (snprintf(joined, len + 1,
"%s%s",
path, extension) != len) {
139 if (rename(temp_path,
path) != 0) {
141 NSLOG(netsurf, INFO,
"Error renaming hotlist: %s.",
196 char *last_visited = NULL;
201 const size_t lvsize = 256;
204 if ((lvtime = localtime(&data->
last_visit)) != NULL) {
205 last_visited = malloc(lvsize);
206 if (last_visited != NULL) {
207 len = strftime(last_visited, lvsize,
208 "%a %b %e %H:%M:%S %Y",
213 last_visited = strdup(
"-");
216 if (last_visited == NULL) {
265 title = (data->
title != NULL) ?
327 assert(e->
entry == NULL);
477 &n, relation, rel, &f->
data, f, flags);
495 const char *old_text;
509 lwc_error_ok && match ==
true &&
522 free((
void *)old_text);
541 const char *old_text;
558 lwc_error_ok && match ==
true &&
573 free((
void *)old_text);
580 lwc_error_ok && match ==
true &&
650 dom_string *title1, *url1;
653 dom_exception derror;
659 NSLOG(netsurf, INFO,
"Missing <a> in <li>");
663 derror = dom_node_get_text_content(a, &title1);
664 if (derror != DOM_NO_ERR) {
665 NSLOG(netsurf, INFO,
"No title");
670 derror = dom_element_get_attribute(a, corestring_dom_href, &url1);
671 if (derror != DOM_NO_ERR || url1 == NULL) {
672 NSLOG(netsurf, INFO,
"No URL");
673 dom_string_unref(title1);
679 if (title1 != NULL) {
680 title = dom_string_data(title1);
687 dom_string_unref(url1);
690 NSLOG(netsurf, INFO,
"Failed normalising '%s'",
691 dom_string_data(url1));
693 if (title1 != NULL) {
694 dom_string_unref(title1);
704 if (title1 != NULL) {
705 dom_string_unref(title1);
756 error = dom_node_get_node_name(node, &name);
757 if (error != DOM_NO_ERR || name == NULL)
760 if (dom_string_caseless_lwc_isequal(name, corestring_lwc_li)) {
765 }
else if (dom_string_caseless_lwc_isequal(name, corestring_lwc_h4)) {
769 error = dom_node_get_text_content(node, &title);
770 if (error != DOM_NO_ERR || title == NULL) {
772 "Empty <h4> or memory exhausted.");
773 dom_string_unref(name);
777 if (current_ctx->
title != NULL)
778 dom_string_unref(current_ctx->
title);
779 current_ctx->
title = title;
783 dom_string_caseless_lwc_isequal(name,
784 corestring_lwc_ul)) {
791 bool default_folder =
false;
794 error = dom_element_get_attribute(node, corestring_dom_id, &
id);
795 if (error != DOM_NO_ERR) {
796 dom_string_unref(name);
800 if (dom_string_lwc_isequal(
id, corestring_lwc_default))
801 default_folder =
true;
803 dom_string_unref(
id);
806 title = dom_string_data(current_ctx->
title);
810 current_ctx->
relshp, &f, default_folder);
812 dom_string_unref(name);
820 current_ctx->
rel = rel;
827 new_ctx.
title = NULL;
832 dom_string_unref(name);
836 if (new_ctx.
title != NULL) {
837 dom_string_unref(new_ctx.
title);
838 new_ctx.
title = NULL;
845 dom_string_unref(name);
860 dom_document *document;
861 dom_node *html, *body, *ul;
870 NSLOG(netsurf, INFO,
"No hotlist file path provided.");
893 corestring_lwc_html);
895 dom_node_unref(document);
896 NSLOG(netsurf, WARNING,
897 "%s (<html> not found)",
905 dom_node_unref(html);
906 dom_node_unref(document);
907 NSLOG(netsurf, WARNING,
908 "%s (<html>...<body> not found)",
916 dom_node_unref(body);
917 dom_node_unref(html);
918 dom_node_unref(document);
919 NSLOG(netsurf, WARNING,
920 "%s (<html>...<body>...<ul> not found.)",
934 if (ctx.
title != NULL) {
935 dom_string_unref(ctx.
title);
940 dom_node_unref(body);
941 dom_node_unref(html);
942 dom_node_unref(document);
945 NSLOG(netsurf, WARNING,
946 "%s (Failed building tree.)",
970 static const struct {
973 } default_entries[] = {
974 {
"https://www.netsurf-browser.org/",
976 {
"https://www.netsurf-browser.org/downloads/",
977 "HotlistDownloads" },
978 {
"https://www.netsurf-browser.org/documentation",
979 "HotlistDocumentation" },
980 {
"https://www.netsurf-browser.org/contact",
983 const int n_entries =
sizeof(default_entries) /
984 sizeof(default_entries[0]);
995 for (i = n_entries - 1; i >= 0; i--) {
1046 fprintf(tw->
fp,
"<li><a href=\"%s\">%s</a></li>\n",
1062 fprintf(tw->
fp,
"<h4>%s</h4>\n<ul id=\"default\">\n",
1065 fprintf(tw->
fp,
"<h4>%s</h4>\n<ul>\n", f_text);
1080 fputs(
"</ul>\n", tw->
fp);
1097 title =
"NetSurf hotlist";
1102 fputs(
"<!DOCTYPE html "
1103 "PUBLIC \"//W3C/DTD HTML 4.01//EN\" "
1104 "\"http://www.w3.org/TR/html4/strict.dtd\">\n",
fp);
1105 fputs(
"<html>\n<head>\n",
fp);
1106 fputs(
"<meta http-equiv=\"Content-Type\" "
1107 "content=\"text/html; charset=iso-8859-1\">\n",
fp);
1108 fprintf(
fp,
"<title>%s</title>\n", title);
1109 fputs(
"</head>\n<body>\n<ul>\n",
fp);
1119 fputs(
"</ul>\n</body>\n</html>\n",
fp);
1203 label =
"TreeviewLabelTitle";
1205 if (lwc_intern_string(label, strlen(label),
1215 label =
"TreeviewLabelURL";
1217 if (lwc_intern_string(label, strlen(label),
1224 label =
"TreeviewLabelLastVisit";
1226 if (lwc_intern_string(label, strlen(label),
1233 label =
"TreeviewLabelVisits";
1235 if (lwc_intern_string(label, strlen(label),
1243 label =
"TreeviewLabelFolder";
1245 if (lwc_intern_string(label, strlen(label),
1291 const char *load_path,
1292 const char *save_path)
1301 NSLOG(netsurf, INFO,
"Loading hotlist");
1308 if (save_path != NULL) {
1347 NSLOG(netsurf, INFO,
"Loaded hotlist");
1392 NSLOG(netsurf, INFO,
"Finalising hotlist");
1401 NSLOG(netsurf, INFO,
"Problem saving the hotlist.");
1409 NSLOG(netsurf, INFO,
"Problem destroying the hotlist treeview.");
1423 NSLOG(netsurf, INFO,
"Finalised hotlist");
1441 const char *temp =
messages_get(
"HotlistDefaultFolderName");
1575 if (tw->
data == NULL) {
1578 if (tw->
data == NULL) {
1584 if (tw->
data == NULL) {
1635 assert(
url != NULL);
1647 relation, rel, &entry);
Browser window creation and manipulation interface.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
browser_window_create_flags
flags to browser_window_create
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
static osspriteop_area * buffer
The buffer characteristics.
Useful interned string pointers (interface).
static nserror hotlist_update_url_walk_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for treeview_walk.
bool hotlist_keypress(uint32_t key)
Key press handling.
static nserror hotlist_export_enter_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for treeview_walk node entering.
void hotlist_update_url(nsurl *url)
Update given URL, e.g.
bool hotlist_has_selection(void)
Determine whether there is a selection.
nserror hotlist_add_entry(nsurl *url, const char *title, bool at_y, int y)
Add an entry to the hotlist for given Title/URL.
struct treeview_callback_table hl_tree_cb_t
void hotlist_mouse_action(browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
static nserror hotlist_load_entry(dom_node *li, hotlist_load_ctx *ctx)
Parse an entry represented as a li.
nserror hotlist_fini(void)
Finalise the hotlist.
nserror hotlist_add_url(nsurl *url)
Add an entry to the hotlist for given URL.
nserror hotlist_manager_init(void *core_window_handle)
Initialise the hotlist manager.
static nserror hotlist_add_folder_internal(const char *title, treeview_node *relation, enum treeview_relationship rel, struct hotlist_folder **folder, bool default_folder)
Add folder to the hotlist (creates the folder).
static nserror hotlist_iterate_enter_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for hotlist_iterate node entering.
static nserror hotlist_add_entry_internal(nsurl *url, const char *title, const struct url_data *data, treeview_node *relation, enum treeview_relationship rel, treeview_node **entry)
Add an entry to the hotlist (creates the entry).
static nserror hotlist_create_treeview_field_data(struct hotlist_entry *e, const char *title, const struct url_data *data)
Set a hotlist entry's data from the url_data.
static nserror hotlist_load_directory(dom_node *ul, hotlist_load_ctx *ctx)
Parse a directory represented as a ul.
static nserror hotlist_has_url_walk_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for treeview_walk.
static nserror hotlist_populate(const char *path)
nserror hotlist_manager_fini(void)
Finalise the hotlist manager.
void hotlist_redraw(int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the hotlist.
static nserror hotlist_tree_node_folder_cb(struct treeview_node_msg msg, void *data)
static nserror hotlist_save(const char *path)
nserror hotlist_iterate(void *ctx, hotlist_folder_enter_cb enter_cb, hotlist_address_cb address_cb, hotlist_folder_leave_cb leave_cb)
Walk (depth first) the hotlist, calling callbacks on entering folders, address nodes,...
static nserror hotlist_export_leave_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for treeview_walk node leaving.
static void hotlist_delete_entry_internal(struct hotlist_entry *e)
Delete a hotlist entry.
static nserror hotlist_schedule_save(void)
Schedule a hotlist save.
static nserror hotlist_remove_url_walk_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for treeview_walk.
static nserror hotlist_create_treeview_field_visits_data(struct hotlist_entry *e, const struct url_data *data)
Set a hotlist entry's data from the url_data.
nserror hotlist_add_folder(const char *title, bool at_y, int y)
Add a folder to the hotlist.
nserror hotlist_init(const char *load_path, const char *save_path)
Initialise the hotlist.
nserror hotlist_export(const char *path, const char *title)
Save hotlist to file.
static nserror hotlist_load(const char *path, bool *loaded)
nserror hotlist_expand(bool only_folders)
Expand the treeview's nodes.
static nserror hotlist_initialise_entry_fields(void)
Initialise the treeview entry feilds.
static nserror hotlist_generate(void)
static nserror hotlist_create_entry(nsurl *url, const char *title, const struct url_data *data, struct hotlist_entry **entry)
Create hotlist entry data for URL.
static nserror hotlist_load_directory_cb(dom_node *node, void *ctx)
void hotlist_edit_selection(void)
Edit the first selected node.
static nserror hotlist_get_temp_path(const char *path, char **temp_path)
bool hotlist_has_url(nsurl *url)
Check whether given URL is present in hotlist.
static void hotlist_schedule_save_cb(void *p)
Scheduler callback for saving the hotlist.
struct hotlist_ctx hl_ctx
static nserror hotlist_entry_insert(struct hotlist_entry *e, treeview_node *relation, enum treeview_relationship rel)
Add a hotlist entry to the treeview.
bool hotlist_get_selection(nsurl **url, const char **title)
Get the first selected node.
void hotlist_remove_url(nsurl *url)
Remove any entries matching the given URL from the hotlist.
static nserror hotlist_iterate_leave_cb(void *ctx, void *node_data, enum treeview_node_type type, bool *abort)
Callback for hotlist_iterate node leaving.
nserror hotlist_contract(bool all)
Contract the treeview's nodes.
static nserror hotlist_tree_node_entry_cb(struct treeview_node_msg msg, void *data)
callback for hotlist treeview entry manipulation.
nserror(* hotlist_address_cb)(void *ctx, struct nsurl *url, const char *title)
Client callback for hotlist_iterate, reporting a hotlist address.
nserror(* hotlist_folder_leave_cb)(void *ctx)
Client callback for hotlist_iterate, reporting a hotlist folder departure.
nserror(* hotlist_folder_enter_cb)(void *ctx, const char *title)
Client callback for hotlist_iterate, reporting entry into folder.
nserror treeview_create(treeview **treeout, const struct treeview_callback_table *callbacks, int n_fields, struct treeview_field_desc fields[], struct core_window *cw, treeview_flags flags)
Create a treeview.
nserror treeview_cw_detach(treeview *tree)
Detach a treeview from a corewindow.
nserror treeview_cw_attach(treeview *tree, struct core_window *cw)
Attach a treeview to a corewindow.
void treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
nserror treeview_contract(treeview *tree, bool all)
Contract a treeview's nodes.
nserror treeview_delete_node(treeview *tree, treeview_node *n, treeview_node_options_flags flags)
Delete a treeview node.
enum treeview_node_type treeview_get_selection(treeview *tree, void **node_data)
Get the first selected node.
nserror treeview_fini(void)
Finalise the treeview module (all treeviews must have been destroyed first)
void treeview_edit_selection(treeview *tree)
Edit the first selected node.
bool treeview_has_selection(treeview *tree)
Determine whether treeview has a selection.
bool treeview_keypress(treeview *tree, uint32_t key)
Key press handling for treeviews.
nserror treeview_update_node_entry(treeview *tree, treeview_node *entry, const struct treeview_field_data fields[], void *data)
Update an entry node in given treeview.
nserror treeview_get_relation(treeview *tree, treeview_node **relation, enum treeview_relationship *rel, bool at_y, int y)
Find a relation for node creation.
nserror treeview_create_node_folder(treeview *tree, treeview_node **folder, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data *field, void *data, treeview_node_options_flags flags)
Create a folder node in given treeview.
nserror treeview_destroy(treeview *tree)
Destroy a treeview object.
nserror treeview_walk(treeview *tree, treeview_node *root, treeview_walk_cb enter_cb, treeview_walk_cb leave_cb, void *ctx, enum treeview_node_type type)
Walk (depth first) a treeview subtree, calling a callback at each node of required type.
int treeview_get_height(treeview *tree)
Find current height of a treeview.
void treeview_redraw(treeview *tree, const int x, const int y, struct rect *clip, const struct redraw_context *ctx)
Redraw a treeview object.
nserror treeview_node_expand(treeview *tree, treeview_node *node)
Expand a treeview node.
nserror treeview_init(void)
Prepare treeview module for treeview usage.
nserror treeview_create_node_entry(treeview *tree, treeview_node **entry, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data fields[], void *data, treeview_node_options_flags flags)
Create an entry node in given treeview.
nserror treeview_expand(treeview *tree, bool only_folders)
Expand a treeview's nodes.
nserror treeview_update_node_folder(treeview *tree, treeview_node *folder, const struct treeview_field_data *field, void *data)
Update an folder node in given treeview.
Treeview handling interface.
@ TREE_MSG_NODE_EDIT
Node to be edited.
@ TREE_MSG_NODE_LAUNCH
Node to be launched.
@ TREE_MSG_NODE_DELETE
Node to be deleted.
treeview_node_type
treeview node type
@ TREE_NODE_ENTRY
Node is an entry.
@ TREE_NODE_FOLDER
Node is folder.
treeview_node_options_flags
Node change handling options.
@ TREE_OPTION_SUPPRESS_RESIZE
@ TREE_OPTION_SPECIAL_DIR
@ TREE_OPTION_SUPPRESS_REDRAW
@ TREE_FLAG_SEARCHABLE
Whether field is searchable.
@ TREE_FLAG_SHOW_NAME
Whether field name shown.
@ TREE_FLAG_COPY_TEXT
Whether to copy to clipb.
@ TREE_FLAG_ALLOW_EDIT
Whether allow edit field.
@ TREE_FLAG_DEFAULT
Whether field is default.
treeview_relationship
Relationship between nodes.
@ TREEVIEW_SEARCHABLE
Treeview has search bar.
nserror
Enumeration of error codes.
@ NSERROR_SAVE_FAILED
Failed to save data.
@ NSERROR_DOM
DOM call returned error.
@ NSERROR_UNKNOWN
Unknown error - DO NOT USE.
@ NSERROR_INVALID
Invalid data.
@ NSERROR_NOMEM
Memory exhaustion.
struct netsurf_table * guit
The global interface table.
Interface to core interface table.
Interface to platform-specific miscellaneous browser operation table.
browser_mouse_state
Mouse state.
@ BROWSER_MOUSE_MOD_2
2nd modifier key pressed (eg.
@ BROWSER_MOUSE_MOD_1
1st modifier key pressed (eg.
nserror libdom_iterate_child_elements(dom_node *parent, libdom_iterate_cb cb, void *ctx)
dom_node * libdom_find_first_element(dom_node *parent, lwc_string *element_name)
Search children of a node for first named element.
nserror libdom_parse_file(const char *filename, const char *encoding, dom_document **doc)
libdom utilities (implementation).
#define NSLOG(catname, level, logmsg, args...)
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Localised message support (interface).
NetSurf URL handling (interface).
bool nsurl_compare(const nsurl *url1, const nsurl *url2, nsurl_component parts)
Compare two URLs.
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
size_t nsurl_length(const nsurl *url)
Find the length of a NetSurf URL object's URL, as returned by nsurl_access.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Interface to utility string handling.
nserror(* schedule)(int t, void(*callback)(void *p), void *p)
Schedule a callback.
struct treeview_field_desc fields[HL_N_FIELDS]
struct hotlist_folder * default_folder
struct treeview_field_data data[HL_N_FIELDS - 1]
struct treeview_field_data data
hotlist_address_cb address_cb
hotlist_folder_leave_cb leave_cb
hotlist_folder_enter_cb enter_cb
enum treeview_relationship relshp
struct gui_misc_table * misc
Browser table.
Client callbacks for events concerning nodes.
nserror(* folder)(struct treeview_node_msg msg, void *data)
const char * value
Field value.
lwc_string * field
Field name.
size_t value_len
Field value length (bytes)
Treeview field description.
lwc_string * field
A treeview field name.
enum treeview_field_flags flags
Flags for field.
lwc_string * field
The field being edited.
union treeview_node_msg::@94 data
The message data.
const char * text
The proposed new value.
browser_mouse_state mouse
struct treeview_node_msg::@94::@97 node_launch
struct treeview_node_msg::@94::@96 node_edit
enum treeview_msg msg
The message type.
const struct url_data * data
unsigned int visits
Visit count.
time_t last_visit
Last visit time.
const char * title
Resource title.
const struct url_data * urldb_get_url_data(struct nsurl *url)
Find data for an URL.
nserror urldb_set_url_persistence(nsurl *url, bool persist)
Set the cross-session persistence of the entry for an URL.
bool urldb_add_url(nsurl *url)
Insert an URL into the database.
Unified URL information database internal interface.
nserror utf8_to_html(const char *string, const char *encname, size_t len, char **result_out)
Convert a UTF-8 encoded string into a string of the given encoding, applying HTML escape sequences wh...
UTF-8 manipulation functions (interface).
Interface to a number of general purpose functionality.
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.