netsurf: branch master updated. release/3.1-292-g1aed82b
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/1aed82b07428d17b74435...
...commit http://git.netsurf-browser.org/netsurf.git/commit/1aed82b07428d17b74435c2...
...tree http://git.netsurf-browser.org/netsurf.git/tree/1aed82b07428d17b74435c29a...
The branch, master has been updated
via 1aed82b07428d17b74435c29ac240de8288b85ab (commit)
via 846b53485474211a24248c9b0d5cc4205104a772 (commit)
via 01271f4061bbc8f8b26492a26e04bdbb8b9746c9 (commit)
from 0c5bb37bea878d6b0b622cb7ea6eab649e4c578b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=1aed82b07428d17b744...
commit 1aed82b07428d17b74435c29ac240de8288b85ab
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
fix warnings
diff --git a/amiga/launch.c b/amiga/launch.c
index 1405d6a..d3c9ff1 100755
--- a/amiga/launch.c
+++ b/amiga/launch.c
@@ -31,6 +31,7 @@
#include <proto/openurl.h>
#include "utils/nsoption.h"
+#include "utils/nsurl.h"
#include "utils/url.h"
struct Library *OpenURLBase = NULL;
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=846b53485474211a242...
commit 846b53485474211a24248c9b0d5cc4205104a772
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Recreate the entire menu when the hotlist window is closed.
This ensures the hotlist entries in the menu are in sync with reality, and mirrors the existing hotlist toolbar update.
diff --git a/amiga/gui.c b/amiga/gui.c
index 6e84e70..543a774 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -3030,7 +3030,10 @@ void ami_gui_hotlist_toolbar_update(struct gui_window_2 *gwin)
}
}
-void ami_gui_hotlist_toolbar_update_all(void)
+/**
+ * Update hotlist toolbar and recreate the menu for all windows
+ */
+void ami_gui_hotlist_update_all(void)
{
struct nsObject *node;
struct nsObject *nnode;
@@ -3047,6 +3050,7 @@ void ami_gui_hotlist_toolbar_update_all(void)
if(node->Type == AMINS_WINDOW)
{
ami_gui_hotlist_toolbar_update(gwin);
+ ami_menu_refresh(gwin);
}
} while(node = nnode);
}
diff --git a/amiga/gui.h b/amiga/gui.h
index 87258a1..c106455 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -162,7 +162,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
BOOL ami_gadget_hit(Object *obj, int x, int y);
void ami_gui_history(struct gui_window_2 *gwin, bool back);
-void ami_gui_hotlist_toolbar_update_all(void);
+void ami_gui_hotlist_update_all(void);
void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
diff --git a/amiga/menu.c b/amiga/menu.c
index c6258be..784fec1 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -485,14 +485,6 @@ struct NewMenu *ami_create_menu(struct gui_window_2 *gwin)
if(nsoption_bool(background_images) == true)
gwin->menu[M_IMGBACK].nm_Flags |= CHECKED;
- /* Set up scheduler to refresh the hotlist menu */
- if(nsoption_int(menu_refresh) > 0)
- {
- ami_schedule(nsoption_int(menu_refresh) * 10,
- (void *)ami_menu_refresh,
- gwin);
- }
-
return(gwin->menu);
}
diff --git a/amiga/options.h b/amiga/options.h
index e383dcf..868e28f 100644
--- a/amiga/options.h
+++ b/amiga/options.h
@@ -86,6 +86,4 @@ NSOPTION_INTEGER(redraw_tile_size_y, 0)
NSOPTION_INTEGER(monitor_aspect_x, 0)
NSOPTION_INTEGER(monitor_aspect_y, 0)
NSOPTION_BOOL(accept_lang_locale, true)
-NSOPTION_INTEGER(menu_refresh, 0)
-
diff --git a/amiga/tree.c b/amiga/tree.c
index 04c7996..18b071d 100644
--- a/amiga/tree.c
+++ b/amiga/tree.c
@@ -711,7 +711,7 @@ void ami_tree_close(struct treeview_window *twin)
ami_ssl_free(twin);
}
- ami_gui_hotlist_toolbar_update_all();
+ ami_gui_hotlist_update_all();
}
void ami_tree_update_quals(struct treeview_window *twin)
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=01271f4061bbc8f8b26...
commit 01271f4061bbc8f8b26492a26e04bdbb8b9746c9
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Re-enable favicon render hook. Not sure why or when this was disabled.
diff --git a/amiga/gui.c b/amiga/gui.c
index 8985d4f..6e84e70 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -3542,7 +3542,7 @@ gui_window_create(struct browser_window *bw,
SPACE_MinWidth, 16,
SPACE_MinHeight, 16,
SPACE_Transparent, FALSE,
- // SPACE_RenderHook, &g->shared->favicon_hook,
+ SPACE_RenderHook, &g->shared->favicon_hook,
SpaceEnd,
CHILD_WeightedWidth, 0,
CHILD_WeightedHeight, 0,
-----------------------------------------------------------------------
Summary of changes:
amiga/gui.c | 8 ++++++--
amiga/gui.h | 2 +-
amiga/launch.c | 1 +
amiga/menu.c | 8 --------
amiga/options.h | 2 --
amiga/tree.c | 2 +-
6 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/amiga/gui.c b/amiga/gui.c
index 8985d4f..543a774 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -3030,7 +3030,10 @@ void ami_gui_hotlist_toolbar_update(struct gui_window_2 *gwin)
}
}
-void ami_gui_hotlist_toolbar_update_all(void)
+/**
+ * Update hotlist toolbar and recreate the menu for all windows
+ */
+void ami_gui_hotlist_update_all(void)
{
struct nsObject *node;
struct nsObject *nnode;
@@ -3047,6 +3050,7 @@ void ami_gui_hotlist_toolbar_update_all(void)
if(node->Type == AMINS_WINDOW)
{
ami_gui_hotlist_toolbar_update(gwin);
+ ami_menu_refresh(gwin);
}
} while(node = nnode);
}
@@ -3542,7 +3546,7 @@ gui_window_create(struct browser_window *bw,
SPACE_MinWidth, 16,
SPACE_MinHeight, 16,
SPACE_Transparent, FALSE,
- // SPACE_RenderHook, &g->shared->favicon_hook,
+ SPACE_RenderHook, &g->shared->favicon_hook,
SpaceEnd,
CHILD_WeightedWidth, 0,
CHILD_WeightedHeight, 0,
diff --git a/amiga/gui.h b/amiga/gui.h
index 87258a1..c106455 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -162,7 +162,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
BOOL ami_gadget_hit(Object *obj, int x, int y);
void ami_gui_history(struct gui_window_2 *gwin, bool back);
-void ami_gui_hotlist_toolbar_update_all(void);
+void ami_gui_hotlist_update_all(void);
void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
diff --git a/amiga/launch.c b/amiga/launch.c
index 1405d6a..d3c9ff1 100755
--- a/amiga/launch.c
+++ b/amiga/launch.c
@@ -31,6 +31,7 @@
#include <proto/openurl.h>
#include "utils/nsoption.h"
+#include "utils/nsurl.h"
#include "utils/url.h"
struct Library *OpenURLBase = NULL;
diff --git a/amiga/menu.c b/amiga/menu.c
index c6258be..784fec1 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -485,14 +485,6 @@ struct NewMenu *ami_create_menu(struct gui_window_2 *gwin)
if(nsoption_bool(background_images) == true)
gwin->menu[M_IMGBACK].nm_Flags |= CHECKED;
- /* Set up scheduler to refresh the hotlist menu */
- if(nsoption_int(menu_refresh) > 0)
- {
- ami_schedule(nsoption_int(menu_refresh) * 10,
- (void *)ami_menu_refresh,
- gwin);
- }
-
return(gwin->menu);
}
diff --git a/amiga/options.h b/amiga/options.h
index e383dcf..868e28f 100644
--- a/amiga/options.h
+++ b/amiga/options.h
@@ -86,6 +86,4 @@ NSOPTION_INTEGER(redraw_tile_size_y, 0)
NSOPTION_INTEGER(monitor_aspect_x, 0)
NSOPTION_INTEGER(monitor_aspect_y, 0)
NSOPTION_BOOL(accept_lang_locale, true)
-NSOPTION_INTEGER(menu_refresh, 0)
-
diff --git a/amiga/tree.c b/amiga/tree.c
index 04c7996..18b071d 100644
--- a/amiga/tree.c
+++ b/amiga/tree.c
@@ -711,7 +711,7 @@ void ami_tree_close(struct treeview_window *twin)
ami_ssl_free(twin);
}
- ami_gui_hotlist_toolbar_update_all();
+ ami_gui_hotlist_update_all();
}
void ami_tree_update_quals(struct treeview_window *twin)
--
NetSurf Browser
9 years, 3 months
netsurf: branch master updated. release/3.1-289-g0c5bb37
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/0c5bb37bea878d6b0b622...
...commit http://git.netsurf-browser.org/netsurf.git/commit/0c5bb37bea878d6b0b622cb...
...tree http://git.netsurf-browser.org/netsurf.git/tree/0c5bb37bea878d6b0b622cb7e...
The branch, master has been updated
via 0c5bb37bea878d6b0b622cb7ea6eab649e4c578b (commit)
from dfc095bd900b37fb7e1ddb25fd2a85bf1839e41c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=0c5bb37bea878d6b0b6...
commit 0c5bb37bea878d6b0b622cb7ea6eab649e4c578b
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Implement a very basic favicon cache for the hotlist menu to use
diff --git a/amiga/bitmap.c b/amiga/bitmap.c
index f25ac2b..271978b 100644
--- a/amiga/bitmap.c
+++ b/amiga/bitmap.c
@@ -152,7 +152,9 @@ bool bitmap_save(void *bitmap, const char *path, unsigned flags)
int err = 0;
Object *dto = NULL;
- if(!ami_download_check_overwrite(path, NULL, 0)) return false;
+ if ((flags & AMI_BITMAP_FORCE_OVERWRITE) == 0) {
+ if(!ami_download_check_overwrite(path, NULL, 0)) return false;
+ }
if(dto = ami_datatype_object_from_bitmap(bitmap))
{
diff --git a/amiga/bitmap.h b/amiga/bitmap.h
index 0435aec..6657d2f 100755
--- a/amiga/bitmap.h
+++ b/amiga/bitmap.h
@@ -26,6 +26,7 @@
#include <libraries/Picasso96.h>
#define AMI_BITMAP_FORMAT RGBFB_R8G8B8A8
+#define AMI_BITMAP_FORCE_OVERWRITE 0xFF
struct bitmap {
int width;
diff --git a/amiga/gui.c b/amiga/gui.c
index 756ed63..8985d4f 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -181,6 +181,7 @@ bool cli_force = false;
static char *current_user;
static char *current_user_dir;
+static char *current_user_faviconcache;
static const __attribute__((used)) char *stack_cookie = "\0$STACK:262144\0";
@@ -2769,9 +2770,40 @@ static void gui_quit(void)
FreeVec(current_user_options);
FreeVec(current_user_dir);
+ FreeVec(current_user_faviconcache);
FreeVec(current_user);
}
+char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
+{
+ STRPTR filename = NULL;
+ BPTR lock = 0;
+
+ if (filename = ASPrintf("%s/%x", current_user_faviconcache, nsurl_hash(url))) {
+ LOG(("favicon cache location: %s", filename));
+
+ if (only_if_avail == true) {
+ if(lock = Lock(filename, ACCESS_READ)) {
+ UnLock(lock);
+ return filename;
+ }
+ } else {
+ return filename;
+ }
+ }
+ return NULL;
+}
+
+static void ami_gui_cache_favicon(nsurl *url, struct bitmap *favicon)
+{
+ STRPTR filename = NULL;
+
+ if (filename = ami_gui_get_cache_favicon_name(url, false)) {
+ if(favicon) bitmap_save(favicon, filename, AMI_BITMAP_FORCE_OVERWRITE);
+ FreeVec(filename);
+ }
+}
+
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin)
{
char *url;
@@ -2785,6 +2817,9 @@ void ami_gui_update_hotlist_button(struct gui_window_2 *gwin)
if(hotlist_has_url(nsurl)) {
RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
BUTTON_RenderImage, gwin->objects[GID_FAVE_RMV], TAG_DONE);
+
+ if (gwin->bw->window->favicon)
+ ami_gui_cache_favicon(nsurl, content_get_bitmap(gwin->bw->window->favicon));
} else {
RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
BUTTON_RenderImage, gwin->objects[GID_FAVE_ADD], TAG_DONE);
@@ -5127,8 +5162,10 @@ int main(int argc, char** argv)
current_user_options = ASPrintf("%s/Choices", current_user_dir);
current_user_cache = ASPrintf("%s/Cache", current_user_dir);
+ current_user_faviconcache = ASPrintf("%s/IconCache", current_user_dir);
if(lock = CreateDirTree(current_user_cache)) UnLock(lock);
+ if(lock = CreateDirTree(current_user_faviconcache)) UnLock(lock);
ami_mime_init("PROGDIR:Resources/mimetypes");
sprintf(temp, "%s/mimetypes.user", current_user_dir);
diff --git a/amiga/gui.h b/amiga/gui.h
index f5a9030..87258a1 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -167,6 +167,7 @@ void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin);
+char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail);
struct TextFont *origrpfont;
struct MinList *window_list;
diff --git a/amiga/menu.c b/amiga/menu.c
index 43c8c18..c6258be 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -405,6 +405,13 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
BITMAP_SourceFile, gwin->menuicon[i],
BITMAP_Masking, TRUE,
BitMapEnd;
+
+ /* \todo make this scale the bitmap to these dimensions */
+ SetAttrs(icon,
+ BITMAP_Width, 16,
+ BITMAP_Height, 16,
+ TAG_DONE);
+
GetAttr(IA_Width, icon, (ULONG *)&icon_width);
if((gwin->menutype[i] == NM_ITEM) && (gwin->menutype[i+1] == NM_SUB)) {
@@ -551,7 +558,7 @@ void ami_menu_arexx_scan(struct gui_window_2 *gwin)
static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char *title, nsurl *url, bool is_folder)
{
UBYTE type;
- char *icon;
+ STRPTR icon;
struct gui_window_2 *gw = (struct gui_window_2 *)userdata;
if(item >= AMI_MENU_HOTLIST_MAX) return false;
@@ -570,9 +577,10 @@ static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char
}
if(is_folder == true) {
- icon = "icons/directory.png";
+ icon = ASPrintf("icons/directory.png");
} else {
- icon = "icons/content.png";
+ icon = ami_gui_get_cache_favicon_name(url, true);
+ if (icon == NULL) icon = ASPrintf("icons/content.png");
}
ami_menu_alloc_item(gw, item, type, title,
@@ -580,6 +588,8 @@ static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char
if((is_folder == true) && (type == NM_SUB))
gw->menu[item].nm_Flags = NM_ITEMDISABLED;
+ if(icon) FreeVec(icon);
+
return true;
}
-----------------------------------------------------------------------
Summary of changes:
amiga/bitmap.c | 4 +++-
amiga/bitmap.h | 1 +
amiga/gui.c | 37 +++++++++++++++++++++++++++++++++++++
amiga/gui.h | 1 +
amiga/menu.c | 16 +++++++++++++---
5 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/amiga/bitmap.c b/amiga/bitmap.c
index f25ac2b..271978b 100644
--- a/amiga/bitmap.c
+++ b/amiga/bitmap.c
@@ -152,7 +152,9 @@ bool bitmap_save(void *bitmap, const char *path, unsigned flags)
int err = 0;
Object *dto = NULL;
- if(!ami_download_check_overwrite(path, NULL, 0)) return false;
+ if ((flags & AMI_BITMAP_FORCE_OVERWRITE) == 0) {
+ if(!ami_download_check_overwrite(path, NULL, 0)) return false;
+ }
if(dto = ami_datatype_object_from_bitmap(bitmap))
{
diff --git a/amiga/bitmap.h b/amiga/bitmap.h
index 0435aec..6657d2f 100755
--- a/amiga/bitmap.h
+++ b/amiga/bitmap.h
@@ -26,6 +26,7 @@
#include <libraries/Picasso96.h>
#define AMI_BITMAP_FORMAT RGBFB_R8G8B8A8
+#define AMI_BITMAP_FORCE_OVERWRITE 0xFF
struct bitmap {
int width;
diff --git a/amiga/gui.c b/amiga/gui.c
index 756ed63..8985d4f 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -181,6 +181,7 @@ bool cli_force = false;
static char *current_user;
static char *current_user_dir;
+static char *current_user_faviconcache;
static const __attribute__((used)) char *stack_cookie = "\0$STACK:262144\0";
@@ -2769,9 +2770,40 @@ static void gui_quit(void)
FreeVec(current_user_options);
FreeVec(current_user_dir);
+ FreeVec(current_user_faviconcache);
FreeVec(current_user);
}
+char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
+{
+ STRPTR filename = NULL;
+ BPTR lock = 0;
+
+ if (filename = ASPrintf("%s/%x", current_user_faviconcache, nsurl_hash(url))) {
+ LOG(("favicon cache location: %s", filename));
+
+ if (only_if_avail == true) {
+ if(lock = Lock(filename, ACCESS_READ)) {
+ UnLock(lock);
+ return filename;
+ }
+ } else {
+ return filename;
+ }
+ }
+ return NULL;
+}
+
+static void ami_gui_cache_favicon(nsurl *url, struct bitmap *favicon)
+{
+ STRPTR filename = NULL;
+
+ if (filename = ami_gui_get_cache_favicon_name(url, false)) {
+ if(favicon) bitmap_save(favicon, filename, AMI_BITMAP_FORCE_OVERWRITE);
+ FreeVec(filename);
+ }
+}
+
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin)
{
char *url;
@@ -2785,6 +2817,9 @@ void ami_gui_update_hotlist_button(struct gui_window_2 *gwin)
if(hotlist_has_url(nsurl)) {
RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
BUTTON_RenderImage, gwin->objects[GID_FAVE_RMV], TAG_DONE);
+
+ if (gwin->bw->window->favicon)
+ ami_gui_cache_favicon(nsurl, content_get_bitmap(gwin->bw->window->favicon));
} else {
RefreshSetGadgetAttrs((struct Gadget *)gwin->objects[GID_FAVE], gwin->win, NULL,
BUTTON_RenderImage, gwin->objects[GID_FAVE_ADD], TAG_DONE);
@@ -5127,8 +5162,10 @@ int main(int argc, char** argv)
current_user_options = ASPrintf("%s/Choices", current_user_dir);
current_user_cache = ASPrintf("%s/Cache", current_user_dir);
+ current_user_faviconcache = ASPrintf("%s/IconCache", current_user_dir);
if(lock = CreateDirTree(current_user_cache)) UnLock(lock);
+ if(lock = CreateDirTree(current_user_faviconcache)) UnLock(lock);
ami_mime_init("PROGDIR:Resources/mimetypes");
sprintf(temp, "%s/mimetypes.user", current_user_dir);
diff --git a/amiga/gui.h b/amiga/gui.h
index f5a9030..87258a1 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -167,6 +167,7 @@ void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin);
+char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail);
struct TextFont *origrpfont;
struct MinList *window_list;
diff --git a/amiga/menu.c b/amiga/menu.c
index 43c8c18..c6258be 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -405,6 +405,13 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
BITMAP_SourceFile, gwin->menuicon[i],
BITMAP_Masking, TRUE,
BitMapEnd;
+
+ /* \todo make this scale the bitmap to these dimensions */
+ SetAttrs(icon,
+ BITMAP_Width, 16,
+ BITMAP_Height, 16,
+ TAG_DONE);
+
GetAttr(IA_Width, icon, (ULONG *)&icon_width);
if((gwin->menutype[i] == NM_ITEM) && (gwin->menutype[i+1] == NM_SUB)) {
@@ -551,7 +558,7 @@ void ami_menu_arexx_scan(struct gui_window_2 *gwin)
static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char *title, nsurl *url, bool is_folder)
{
UBYTE type;
- char *icon;
+ STRPTR icon;
struct gui_window_2 *gw = (struct gui_window_2 *)userdata;
if(item >= AMI_MENU_HOTLIST_MAX) return false;
@@ -570,9 +577,10 @@ static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char
}
if(is_folder == true) {
- icon = "icons/directory.png";
+ icon = ASPrintf("icons/directory.png");
} else {
- icon = "icons/content.png";
+ icon = ami_gui_get_cache_favicon_name(url, true);
+ if (icon == NULL) icon = ASPrintf("icons/content.png");
}
ami_menu_alloc_item(gw, item, type, title,
@@ -580,6 +588,8 @@ static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char
if((is_folder == true) && (type == NM_SUB))
gw->menu[item].nm_Flags = NM_ITEMDISABLED;
+ if(icon) FreeVec(icon);
+
return true;
}
--
NetSurf Browser
9 years, 3 months
netsurf: branch vince/fetchschedule created. release/3.1-284-g8944edd
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/8944edd649e74e4864f36...
...commit http://git.netsurf-browser.org/netsurf.git/commit/8944edd649e74e4864f36d7...
...tree http://git.netsurf-browser.org/netsurf.git/tree/8944edd649e74e4864f36d729...
The branch, vince/fetchschedule has been created
at 8944edd649e74e4864f36d7293921385ba5ca2c7 (commit)
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=8944edd649e74e4864f...
commit 8944edd649e74e4864f36d7293921385ba5ca2c7
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
convert all frontends to scheduled fetch operation
diff --git a/amiga/gui.c b/amiga/gui.c
index 756ed63..e2bb39c 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -2502,18 +2502,9 @@ void ami_get_msg(void)
ami_quit_netsurf_delayed();
}
-static void ami_gui_fetch_callback(void *p)
-{
- /* This doesn't need to do anything - the scheduled event will
- * send a message to trigger Wait() to return, thereby causing
- * the event function to return, and NetSurf to call
- * hlcache_poll() as part of the usual fetch/event loop.
- */
-}
static void gui_poll(bool active)
{
- if(active) ami_schedule(0, ami_gui_fetch_callback, NULL);
ami_get_msg();
}
diff --git a/atari/gui.c b/atari/gui.c
index 7cac90c..608d0d8 100644
--- a/atari/gui.c
+++ b/atari/gui.c
@@ -121,7 +121,7 @@ static void gui_poll(bool active)
aes_event_in.emi_tlow = schedule_run();
- if(active || rendering){
+ if(rendering){
aes_event_in.emi_tlow = nsoption_int(atari_gui_poll_timeout);
}
@@ -130,11 +130,10 @@ static void gui_poll(bool active)
printf("long poll!\n");
}
- if( !active ) {
if(input_window && input_window->root->redraw_slots.areas_used > 0) {
window_process_redraws(input_window->root);
}
- }
+
graf_mkstate(&mx, &my, &dummy, &dummy);
aes_event_in.emi_m1.g_x = mx;
diff --git a/beos/gui.cpp b/beos/gui.cpp
index db43745..8518ba1 100644
--- a/beos/gui.cpp
+++ b/beos/gui.cpp
@@ -46,7 +46,7 @@ extern "C" {
#include "content/content.h"
#include "content/content_protected.h"
#include "content/fetch.h"
-#include "content/fetchers/curl.h"
+#include "content/fetchers.h"
#include "content/fetchers/resource.h"
#include "content/hlcache.h"
#include "content/urldb.h"
@@ -702,32 +702,23 @@ void nsbeos_pipe_message_top(BMessage *message, BWindow *_this, struct beos_scaf
static void gui_poll(bool active)
{
- CURLMcode code;
fd_set read_fd_set, write_fd_set, exc_fd_set;
- int max_fd = 0;
+ int max_fd;
struct timeval timeout;
unsigned int fd_count = 0;
bool block = true;
bigtime_t next_schedule = 0;
- // handle early deadlines
- schedule_run();
+ /* get any active fetcher fd */
+ fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
- FD_ZERO(&read_fd_set);
- FD_ZERO(&write_fd_set);
- FD_ZERO(&exc_fd_set);
-
- if (active) {
- code = curl_multi_fdset(fetch_curl_multi,
- &read_fd_set,
- &write_fd_set,
- &exc_fd_set,
- &max_fd);
- assert(code == CURLM_OK);
- }
+ /* run the scheduler */
+ schedule_run();
// our own event pipe
FD_SET(sEventPipe[0], &read_fd_set);
+
+ /** @todo Check if this max_fd should have + 1 */
max_fd = MAX(max_fd, sEventPipe[0] + 1);
// If there are pending events elsewhere, we should not be blocking
@@ -741,8 +732,10 @@ static void gui_poll(bool active)
if (next_schedule < 0)
next_schedule = 0;
- } else //we're not allowed to sleep, there is other activity going on.
+ } else {//we're not allowed to sleep, there is other activity going on.
+ nsbeos_window_process_reformats();
block = false;
+ }
/*
LOG(("gui_poll: browser_reformat_pending:%d earliest_callback_timeout:%Ld"
@@ -767,11 +760,6 @@ static void gui_poll(bool active)
nsbeos_dispatch_event(message);
}
}
-
- schedule_run();
-
- if (browser_reformat_pending)
- nsbeos_window_process_reformats();
}
diff --git a/cocoa/gui.m b/cocoa/gui.m
index 1cb19a7..713f456 100644
--- a/cocoa/gui.m
+++ b/cocoa/gui.m
@@ -53,7 +53,7 @@ static void gui_poll(bool active)
{
cocoa_autorelease();
- NSEvent *event = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: active ? nil : [NSDate distantFuture]
+ NSEvent *event = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: [NSDate distantFuture]
inMode: NSDefaultRunLoopMode dequeue: YES];
if (nil != event) {
diff --git a/content/fetch.c b/content/fetch.c
index 10cac9b..3d1183a 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -61,6 +61,7 @@
/* Define this to turn on verbose fetch logging */
#undef DEBUG_FETCH_VERBOSE
+#define DEBUG_FETCH_VERBOSE
/** The maximum number of fetchers that can be added */
#define MAX_FETCHERS 8
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index 251326d..0632bf3 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -564,10 +564,6 @@ static void framebuffer_poll(bool active)
/* run the scheduler and discover how long to wait for the next event */
timeout = schedule_run();
- /* if active do not wait for event, return immediately */
- if (active)
- timeout = 0;
-
/* if redraws are pending do not wait for event, return immediately */
if (fbtk_get_redraw_pending(fbtk))
timeout = 0;
diff --git a/gtk/gui.c b/gtk/gui.c
index 7de448c..9cd89e6 100644
--- a/gtk/gui.c
+++ b/gtk/gui.c
@@ -33,13 +33,13 @@
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <curl/curl.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "content/content.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/fetchers/curl.h"
#include "content/fetchers/resource.h"
#include "content/hlcache.h"
@@ -485,51 +485,42 @@ static bool nslog_stream_configure(FILE *fptr)
static void nsgtk_poll(bool active)
{
- CURLMcode code;
fd_set read_fd_set, write_fd_set, exc_fd_set;
int max_fd;
GPollFD *fd_list[1000];
unsigned int fd_count = 0;
bool block = true;
+ fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+ for (int i = 0; i <= max_fd; i++) {
+ if (FD_ISSET(i, &read_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &write_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_OUT | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &exc_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ }
+
schedule_run();
- if (browser_reformat_pending)
+ if (browser_reformat_pending) {
+ nsgtk_window_process_reformats();
block = false;
-
- if (active) {
- FD_ZERO(&read_fd_set);
- FD_ZERO(&write_fd_set);
- FD_ZERO(&exc_fd_set);
- code = curl_multi_fdset(fetch_curl_multi,
- &read_fd_set,
- &write_fd_set,
- &exc_fd_set,
- &max_fd);
- assert(code == CURLM_OK);
- for (int i = 0; i <= max_fd; i++) {
- if (FD_ISSET(i, &read_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &write_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_OUT | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &exc_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- }
}
gtk_main_iteration_do(block);
@@ -539,10 +530,6 @@ static void nsgtk_poll(bool active)
free(fd_list[i]);
}
- schedule_run();
-
- if (browser_reformat_pending)
- nsgtk_window_process_reformats();
}
diff --git a/monkey/poll.c b/monkey/poll.c
index 414d458..d5b49f0 100644
--- a/monkey/poll.c
+++ b/monkey/poll.c
@@ -22,7 +22,7 @@
#include "desktop/gui.h"
#include "monkey/schedule.h"
#include "monkey/browser.h"
-#include "content/fetchers/curl.h"
+#include "content/fetchers.h"
#include "monkey/dispatch.h"
#include "monkey/poll.h"
@@ -90,58 +90,48 @@ monkey_prepare_input(void)
void
monkey_poll(bool active)
{
- CURLMcode code;
fd_set read_fd_set, write_fd_set, exc_fd_set;
int max_fd;
GPollFD *fd_list[1000];
unsigned int fd_count = 0;
bool block = true;
-
+
+ fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+ for (int i = 0; i <= max_fd; i++) {
+ if (FD_ISSET(i, &read_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ LOG(("Want to read %d", i));
+ }
+ if (FD_ISSET(i, &write_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_OUT | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ LOG(("Want to write %d", i));
+ }
+ if (FD_ISSET(i, &exc_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ LOG(("Want to check %d", i));
+ }
+ }
+
schedule_run();
- if (browser_reformat_pending)
+ if (browser_reformat_pending) {
+ monkey_window_process_reformats();
block = false;
-
- if (active) {
- FD_ZERO(&read_fd_set);
- FD_ZERO(&write_fd_set);
- FD_ZERO(&exc_fd_set);
- code = curl_multi_fdset(fetch_curl_multi,
- &read_fd_set,
- &write_fd_set,
- &exc_fd_set,
- &max_fd);
- assert(code == CURLM_OK);
- LOG(("maxfd from curl is %d", max_fd));
- for (int i = 0; i <= max_fd; i++) {
- if (FD_ISSET(i, &read_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG(("Want to read %d", i));
- }
- if (FD_ISSET(i, &write_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_OUT | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG(("Want to write %d", i));
- }
- if (FD_ISSET(i, &exc_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- LOG(("Want to check %d", i));
- }
- }
}
-
- LOG(("Iterate %sactive %sblocking", active?"":"in", block?"":"non-"));
+
+ LOG(("Iterate %sblocking", block?"":"non-"));
if (block) {
fprintf(stdout, "GENERIC POLL BLOCKING\n");
}
@@ -152,9 +142,5 @@ monkey_poll(bool active)
free(fd_list[i]);
}
- schedule_run();
-
- if (browser_reformat_pending)
- monkey_window_process_reformats();
}
diff --git a/riscos/gui.c b/riscos/gui.c
index 09f254b..00f6ebc 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -1852,24 +1852,19 @@ static void ro_gui_handle_event(wimp_event_no event, wimp_block *block)
/**
- * Poll the OS for events (RISC OS).
- *
- * \param active return as soon as possible
+ * Poll the RISC OS wimp for events.
*/
static void riscos_poll(bool active)
{
wimp_event_no event;
wimp_block block;
- const wimp_poll_flags mask = wimp_MASK_LOSE | wimp_MASK_GAIN |
- wimp_SAVE_FP;
+ const wimp_poll_flags mask = wimp_MASK_LOSE | wimp_MASK_GAIN | wimp_SAVE_FP;
os_t track_poll_offset;
/* Poll wimp. */
xhourglass_off();
track_poll_offset = ro_mouse_poll_interval();
- if (active) {
- event = wimp_poll(mask, &block, 0);
- } else if (sched_active || (track_poll_offset > 0) ||
+ if (sched_active || (track_poll_offset > 0) ||
browser_reformat_pending) {
os_t t = os_read_monotonic_time();
diff --git a/windows/gui.c b/windows/gui.c
index 21eff0e..824abad 100644
--- a/windows/gui.c
+++ b/windows/gui.c
@@ -107,10 +107,6 @@ static void win32_poll(bool active)
/* run the scheduler and discover how long to wait for the next event */
timeout = schedule_run();
- /* if active set timeout so message is not waited for */
- if (active)
- timeout = 0;
-
if (timeout == 0) {
bRet = PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE);
} else {
@@ -128,7 +124,6 @@ static void win32_poll(bool active)
}
}
-
if (bRet > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=1b7aa7ffe53843f072e...
commit 1b7aa7ffe53843f072e3de5e28bdf06faa7980b9
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
make fetchers scheduled
diff --git a/content/fetch.c b/content/fetch.c
index 13c7c65..10cac9b 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -37,9 +37,11 @@
#include <strings.h>
#include <time.h>
#include <libwapcaplet/libwapcaplet.h>
+#include <curl/curl.h>
#include "utils/config.h"
#include "desktop/netsurf.h"
+#include "desktop/gui_factory.h"
#include "utils/corestrings.h"
#include "utils/nsoption.h"
#include "utils/log.h"
@@ -63,7 +65,11 @@
/** The maximum number of fetchers that can be added */
#define MAX_FETCHERS 8
-bool fetch_active; /**< Fetches in progress, please call fetch_poll(). */
+#ifdef DEBUG_FETCH_VERBOSE
+#define FETCH_LOG(x) LOG(x)
+#else
+#define FETCH_LOG(x)
+#endif
/**
* Information about a fetcher for a given scheme.
@@ -129,7 +135,7 @@ static int get_fetcher_for_scheme(lwc_string *scheme)
scheme, &match) == lwc_error_ok) &&
(match == true)) {
return fetcherd;
- }
+ }
}
return -1;
}
@@ -140,10 +146,9 @@ static int get_fetcher_for_scheme(lwc_string *scheme)
static bool fetch_dispatch_job(struct fetch *fetch)
{
RING_REMOVE(queue_ring, fetch);
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("Attempting to start fetch %p, fetcher %p, url %s", fetch,
+ FETCH_LOG(("Attempting to start fetch %p, fetcher %p, url %s", fetch,
fetch->fetcher_handle, nsurl_access(fetch->url)));
-#endif
+
if (!fetchers[fetch->fetcherd].ops.start(fetch->fetcher_handle)) {
RING_INSERT(queue_ring, fetch); /* Put it back on the end of the queue */
return false;
@@ -191,56 +196,76 @@ static bool fetch_choose_and_dispatch(void)
return false;
}
-/**
- * Dispatch as many jobs as we have room to dispatch.
- */
-static void fetch_dispatch_jobs(void)
+static void dump_rings(void)
{
- int all_active, all_queued;
#ifdef DEBUG_FETCH_VERBOSE
struct fetch *q;
struct fetch *f;
-#endif
-
- if (!queue_ring)
- return; /* Nothing to do, the queue is empty */
- RING_GETSIZE(struct fetch, queue_ring, all_queued);
- RING_GETSIZE(struct fetch, fetch_ring, all_active);
-
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("queue_ring %i, fetch_ring %i", all_queued, all_active));
q = queue_ring;
if (q) {
do {
- LOG(("queue_ring: %s", q->url));
+ LOG(("queue_ring: %s", nsurl_access(q->url)));
q = q->r_next;
} while (q != queue_ring);
}
f = fetch_ring;
if (f) {
do {
- LOG(("fetch_ring: %s", f->url));
+ LOG(("fetch_ring: %s", nsurl_access(f->url)));
f = f->r_next;
} while (f != fetch_ring);
}
#endif
+}
+
+/**
+ * Dispatch as many jobs as we have room to dispatch.
+ *
+ * @return true if there are active fetchers that require polling else false.
+ */
+static bool fetch_dispatch_jobs(void)
+{
+ int all_active;
+ int all_queued;
+
+ RING_GETSIZE(struct fetch, queue_ring, all_queued);
+ RING_GETSIZE(struct fetch, fetch_ring, all_active);
+
+ FETCH_LOG(("queue_ring %i, fetch_ring %i", all_queued, all_active));
+ dump_rings();
- while ( all_queued && all_active < nsoption_int(max_fetchers) ) {
- /*LOG(("%d queued, %d fetching", all_queued, all_active));*/
- if (fetch_choose_and_dispatch()) {
+ while ((all_queued != 0) &&
+ (all_active < nsoption_int(max_fetchers)) &&
+ fetch_choose_and_dispatch()) {
all_queued--;
all_active++;
- } else {
- /* Either a dispatch failed or we ran out. Just stop */
- break;
+ FETCH_LOG(("%d queued, %d fetching",
+ all_queued, all_active));
+ }
+
+ FETCH_LOG(("Fetch ring is now %d elements.", all_active));
+ FETCH_LOG(("Queue ring is now %d elements.", all_queued));
+
+ return (all_active > 0);
+}
+
+static void fetcher_poll(void *unused)
+{
+ int fetcherd;
+
+ if (fetch_dispatch_jobs()) {
+ FETCH_LOG(("Polling fetchers"));
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if (fetchers[fetcherd].refcount > 0) {
+ /* fetcher present */
+ fetchers[fetcherd].ops.poll(fetchers[fetcherd].scheme);
+ }
}
+
+ /* schedule active fetchers to run again in 10ms */
+ guit->browser->schedule(10, fetcher_poll, NULL);
}
- fetch_active = (all_active > 0);
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("Fetch ring is now %d elements.", all_active));
- LOG(("Queue ring is now %d elements.", all_queued));
-#endif
}
/******************************************************************************
@@ -256,8 +281,6 @@ nserror fetcher_init(void)
fetch_resource_register();
fetch_about_register();
- fetch_active = false;
-
return NSERROR_OK;
}
@@ -304,6 +327,63 @@ fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
}
/* exported interface documented in content/fetch.h */
+nserror fetcher_fdset(fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ int *maxfd_out)
+{
+ CURLMcode code;
+ int maxfd;
+ int fetcherd; /* fetcher index */
+
+ if (!fetch_dispatch_jobs()) {
+ FETCH_LOG(("No jobs"));
+ *maxfd_out = -1;
+ return NSERROR_OK;
+ }
+
+ FETCH_LOG(("Polling fetchers"));
+
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if (fetchers[fetcherd].refcount > 0) {
+ /* fetcher present */
+ fetchers[fetcherd].ops.poll(fetchers[fetcherd].scheme);
+ }
+ }
+
+ FD_ZERO(read_fd_set);
+ FD_ZERO(write_fd_set);
+ FD_ZERO(except_fd_set);
+ code = curl_multi_fdset(fetch_curl_multi,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ &maxfd);
+ assert(code == CURLM_OK);
+
+ if (maxfd >= 0) {
+ /* change the scheduled poll to happen is a 1000ms as
+ * we assume fetching an fdset means the fetchers will
+ * be run by the client waking up on data available on
+ * the fd and re-calling fetcher_fdset() if this does
+ * not happen the fetch polling will continue as
+ * usual.
+ */
+ /** @note adjusting the schedule time is only done for
+ * curl currently. This is because as it is assumed to
+ * be the only fetcher that can possibly have fd to
+ * select on. All the other fetchers continue to need
+ * polling frequently.
+ */
+ guit->browser->schedule(1000, fetcher_poll, NULL);
+ }
+
+ *maxfd_out = maxfd;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in content/fetch.h */
struct fetch *
fetch_start(nsurl *url,
nsurl *referer,
@@ -336,9 +416,7 @@ fetch_start(nsurl *url,
return NULL;
}
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("fetch %p, url '%s'", fetch, nsurl_access(url)));
-#endif
+ FETCH_LOG(("fetch %p, url '%s'", fetch, nsurl_access(url)));
/* construct a new fetch structure */
fetch->callback = callback;
@@ -421,9 +499,15 @@ fetch_start(nsurl *url,
/* Rah, got it, so ref the fetcher. */
fetch_ref_fetcher(fetch->fetcherd);
- /* Dump us in the queue and ask the queue to run. */
+ /* Dump new fetch in the queue. */
RING_INSERT(queue_ring, fetch);
- fetch_dispatch_jobs();
+
+ /* Ask the queue to run. */
+ if (fetch_dispatch_jobs()) {
+ FETCH_LOG(("scheduling poll"));
+ /* schedule active fetchers to run again in 10ms */
+ guit->browser->schedule(10, fetcher_poll, NULL);
+ }
return fetch;
}
@@ -432,47 +516,31 @@ fetch_start(nsurl *url,
void fetch_abort(struct fetch *f)
{
assert(f);
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
+ FETCH_LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
nsurl_access(f->url)));
-#endif
fetchers[f->fetcherd].ops.abort(f->fetcher_handle);
}
/* exported interface documented in content/fetch.h */
void fetch_free(struct fetch *f)
{
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("Freeing fetch %p, fetcher %p", f, f->fetcher_handle));
-#endif
+ FETCH_LOG(("Freeing fetch %p, fetcher %p", f, f->fetcher_handle));
+
fetchers[f->fetcherd].ops.free(f->fetcher_handle);
fetch_unref_fetcher(f->fetcherd);
nsurl_unref(f->url);
- if (f->referer != NULL)
+ if (f->referer != NULL) {
nsurl_unref(f->referer);
- if (f->host != NULL)
+ }
+ if (f->host != NULL) {
lwc_string_unref(f->host);
+ }
free(f);
}
-/* exported interface documented in content/fetchers.h */
-void fetcher_poll(void)
-{
- int fetcherd;
-
- fetch_dispatch_jobs();
- if (fetch_active) {
- for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
- if (fetchers[fetcherd].refcount > 0) {
- /* fetcher present */
- fetchers[fetcherd].ops.poll(fetchers[fetcherd].scheme);
- }
- }
- }
-}
/* exported interface documented in content/fetch.h */
bool fetch_can_fetch(const nsurl *url)
@@ -589,7 +657,7 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
free(list->name);
free(list->value);
if (list->file) {
- LOG(("Freeing rawfile: %s", list->rawfile));
+ FETCH_LOG(("Freeing rawfile: %s", list->rawfile));
free(list->rawfile);
}
free(list);
@@ -607,12 +675,8 @@ fetch_send_callback(const fetch_msg *msg, struct fetch *fetch)
/* exported interface documented in content/fetch.h */
void fetch_remove_from_queues(struct fetch *fetch)
{
- int all_active;
-
-#ifdef DEBUG_FETCH_VERBOSE
- int all_queued;
- LOG(("Fetch %p, fetcher %p can be freed", fetch, fetch->fetcher_handle));
-#endif
+ FETCH_LOG(("Fetch %p, fetcher %p can be freed",
+ fetch, fetch->fetcher_handle));
/* Go ahead and free the fetch properly now */
if (fetch->fetch_is_active) {
@@ -621,15 +685,15 @@ void fetch_remove_from_queues(struct fetch *fetch)
RING_REMOVE(queue_ring, fetch);
}
- RING_GETSIZE(struct fetch, fetch_ring, all_active);
-
- fetch_active = (all_active > 0);
-
#ifdef DEBUG_FETCH_VERBOSE
- LOG(("Fetch ring is now %d elements.", all_active));
+ int all_active;
+ int all_queued;
+ RING_GETSIZE(struct fetch, fetch_ring, all_active);
RING_GETSIZE(struct fetch, queue_ring, all_queued);
+ LOG(("Fetch ring is now %d elements.", all_active));
+
LOG(("Queue ring is now %d elements.", all_queued));
#endif
}
@@ -638,9 +702,8 @@ void fetch_remove_from_queues(struct fetch *fetch)
/* exported interface documented in content/fetch.h */
void fetch_set_http_code(struct fetch *fetch, long http_code)
{
-#ifdef DEBUG_FETCH_VERBOSE
- LOG(("Setting HTTP code to %ld", http_code));
-#endif
+ FETCH_LOG(("Setting HTTP code to %ld", http_code));
+
fetch->http_code = http_code;
}
diff --git a/content/fetchers.h b/content/fetchers.h
index 6ca5224..3303379 100644
--- a/content/fetchers.h
+++ b/content/fetchers.h
@@ -23,14 +23,13 @@
#ifndef _NETSURF_DESKTOP_FETCHERS_H_
#define _NETSURF_DESKTOP_FETCHERS_H_
+#include <sys/select.h>
#include <libwapcaplet/libwapcaplet.h>
struct nsurl;
struct fetch_multipart_data;
struct fetch;
-extern bool fetch_active;
-
/**
* Fetcher operations API
*
@@ -86,6 +85,7 @@ struct fetcher_operation_table {
void (*finalise)(lwc_string *scheme);
};
+
/**
* Register a fetcher for a scheme
*
@@ -95,6 +95,7 @@ struct fetcher_operation_table {
*/
nserror fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops);
+
/**
* Initialise the fetchers.
*
@@ -102,6 +103,7 @@ nserror fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *op
*/
nserror fetcher_init(void);
+
/**
* Clean up for quit.
*
@@ -109,11 +111,31 @@ nserror fetcher_init(void);
*/
void fetcher_quit(void);
+
/**
- * Do some work on current fetches.
+ * Get the set of file descriptors the fetchers are currently using.
+ *
+ * This obtains the file descriptors the fetch system is using to
+ * obtain data. It will cause the fetchers to make progress, if
+ * possible, potentially completing fetches before requiring activity
+ * on file descriptors.
+ *
+ * If a set of descriptors is returned (maxfd is not -1) The caller is
+ * expected to wait on them (with select etc.) and continue to obtain
+ * the fdset with this call. This will switch the fetchers from polled
+ * mode to waiting for network activity which is much more efficient.
+ *
+ * \note If the caller does not subsequently obtain the fdset again
+ * the fetchers will fall back to the less efficient polled
+ * operation. The fallback to polled operation will only occour after
+ * a timeout which introduces additional delay.
*
- * Must be called regularly to make progress on fetches.
+ * \param read_fd_set[out] The fd set for read.
+ * \param write_fd_set[out] The fd set for write.
+ * \param except_fd_set[out] The fd set for exceptions.
+ * \param maxfd[out] The highest fd number in the set or -1 if no fd available.
+ * \return NSERROR_OK on success or appropriate error code.
*/
-void fetcher_poll(void);
+nserror fetcher_fdset(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, int *maxfd);
#endif
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 39c15b9..32b7189 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -500,9 +500,7 @@ bool fetch_curl_initiate_fetch(struct curl_fetch_info *fetch, CURL *handle)
/* add to the global curl multi handle */
codem = curl_multi_add_handle(fetch_curl_multi, fetch->curl_handle);
assert(codem == CURLM_OK || codem == CURLM_CALL_MULTI_PERFORM);
-
- guit->browser->schedule(10, (void *)fetch_curl_poll, NULL);
-
+
return true;
}
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index b0c338a..579648b 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -257,8 +257,7 @@ nserror netsurf_init(const char *messages, const char *store_path)
int netsurf_main_loop(void)
{
while (!netsurf_quit) {
- guit->browser->poll(fetch_active);
- fetcher_poll();
+ guit->browser->poll(false);
}
return 0;
@@ -310,5 +309,3 @@ void netsurf_exit(void)
LOG(("Exited successfully"));
}
-
-
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=4b2101ba6ab62ae26d8...
commit 4b2101ba6ab62ae26d82cc8b86e0e61e9c007156
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
clean up the fetcher factory and improve its API
diff --git a/amiga/Makefile.target b/amiga/Makefile.target
index c900274..ea765af 100644
--- a/amiga/Makefile.target
+++ b/amiga/Makefile.target
@@ -2,7 +2,7 @@
# Amiga target setup
# ----------------------------------------------------------------------------
-CFLAGS += -std=c99 -Dnsamiga -DFETCHER_CURLL_SCHEDULED
+CFLAGS += -std=c99 -Dnsamiga
ifneq ($(SUBTARGET),os3)
CFLAGS += -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__
diff --git a/beos/fetch_rsrc.cpp b/beos/fetch_rsrc.cpp
index 887be79..9461f5c 100644
--- a/beos/fetch_rsrc.cpp
+++ b/beos/fetch_rsrc.cpp
@@ -33,6 +33,7 @@
extern "C" {
#include "utils/config.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/urldb.h"
#include "desktop/netsurf.h"
#include "utils/nsoption.h"
@@ -358,6 +359,16 @@ void fetch_rsrc_register(void)
{
lwc_string *scheme;
int err;
+ const struct fetcher_operation_table fetcher_ops_rsrc = {
+ fetch_rsrc_initialise,
+ fetch_rsrc_can_fetch,
+ fetch_rsrc_setup,
+ fetch_rsrc_start,
+ fetch_rsrc_abort,
+ fetch_rsrc_free,
+ fetch_rsrc_poll,
+ fetch_rsrc_finalise
+ };
err = find_app_resources();
@@ -371,15 +382,7 @@ void fetch_rsrc_register(void)
"(couldn't intern \"rsrc\").");
}
- fetch_add_fetcher(scheme,
- fetch_rsrc_initialise,
- fetch_rsrc_can_fetch,
- fetch_rsrc_setup,
- fetch_rsrc_start,
- fetch_rsrc_abort,
- fetch_rsrc_free,
- fetch_rsrc_poll,
- fetch_rsrc_finalise);
+ fetcher_add(scheme, &fetcher_ops_rsrc);
}
void fetch_rsrc_unregister(void)
diff --git a/content/fetch.c b/content/fetch.c
index 4736670..13c7c65 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -19,12 +19,15 @@
*/
/** \file
- * Fetching of data from a URL (implementation).
+ * Implementation of fetching of data from a URL.
+ *
+ * The implementation is the fetch factory and the generic operations
+ * around the fetcher specific methods.
*
* Active fetches are held in the circular linked list ::fetch_ring. There may
* be at most ::option_max_fetchers_per_host active requests per Host: header.
* There may be at most ::option_max_fetchers active requests overall. Inactive
- * fetchers are stored in the ::queue_ring waiting for use.
+ * fetches are stored in the ::queue_ring waiting for use.
*/
#include <assert.h>
@@ -33,17 +36,9 @@
#include <string.h>
#include <strings.h>
#include <time.h>
-
#include <libwapcaplet/libwapcaplet.h>
#include "utils/config.h"
-#include "content/fetch.h"
-#include "content/fetchers/resource.h"
-#include "content/fetchers/about.h"
-#include "content/fetchers/curl.h"
-#include "content/fetchers/data.h"
-#include "content/fetchers/file.h"
-#include "content/urldb.h"
#include "desktop/netsurf.h"
#include "utils/corestrings.h"
#include "utils/nsoption.h"
@@ -53,27 +48,34 @@
#include "utils/utils.h"
#include "utils/ring.h"
+#include "content/fetch.h"
+#include "content/fetchers.h"
+#include "content/fetchers/resource.h"
+#include "content/fetchers/about.h"
+#include "content/fetchers/curl.h"
+#include "content/fetchers/data.h"
+#include "content/fetchers/file.h"
+#include "content/urldb.h"
+
/* Define this to turn on verbose fetch logging */
#undef DEBUG_FETCH_VERBOSE
-bool fetch_active; /**< Fetches in progress, please call fetch_poll(). */
+/** The maximum number of fetchers that can be added */
+#define MAX_FETCHERS 8
-/** Information about a fetcher for a given scheme. */
+bool fetch_active; /**< Fetches in progress, please call fetch_poll(). */
+
+/**
+ * Information about a fetcher for a given scheme.
+ */
typedef struct scheme_fetcher_s {
- lwc_string *scheme_name; /**< The scheme. */
- fetcher_can_fetch can_fetch; /**< Ensure an URL can be fetched. */
- fetcher_setup_fetch setup_fetch; /**< Set up a fetch. */
- fetcher_start_fetch start_fetch; /**< Start a fetch. */
- fetcher_abort_fetch abort_fetch; /**< Abort a fetch. */
- fetcher_free_fetch free_fetch; /**< Free a fetch. */
- fetcher_poll_fetcher poll_fetcher; /**< Poll this fetcher. */
- fetcher_finalise finaliser; /**< Clean up this fetcher. */
- int refcount; /**< When zero, clean up the fetcher. */
- struct scheme_fetcher_s *next_fetcher; /**< Next fetcher in the list. */
- struct scheme_fetcher_s *prev_fetcher; /**< Prev fetcher in the list. */
+ lwc_string *scheme; /**< The scheme. */
+
+ struct fetcher_operation_table ops; /**< The fetchers operations. */
+ int refcount; /**< When zero the fetcher is no longer in use. */
} scheme_fetcher;
-static scheme_fetcher *fetchers = NULL;
+static scheme_fetcher fetchers[MAX_FETCHERS];
/** Information for a single fetch. */
struct fetch {
@@ -85,44 +87,54 @@ struct fetch {
void *p; /**< Private data for callback. */
lwc_string *host; /**< Host part of URL, interned */
long http_code; /**< HTTP response code, or 0. */
- scheme_fetcher *ops; /**< Fetcher operations for this fetch,
- NULL if not set. */
+ int fetcherd; /**< Fetcher descriptor for this fetch */
void *fetcher_handle; /**< The handle for the fetcher. */
bool fetch_is_active; /**< This fetch is active. */
struct fetch *r_prev; /**< Previous active fetch in ::fetch_ring. */
struct fetch *r_next; /**< Next active fetch in ::fetch_ring. */
};
-static struct fetch *fetch_ring = 0; /**< Ring of active fetches. */
-static struct fetch *queue_ring = 0; /**< Ring of queued fetches */
-
-#define fetch_ref_fetcher(F) F->refcount++
+static struct fetch *fetch_ring = NULL; /**< Ring of active fetches. */
+static struct fetch *queue_ring = NULL; /**< Ring of queued fetches */
/******************************************************************************
* fetch internals *
******************************************************************************/
-static void fetch_unref_fetcher(scheme_fetcher *fetcher)
+static inline void fetch_ref_fetcher(int fetcherd)
{
- if (--fetcher->refcount == 0) {
- fetcher->finaliser(fetcher->scheme_name);
- lwc_string_unref(fetcher->scheme_name);
- if (fetcher == fetchers) {
- fetchers = fetcher->next_fetcher;
- if (fetchers)
- fetchers->prev_fetcher = NULL;
- } else {
- fetcher->prev_fetcher->next_fetcher =
- fetcher->next_fetcher;
- if (fetcher->next_fetcher != NULL)
- fetcher->next_fetcher->prev_fetcher =
- fetcher->prev_fetcher;
- }
- free(fetcher);
+ fetchers[fetcherd].refcount++;
+}
+
+static inline void fetch_unref_fetcher(int fetcherd)
+{
+ fetchers[fetcherd].refcount--;
+ if (fetchers[fetcherd].refcount == 0) {
+ fetchers[fetcherd].ops.finalise(fetchers[fetcherd].scheme);
+ lwc_string_unref(fetchers[fetcherd].scheme);
}
}
/**
+ * Find a suitable fetcher for a scheme.
+ */
+static int get_fetcher_for_scheme(lwc_string *scheme)
+{
+ int fetcherd;
+ bool match;
+
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if ((fetchers[fetcherd].refcount > 0) &&
+ (lwc_string_isequal(fetchers[fetcherd].scheme,
+ scheme, &match) == lwc_error_ok) &&
+ (match == true)) {
+ return fetcherd;
+ }
+ }
+ return -1;
+}
+
+/**
* Dispatch a single job
*/
static bool fetch_dispatch_job(struct fetch *fetch)
@@ -132,7 +144,7 @@ static bool fetch_dispatch_job(struct fetch *fetch)
LOG(("Attempting to start fetch %p, fetcher %p, url %s", fetch,
fetch->fetcher_handle, nsurl_access(fetch->url)));
#endif
- if (!fetch->ops->start_fetch(fetch->fetcher_handle)) {
+ if (!fetchers[fetch->fetcherd].ops.start(fetch->fetcher_handle)) {
RING_INSERT(queue_ring, fetch); /* Put it back on the end of the queue */
return false;
} else {
@@ -236,7 +248,7 @@ static void fetch_dispatch_jobs(void)
******************************************************************************/
/* exported interface documented in content/fetch.h */
-nserror fetch_init(void)
+nserror fetcher_init(void)
{
fetch_curl_register();
fetch_data_register();
@@ -249,76 +261,81 @@ nserror fetch_init(void)
return NSERROR_OK;
}
-/* exported interface documented in content/fetch.h */
-void fetch_quit(void)
+/* exported interface documented in content/fetchers.h */
+void fetcher_quit(void)
{
- while (fetchers != NULL) {
- if (fetchers->refcount != 1) {
- LOG(("Fetcher for scheme %s still active?!",
- lwc_string_data(fetchers->scheme_name)));
- /* We shouldn't do this, but... */
- fetchers->refcount = 1;
+ int fetcherd; /* fetcher index */
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if (fetchers[fetcherd].refcount > 0) {
+ /* assert if the fetcher is active at quit */
+ assert(fetchers[fetcherd].refcount == 1);
+
+ fetch_unref_fetcher(fetcherd);
}
- fetch_unref_fetcher(fetchers);
}
}
-/* exported interface documented in content/fetch.h */
-bool fetch_add_fetcher(lwc_string *scheme,
- fetcher_initialise initialiser,
- fetcher_can_fetch can_fetch,
- fetcher_setup_fetch setup_fetch,
- fetcher_start_fetch start_fetch,
- fetcher_abort_fetch abort_fetch,
- fetcher_free_fetch free_fetch,
- fetcher_poll_fetcher poll_fetcher,
- fetcher_finalise finaliser)
+/* exported interface documented in content/fetchers.h */
+nserror
+fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops)
{
- scheme_fetcher *new_fetcher;
- if (!initialiser(scheme))
- return false;
- new_fetcher = malloc(sizeof(scheme_fetcher));
- if (new_fetcher == NULL) {
- finaliser(scheme);
- return false;
+ int fetcherd;
+
+ /* find unused fetcher descriptor */
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if (fetchers[fetcherd].refcount == 0) {
+ break;
+ }
}
- new_fetcher->scheme_name = scheme;
- new_fetcher->refcount = 0;
- new_fetcher->can_fetch = can_fetch;
- new_fetcher->setup_fetch = setup_fetch;
- new_fetcher->start_fetch = start_fetch;
- new_fetcher->abort_fetch = abort_fetch;
- new_fetcher->free_fetch = free_fetch;
- new_fetcher->poll_fetcher = poll_fetcher;
- new_fetcher->finaliser = finaliser;
- new_fetcher->next_fetcher = fetchers;
- fetchers = new_fetcher;
- fetch_ref_fetcher(new_fetcher);
-
- return true;
+ if (fetcherd == MAX_FETCHERS) {
+ return NSERROR_INIT_FAILED;
+ }
+
+ if (!ops->initialise(scheme)) {
+ return NSERROR_INIT_FAILED;
+ }
+
+ fetchers[fetcherd].scheme = scheme;
+ fetchers[fetcherd].ops = *ops;
+
+ fetch_ref_fetcher(fetcherd);
+
+ return NSERROR_OK;
}
/* exported interface documented in content/fetch.h */
-struct fetch * fetch_start(nsurl *url, nsurl *referer,
- fetch_callback callback,
- void *p, bool only_2xx, const char *post_urlenc,
- const struct fetch_multipart_data *post_multipart,
- bool verifiable, bool downgrade_tls,
- const char *headers[])
+struct fetch *
+fetch_start(nsurl *url,
+ nsurl *referer,
+ fetch_callback callback,
+ void *p,
+ bool only_2xx,
+ const char *post_urlenc,
+ const struct fetch_multipart_data *post_multipart,
+ bool verifiable,
+ bool downgrade_tls,
+ const char *headers[])
{
struct fetch *fetch;
- scheme_fetcher *fetcher = fetchers;
lwc_string *scheme;
bool match;
fetch = malloc(sizeof (*fetch));
- if (fetch == NULL)
+ if (fetch == NULL) {
return NULL;
+ }
/* The URL we're fetching must have a scheme */
scheme = nsurl_get_component(url, NSURL_SCHEME);
assert(scheme != NULL);
+ /* try and obtain a fetcher for this scheme */
+ fetch->fetcherd = get_fetcher_for_scheme(scheme);
+ if (fetch->fetcherd == -1) {
+ lwc_string_unref(scheme);
+ return NULL;
+ }
+
#ifdef DEBUG_FETCH_VERBOSE
LOG(("fetch %p, url '%s'", fetch, nsurl_access(url)));
#endif
@@ -334,7 +351,6 @@ struct fetch * fetch_start(nsurl *url, nsurl *referer,
fetch->referer = NULL;
fetch->send_referer = false;
fetch->fetcher_handle = NULL;
- fetch->ops = NULL;
fetch->fetch_is_active = false;
fetch->host = nsurl_get_component(url, NSURL_HOST);
@@ -378,53 +394,38 @@ struct fetch * fetch_start(nsurl *url, nsurl *referer,
lwc_string_unref(ref_scheme);
}
- /* Pick the scheme ops */
- while (fetcher) {
- if ((lwc_string_isequal(fetcher->scheme_name, scheme,
- &match) == lwc_error_ok) && (match == true)) {
- fetch->ops = fetcher;
- break;
- }
- fetcher = fetcher->next_fetcher;
- }
+ /* these aren't needed past here */
+ lwc_string_unref(scheme);
- if (fetch->ops == NULL)
- goto failed;
+ /* try and set up the fetch */
+ fetch->fetcher_handle = fetchers[fetch->fetcherd].ops.setup(fetch, url,
+ only_2xx, downgrade_tls,
+ post_urlenc, post_multipart,
+ headers);
+ if (fetch->fetcher_handle == NULL) {
- /* Got a scheme fetcher, try and set up the fetch */
- fetch->fetcher_handle = fetch->ops->setup_fetch(fetch, url,
- only_2xx, downgrade_tls,
- post_urlenc, post_multipart,
- headers);
+ if (fetch->host != NULL)
+ lwc_string_unref(fetch->host);
- if (fetch->fetcher_handle == NULL)
- goto failed;
+ if (fetch->url != NULL)
+ nsurl_unref(fetch->url);
- /* Rah, got it, so ref the fetcher. */
- fetch_ref_fetcher(fetch->ops);
+ if (fetch->referer != NULL)
+ nsurl_unref(fetch->referer);
- /* these aren't needed past here */
- lwc_string_unref(scheme);
+ free(fetch);
+
+ return NULL;
+ }
+
+ /* Rah, got it, so ref the fetcher. */
+ fetch_ref_fetcher(fetch->fetcherd);
/* Dump us in the queue and ask the queue to run. */
RING_INSERT(queue_ring, fetch);
fetch_dispatch_jobs();
return fetch;
-
-failed:
- lwc_string_unref(scheme);
-
- if (fetch->host != NULL)
- lwc_string_unref(fetch->host);
- if (fetch->url != NULL)
- nsurl_unref(fetch->url);
- if (fetch->referer != NULL)
- nsurl_unref(fetch->referer);
-
- free(fetch);
-
- return NULL;
}
/* exported interface documented in content/fetch.h */
@@ -435,7 +436,7 @@ void fetch_abort(struct fetch *f)
LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
nsurl_access(f->url)));
#endif
- f->ops->abort_fetch(f->fetcher_handle);
+ fetchers[f->fetcherd].ops.abort(f->fetcher_handle);
}
/* exported interface documented in content/fetch.h */
@@ -444,8 +445,10 @@ void fetch_free(struct fetch *f)
#ifdef DEBUG_FETCH_VERBOSE
LOG(("Freeing fetch %p, fetcher %p", f, f->fetcher_handle));
#endif
- f->ops->free_fetch(f->fetcher_handle);
- fetch_unref_fetcher(f->ops);
+ fetchers[f->fetcherd].ops.free(f->fetcher_handle);
+
+ fetch_unref_fetcher(f->fetcherd);
+
nsurl_unref(f->url);
if (f->referer != NULL)
nsurl_unref(f->referer);
@@ -454,45 +457,37 @@ void fetch_free(struct fetch *f)
free(f);
}
-/* exported interface documented in content/fetch.h */
-void fetch_poll(void)
+/* exported interface documented in content/fetchers.h */
+void fetcher_poll(void)
{
- scheme_fetcher *fetcher = fetchers;
- scheme_fetcher *next_fetcher;
+ int fetcherd;
fetch_dispatch_jobs();
- if (!fetch_active)
- return; /* No point polling, there's no fetch active. */
- while (fetcher != NULL) {
- next_fetcher = fetcher->next_fetcher;
- if (fetcher->poll_fetcher != NULL) {
- /* LOG(("Polling fetcher for %s",
- lwc_string_data(fetcher->scheme_name))); */
- fetcher->poll_fetcher(fetcher->scheme_name);
+ if (fetch_active) {
+ for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
+ if (fetchers[fetcherd].refcount > 0) {
+ /* fetcher present */
+ fetchers[fetcherd].ops.poll(fetchers[fetcherd].scheme);
+ }
}
- fetcher = next_fetcher;
}
}
/* exported interface documented in content/fetch.h */
bool fetch_can_fetch(const nsurl *url)
{
- scheme_fetcher *fetcher = fetchers;
- bool match;
lwc_string *scheme = nsurl_get_component(url, NSURL_SCHEME);
+ int fetcherd;
- while (fetcher != NULL) {
- if (lwc_string_isequal(fetcher->scheme_name, scheme, &match) == lwc_error_ok && match == true) {
- break;
- }
+ fetcherd = get_fetcher_for_scheme(scheme);
+ lwc_string_unref(scheme);
- fetcher = fetcher->next_fetcher;
+ if (fetcherd == -1) {
+ return false;
}
- lwc_string_unref(scheme);
-
- return fetcher == NULL ? false : fetcher->can_fetch(url);
+ return fetchers[fetcherd].ops.acceptable(url);
}
/* exported interface documented in content/fetch.h */
diff --git a/content/fetch.h b/content/fetch.h
index f20b4f2..37539ef 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -25,8 +25,6 @@
#include <stdbool.h>
-#include <libwapcaplet/libwapcaplet.h>
-
#include "utils/config.h"
#include "utils/nsurl.h"
@@ -95,18 +93,9 @@ struct ssl_cert_info {
int cert_type; /**< Certificate type */
};
-extern bool fetch_active;
-
typedef void (*fetch_callback)(const fetch_msg *msg, void *p);
/**
- * Initialise the fetcher.
- *
- * @return NSERROR_OK or error code
- */
-nserror fetch_init(void);
-
-/**
* Start fetching data for the given URL.
*
* The function returns immediately. The fetch may be queued for later
@@ -137,19 +126,6 @@ struct fetch *fetch_start(nsurl *url, nsurl *referer,
*/
void fetch_abort(struct fetch *f);
-/**
- * Do some work on current fetches.
- *
- * Must be called regularly to make progress on fetches.
- */
-void fetch_poll(void);
-
-/**
- * Clean up for quit.
- *
- * Must be called before exiting.
- */
-void fetch_quit(void);
/**
* Check if a URL's scheme can be fetched.
@@ -162,9 +138,7 @@ bool fetch_can_fetch(const nsurl *url);
/**
* Change the callback function for a fetch.
*/
-void fetch_change_callback(struct fetch *fetch,
- fetch_callback callback,
- void *p);
+void fetch_change_callback(struct fetch *fetch, fetch_callback callback, void *p);
/**
* Get the HTTP response code.
@@ -225,41 +199,4 @@ const char *fetch_get_referer_to_send(struct fetch *fetch);
void fetch_set_cookie(struct fetch *fetch, const char *data);
-/* API for fetchers themselves */
-
-typedef bool (*fetcher_initialise)(lwc_string *scheme);
-typedef bool (*fetcher_can_fetch)(const nsurl *url);
-typedef void *(*fetcher_setup_fetch)(struct fetch *parent_fetch, nsurl *url,
- bool only_2xx, bool downgrade_tls, const char *post_urlenc,
- const struct fetch_multipart_data *post_multipart,
- const char **headers);
-typedef bool (*fetcher_start_fetch)(void *fetch);
-typedef void (*fetcher_abort_fetch)(void *fetch);
-typedef void (*fetcher_free_fetch)(void *fetch);
-typedef void (*fetcher_poll_fetcher)(lwc_string *scheme);
-typedef void (*fetcher_finalise)(lwc_string *scheme);
-
-/** Register a fetcher for a scheme
- *
- * \param scheme scheme fetcher is for (caller relinquishes ownership)
- * \param initialiser fetcher initialiser
- * \param can_fetch fetcher can fetch function
- * \param setup_fetch fetcher fetch setup function
- * \param start_fetch fetcher fetch start function
- * \param abort_fetch fetcher fetch abort function
- * \param free_fetch fetcher fetch free function
- * \param poll_fetcher fetcher poll function
- * \param finaliser fetcher finaliser
- * \return true iff success
- */
-bool fetch_add_fetcher(lwc_string *scheme,
- fetcher_initialise initialiser,
- fetcher_can_fetch can_fetch,
- fetcher_setup_fetch setup_fetch,
- fetcher_start_fetch start_fetch,
- fetcher_abort_fetch abort_fetch,
- fetcher_free_fetch free_fetch,
- fetcher_poll_fetcher poll_fetcher,
- fetcher_finalise finaliser);
-
#endif
diff --git a/content/fetchers.h b/content/fetchers.h
new file mode 100644
index 0000000..6ca5224
--- /dev/null
+++ b/content/fetchers.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2014 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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/>.
+ */
+
+/** \file content/fetchers.h
+ * Interface for fetchers factory.
+ */
+
+#ifndef _NETSURF_DESKTOP_FETCHERS_H_
+#define _NETSURF_DESKTOP_FETCHERS_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+struct nsurl;
+struct fetch_multipart_data;
+struct fetch;
+
+extern bool fetch_active;
+
+/**
+ * Fetcher operations API
+ *
+ * These are the operations a fetcher must implement.
+ */
+struct fetcher_operation_table {
+ /**
+ * The initialiser for the fetcher.
+ *
+ * Called once to initialise the fetcher.
+ */
+ bool (*initialise)(lwc_string *scheme);
+
+ /**
+ * can this fetcher accept a url.
+ *
+ * \param url the URL to check
+ * \return true if the fetcher can handle the url else false.
+ */
+ bool (*acceptable)(const struct nsurl *url);
+
+ /**
+ * Setup a fetch
+ */
+ void *(*setup)(struct fetch *parent_fetch, struct nsurl *url,
+ bool only_2xx, bool downgrade_tls, const char *post_urlenc,
+ const struct fetch_multipart_data *post_multipart,
+ const char **headers);
+
+ /**
+ * start a fetch.
+ */
+ bool (*start)(void *fetch);
+
+ /**
+ * abort a fetch.
+ */
+ void (*abort)(void *fetch);
+
+ /**
+ * free a fetch allocated through the setup method.
+ */
+ void (*free)(void *fetch);
+
+ /**
+ * poll a fetcher to let it make progress.
+ */
+ void (*poll)(lwc_string *scheme);
+
+ /**
+ * finalise the fetcher.
+ */
+ void (*finalise)(lwc_string *scheme);
+};
+
+/**
+ * Register a fetcher for a scheme
+ *
+ * \param scheme The scheme fetcher is for (caller relinquishes ownership)
+ * \param ops The operations for the fetcher.
+ * \return NSERROR_OK or appropriate error code.
+ */
+nserror fetcher_add(lwc_string *scheme, const struct fetcher_operation_table *ops);
+
+/**
+ * Initialise the fetchers.
+ *
+ * @return NSERROR_OK or error code
+ */
+nserror fetcher_init(void);
+
+/**
+ * Clean up for quit.
+ *
+ * Must be called before exiting.
+ */
+void fetcher_quit(void);
+
+/**
+ * Do some work on current fetches.
+ *
+ * Must be called regularly to make progress on fetches.
+ */
+void fetcher_poll(void);
+
+#endif
diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index 17f2209..8c4d29a 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -45,6 +45,7 @@
#include "utils/config.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/fetchers/about.h"
#include "content/urldb.h"
#include "desktop/netsurf.h"
@@ -837,17 +838,19 @@ static void fetch_about_poll(lwc_string *scheme)
} while ( (c = next) != ring && ring != NULL);
}
-void fetch_about_register(void)
+nserror fetch_about_register(void)
{
lwc_string *scheme = lwc_string_ref(corestring_lwc_about);
-
- fetch_add_fetcher(scheme,
- fetch_about_initialise,
- fetch_about_can_fetch,
- fetch_about_setup,
- fetch_about_start,
- fetch_about_abort,
- fetch_about_free,
- fetch_about_poll,
- fetch_about_finalise);
+ const struct fetcher_operation_table fetcher_ops = {
+ .initialise = fetch_about_initialise,
+ .acceptable = fetch_about_can_fetch,
+ .setup = fetch_about_setup,
+ .start = fetch_about_start,
+ .abort = fetch_about_abort,
+ .free = fetch_about_free,
+ .poll = fetch_about_poll,
+ .finalise = fetch_about_finalise
+ };
+
+ return fetcher_add(scheme, &fetcher_ops);
}
diff --git a/content/fetchers/about.h b/content/fetchers/about.h
index f22be6a..9544971 100644
--- a/content/fetchers/about.h
+++ b/content/fetchers/about.h
@@ -23,6 +23,6 @@
#ifndef NETSURF_CONTENT_FETCHERS_FETCH_ABOUT_H
#define NETSURF_CONTENT_FETCHERS_FETCH_ABOUT_H
-void fetch_about_register(void);
+nserror fetch_about_register(void);
#endif
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 80ac5ec..39c15b9 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -53,12 +53,10 @@
#include "utils/file.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/fetchers/curl.h"
#include "content/urldb.h"
-/* uncomment this to use scheduler based calling
-#define FETCHER_CURLL_SCHEDULED 1
-*/
/** SSL certificate info */
struct cert_info {
@@ -160,6 +158,16 @@ void fetch_curl_register(void)
curl_version_info_data *data;
int i;
lwc_string *scheme;
+ const struct fetcher_operation_table fetcher_ops = {
+ .initialise = fetch_curl_initialise,
+ .acceptable = fetch_curl_can_fetch,
+ .setup = fetch_curl_setup,
+ .start = fetch_curl_start,
+ .abort = fetch_curl_abort,
+ .free = fetch_curl_free,
+ .poll = fetch_curl_poll,
+ .finalise = fetch_curl_finalise
+ };
LOG(("curl_version %s", curl_version()));
@@ -261,19 +269,7 @@ void fetch_curl_register(void)
continue;
}
- if (!fetch_add_fetcher(scheme,
- fetch_curl_initialise,
- fetch_curl_can_fetch,
- fetch_curl_setup,
- fetch_curl_start,
- fetch_curl_abort,
- fetch_curl_free,
-#ifdef FETCHER_CURLL_SCHEDULED
- NULL,
-#else
- fetch_curl_poll,
-#endif
- fetch_curl_finalise)) {
+ if (fetcher_add(scheme, &fetcher_ops) != NSERROR_OK) {
LOG(("Unable to register cURL fetcher for %s",
data->protocols[i]));
}
@@ -835,12 +831,6 @@ void fetch_curl_poll(lwc_string *scheme_ignored)
}
curl_msg = curl_multi_info_read(fetch_curl_multi, &queue);
}
-
-#ifdef FETCHER_CURLL_SCHEDULED
- if (running != 0) {
- guit->browser->schedule(10, fetch_curl_poll, fetch_curl_poll);
- }
-#endif
}
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index f7ae171..94ba638 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -31,6 +31,7 @@
#include "utils/config.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/fetchers/data.h"
#include "content/urldb.h"
#include "desktop/netsurf.h"
@@ -324,17 +325,19 @@ static void fetch_data_poll(lwc_string *scheme)
} while ( (c = next) != ring && ring != NULL);
}
-void fetch_data_register(void)
+nserror fetch_data_register(void)
{
lwc_string *scheme = lwc_string_ref(corestring_lwc_data);
-
- fetch_add_fetcher(scheme,
- fetch_data_initialise,
- fetch_data_can_fetch,
- fetch_data_setup,
- fetch_data_start,
- fetch_data_abort,
- fetch_data_free,
- fetch_data_poll,
- fetch_data_finalise);
+ const struct fetcher_operation_table fetcher_ops = {
+ .initialise = fetch_data_initialise,
+ .acceptable = fetch_data_can_fetch,
+ .setup = fetch_data_setup,
+ .start = fetch_data_start,
+ .abort = fetch_data_abort,
+ .free = fetch_data_free,
+ .poll = fetch_data_poll,
+ .finalise = fetch_data_finalise
+ };
+
+ return fetcher_add(scheme, &fetcher_ops);
}
diff --git a/content/fetchers/data.h b/content/fetchers/data.h
index 76f02cb..f6017e0 100644
--- a/content/fetchers/data.h
+++ b/content/fetchers/data.h
@@ -23,6 +23,6 @@
#ifndef NETSURF_CONTENT_FETCHERS_FETCH_DATA_H
#define NETSURF_CONTENT_FETCHERS_FETCH_DATA_H
-void fetch_data_register(void);
+nserror fetch_data_register(void);
#endif
diff --git a/content/fetchers/file.c b/content/fetchers/file.c
index 7834b27..f08be62 100644
--- a/content/fetchers/file.c
+++ b/content/fetchers/file.c
@@ -55,6 +55,7 @@
#include "content/dirlist.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/urldb.h"
#include "content/fetchers/file.h"
@@ -760,17 +761,19 @@ static void fetch_file_poll(lwc_string *scheme)
} while ( (c = next) != ring && ring != NULL);
}
-void fetch_file_register(void)
+nserror fetch_file_register(void)
{
lwc_string *scheme = lwc_string_ref(corestring_lwc_file);
-
- fetch_add_fetcher(scheme,
- fetch_file_initialise,
- fetch_file_can_fetch,
- fetch_file_setup,
- fetch_file_start,
- fetch_file_abort,
- fetch_file_free,
- fetch_file_poll,
- fetch_file_finalise);
+ const struct fetcher_operation_table fetcher_ops = {
+ .initialise = fetch_file_initialise,
+ .acceptable = fetch_file_can_fetch,
+ .setup = fetch_file_setup,
+ .start = fetch_file_start,
+ .abort = fetch_file_abort,
+ .free = fetch_file_free,
+ .poll = fetch_file_poll,
+ .finalise = fetch_file_finalise
+ };
+
+ return fetcher_add(scheme, &fetcher_ops);
}
diff --git a/content/fetchers/file.h b/content/fetchers/file.h
index d1621b9..b3c39db 100644
--- a/content/fetchers/file.h
+++ b/content/fetchers/file.h
@@ -23,6 +23,6 @@
#ifndef NETSURF_CONTENT_FETCHERS_FETCH_FILE_H
#define NETSURF_CONTENT_FETCHERS_FETCH_FILE_H
-void fetch_file_register(void);
+nserror fetch_file_register(void);
#endif
diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c
index 664c457..18e3021 100644
--- a/content/fetchers/resource.c
+++ b/content/fetchers/resource.c
@@ -37,16 +37,19 @@
#include <libwapcaplet/libwapcaplet.h>
#include "utils/config.h"
-#include "content/fetch.h"
-#include "content/fetchers/resource.h"
-#include "content/urldb.h"
-#include "desktop/gui_factory.h"
+#include "utils/errors.h"
#include "utils/corestrings.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/ring.h"
+#include "desktop/gui_factory.h"
+
+#include "content/fetch.h"
+#include "content/fetchers.h"
+#include "content/fetchers/resource.h"
+#include "content/urldb.h"
struct fetch_resource_context;
@@ -353,17 +356,19 @@ static void fetch_resource_poll(lwc_string *scheme)
} while ( (c = next) != ring && ring != NULL);
}
-void fetch_resource_register(void)
+nserror fetch_resource_register(void)
{
lwc_string *scheme = lwc_string_ref(corestring_lwc_resource);
-
- fetch_add_fetcher(scheme,
- fetch_resource_initialise,
- fetch_resource_can_fetch,
- fetch_resource_setup,
- fetch_resource_start,
- fetch_resource_abort,
- fetch_resource_free,
- fetch_resource_poll,
- fetch_resource_finalise);
+ const struct fetcher_operation_table fetcher_ops = {
+ .initialise = fetch_resource_initialise,
+ .acceptable = fetch_resource_can_fetch,
+ .setup = fetch_resource_setup,
+ .start = fetch_resource_start,
+ .abort = fetch_resource_abort,
+ .free = fetch_resource_free,
+ .poll = fetch_resource_poll,
+ .finalise = fetch_resource_finalise
+ };
+
+ return fetcher_add(scheme, &fetcher_ops);
}
diff --git a/content/fetchers/resource.h b/content/fetchers/resource.h
index 79d8e37..cf4d6ed 100644
--- a/content/fetchers/resource.h
+++ b/content/fetchers/resource.h
@@ -35,6 +35,6 @@
*
* should only be called from the fetch initialise
*/
-void fetch_resource_register(void);
+nserror fetch_resource_register(void);
#endif
diff --git a/content/hlcache.c b/content/hlcache.c
index e7c4cd8..0d79965 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -622,15 +622,6 @@ void hlcache_finalise(void)
}
/* See hlcache.h for documentation */
-nserror hlcache_poll(void)
-{
-
- llcache_poll();
-
- return NSERROR_OK;
-}
-
-/* See hlcache.h for documentation */
nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags,
nsurl *referer, llcache_post_data *post,
hlcache_handle_callback cb, void *pw,
diff --git a/content/hlcache.h b/content/hlcache.h
index 746b3c8..e0bf416 100644
--- a/content/hlcache.h
+++ b/content/hlcache.h
@@ -94,14 +94,6 @@ void hlcache_stop(void);
void hlcache_finalise(void);
/**
- * Drive the low-level cache poll loop, and attempt to clean the cache.
- * No guarantee is made about what, if any, cache cleaning will occur.
- *
- * \return NSERROR_OK
- */
-nserror hlcache_poll(void);
-
-/**
* Retrieve a high-level cache handle for an object
*
* \param url URL of the object to retrieve handle for
diff --git a/content/llcache.c b/content/llcache.c
index b241ab2..ad4d6d1 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -3087,14 +3087,6 @@ void llcache_finalise(void)
llcache = NULL;
}
-/* See llcache.h for documentation */
-nserror llcache_poll(void)
-{
- fetch_poll();
-
- return NSERROR_OK;
-}
-
/**
* Catch up the cache users with state changes from fetchers.
*
diff --git a/content/llcache.h b/content/llcache.h
index 4a35216..d4ed5f0 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -239,13 +239,6 @@ nserror llcache_initialise(const struct llcache_parameters *parameters);
void llcache_finalise(void);
/**
- * Cause the low-level cache to emit any pending notifications.
- *
- * \return NSERROR_OK on success, appropriate error otherwise.
- */
-nserror llcache_poll(void);
-
-/**
* Cause the low-level cache to attempt to perform cleanup.
*
* No guarantees are made as to whether or not cleanups will take
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index a1bc42b..b0c338a 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -29,7 +29,7 @@
#include "utils/config.h"
#include "utils/utsname.h"
#include "content/content_factory.h"
-#include "content/fetch.h"
+#include "content/fetchers.h"
#include "content/hlcache.h"
#include "content/mimesniff.h"
#include "content/urldb.h"
@@ -231,7 +231,7 @@ nserror netsurf_init(const char *messages, const char *store_path)
setlocale(LC_ALL, "C");
/* initialise the fetchers */
- ret = fetch_init();
+ ret = fetcher_init();
if (ret != NSERROR_OK)
return ret;
@@ -258,7 +258,7 @@ int netsurf_main_loop(void)
{
while (!netsurf_quit) {
guit->browser->poll(fetch_active);
- hlcache_poll();
+ fetcher_poll();
}
return 0;
@@ -285,7 +285,7 @@ void netsurf_exit(void)
hlcache_finalise();
LOG(("Closing fetches"));
- fetch_quit();
+ fetcher_quit();
mimesniff_fini();
diff --git a/render/html_css_fetcher.c b/render/html_css_fetcher.c
index 9bd3b21..3df1528 100644
--- a/render/html_css_fetcher.c
+++ b/render/html_css_fetcher.c
@@ -28,6 +28,7 @@
#include "utils/config.h"
#include "content/fetch.h"
+#include "content/fetchers.h"
#include "render/html_internal.h"
#include "utils/log.h"
#include "utils/ring.h"
@@ -276,6 +277,16 @@ static void html_css_fetcher_poll(lwc_string *scheme)
void html_css_fetcher_register(void)
{
lwc_string *scheme;
+ const struct fetcher_operation_table html_css_fetcher_ops = {
+ .initialise = html_css_fetcher_initialise,
+ .acceptable = html_css_fetcher_can_fetch,
+ .setup = html_css_fetcher_setup,
+ .start = html_css_fetcher_start,
+ .abort = html_css_fetcher_abort,
+ .free = html_css_fetcher_free,
+ .poll = html_css_fetcher_poll,
+ .finalise = html_css_fetcher_finalise
+ };
if (lwc_intern_string("x-ns-css", SLEN("x-ns-css"),
&scheme) != lwc_error_ok) {
@@ -283,15 +294,7 @@ void html_css_fetcher_register(void)
"(couldn't intern \"x-ns-css\").");
}
- fetch_add_fetcher(scheme,
- html_css_fetcher_initialise,
- html_css_fetcher_can_fetch,
- html_css_fetcher_setup,
- html_css_fetcher_start,
- html_css_fetcher_abort,
- html_css_fetcher_free,
- html_css_fetcher_poll,
- html_css_fetcher_finalise);
+ fetcher_add(scheme, &html_css_fetcher_ops);
}
nserror html_css_fetcher_add_item(dom_string *data, nsurl *base_url,
-----------------------------------------------------------------------
--
NetSurf Browser
9 years, 3 months
libhubbub: branch rupindersingh/libhubbub updated. release/0.3.0-11-g1ffadd6
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libhubbub.git/shortlog/1ffadd66d36045a9d41...
...commit http://git.netsurf-browser.org/libhubbub.git/commit/1ffadd66d36045a9d41aa...
...tree http://git.netsurf-browser.org/libhubbub.git/tree/1ffadd66d36045a9d41aa25...
The branch, rupindersingh/libhubbub has been updated
via 1ffadd66d36045a9d41aa25f9c666596073894bb (commit)
from 6a7bafdc55c83c684e0ffb9fd9a9b89943e0d03d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libhubbub.git/commit/?id=1ffadd66d36045a9d...
commit 1ffadd66d36045a9d41aa25f9c666596073894bb
Author: Rupinder Singh Khokhar <rsk1coder99(a)gmail.com>
Commit: Rupinder Singh Khokhar <rsk1coder99(a)gmail.com>
Random rumblings-- unclean commit
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index 5157e66..e685e0e 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -225,7 +225,8 @@ hubbub_error process_character(hubbub_treebuilder *treebuilder,
if (treebuilder->context.frameset_ok) {
for (p = dummy.ptr; p < dummy.ptr + dummy.len; p++) {
if (*p != 0x0009 && *p != 0x000a &&
- *p != 0x000c && *p != 0x0020) {
+ *p != 0x000c && *p != 0x0020 &&
+ *p != 0x000d) {
treebuilder->context.frameset_ok = false;
break;
}
@@ -324,7 +325,7 @@ hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
} else if (type == AREA || type == BASEFONT ||
type == BGSOUND || type == BR ||
type == EMBED || type == IMG || type == INPUT ||
- type == PARAM || type == SPACER || type == WBR) {
+ type == PARAM || type == WBR) {
err = reconstruct_active_formatting_list(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -997,36 +998,6 @@ hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder,
if (err != HUBBUB_OK)
return err;
- treebuilder->tree_handler->ref_node(
- treebuilder->tree_handler->ctx,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node);
-
- err = formatting_list_append(treebuilder, token->data.tag.ns, BUTTON,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node,
- treebuilder->context.current_node);
- if (err != HUBBUB_OK) {
- hubbub_ns ns;
- element_type type;
- void *node;
-
- remove_node_from_dom(treebuilder,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node);
-
- element_stack_pop(treebuilder, &ns, &type, &node);
-
- /* Unref twice (once for stack, once for formatting list) */
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, node);
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, node);
-
- return err;
- }
-
treebuilder->context.frameset_ok = false;
return HUBBUB_OK;
@@ -1668,11 +1639,11 @@ hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder,
hubbub_error err;
/* Welcome to the adoption agency */
-
- while (true) {
+ uint32_t counter = 0;
+ while (counter++ < 8) {
element_context *stack = treebuilder->context.element_stack;
- formatting_list_entry *entry;
+ formatting_list_entry *entry = NULL;
uint32_t formatting_element;
uint32_t common_ancestor;
uint32_t furthest_block;
@@ -1843,6 +1814,7 @@ hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder,
/* 13 */
}
+ return HUBBUB_OK;
}
/**
@@ -1861,10 +1833,13 @@ hubbub_error aa_find_and_validate_formatting_element(
formatting_list_entry *entry;
entry = aa_find_formatting_element(treebuilder, type);
+ if (entry == NULL) {
+ return process_0generic_in_body(treebuilder, type);
+ }
- if (entry == NULL || (entry->stack_index != 0 &&
+ if (entry->stack_index != 0 &&
element_in_scope(treebuilder, entry->details.type,
- false) != entry->stack_index)) {
+ false) != entry->stack_index) {
/** \todo parse error */
return HUBBUB_OK;
}
@@ -2002,7 +1977,7 @@ hubbub_error aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
}
/**
- * Adoption agency: this is step 6
+ * Adoption agency: this is step 13
*
* \param treebuilder The treebuilder instance
* \param formatting_element The stack index of the formatting element
@@ -2018,7 +1993,7 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
{
hubbub_error err;
element_context *stack = treebuilder->context.element_stack;
- uint32_t node, last, fb;
+ uint32_t node, last, fb, counter = 0;
formatting_list_entry *node_entry;
node = last = fb = *furthest_block;
@@ -2026,6 +2001,7 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
while (true) {
void *reparented;
+ counter += 1;
/* i */
node--;
@@ -2037,6 +2013,25 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
break;
}
+ /* iii */
+ if (node == formatting_element)
+ break;
+
+ if(node_entry != NULL && counter > 3) {
+ hubbub_ns ons;
+ element_type otype;
+ void *onode;
+ uint32_t oindex;
+
+ err = formatting_list_remove(treebuilder, node_entry,
+ &ons, &otype, &onode, &oindex);
+ assert(err == HUBBUB_OK);
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, onode);
+ node_entry = NULL;
+
+ }
+
/* Node is not in list of active formatting elements */
if (node_entry == NULL) {
err = aa_remove_element_stack_item(treebuilder,
@@ -2055,9 +2050,6 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
continue;
}
- /* iii */
- if (node == formatting_element)
- break;
/* iv */
if (last == fb) {
@@ -2375,7 +2367,7 @@ hubbub_error process_0generic_in_body(hubbub_treebuilder *treebuilder,
uint32_t popped = 0;
element_type otype;
- close_implied_end_tags(treebuilder, UNKNOWN);
+ close_implied_end_tags(treebuilder, type);
while (treebuilder->context.current_node >= node) {
hubbub_ns ns;
diff --git a/src/treebuilder/in_foreign_content.c b/src/treebuilder/in_foreign_content.c
index d53be1f..fa68dfc 100644
--- a/src/treebuilder/in_foreign_content.c
+++ b/src/treebuilder/in_foreign_content.c
@@ -40,8 +40,6 @@ static const case_changes svg_attributes[] = {
{ S("contentstyletype"), "contentStyleType" },
{ S("diffuseconstant"), "diffuseConstant" },
{ S("edgemode"), "edgeMode" },
- { S("externalresourcesrequired"), "externalResourcesRequired" },
- { S("filterres"), "filterRes" },
{ S("filterunits"), "filterUnits" },
{ S("glyphref"), "glyphRef" },
{ S("gradienttransform"), "gradientTransform" },
@@ -110,6 +108,7 @@ static const case_changes svg_tagnames[] = {
{ S("fediffuselighting"), "feDiffuseLighting" },
{ S("fedisplacementmap"), "feDisplacementMap" },
{ S("fedistantlight"), "feDistantLight" },
+ { S("fedropshadow"), "feDropShadow"},
{ S("feflood"), "feFlood" },
{ S("fefunca"), "feFuncA" },
{ S("fefuncb"), "feFuncB" },
@@ -391,9 +390,15 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
hubbub_error err = HUBBUB_OK;
+ const uint8_t *c;
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
+ c = (token->data.character.ptr);
+ if(*c != '\t' && *c != '\r' && *c != ' ' && *c != '\n' && *c != '\f') {
+ treebuilder->context.frameset_ok = false;
+ }
+
err = append_text(treebuilder, &token->data.character);
break;
case HUBBUB_TOKEN_COMMENT:
@@ -409,11 +414,11 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
hubbub_ns cur_node_ns = treebuilder->context.element_stack[
treebuilder->context.current_node].ns;
- element_type cur_node = current_node(treebuilder);
+ // element_type cur_node = current_node(treebuilder);
element_type type = element_type_from_name(treebuilder,
&token->data.tag.name);
- if (cur_node_ns == HUBBUB_NS_HTML ||
+ /*if (cur_node_ns == HUBBUB_NS_HTML ||
(cur_node_ns == HUBBUB_NS_MATHML &&
(type != MGLYPH && type != MALIGNMARK) &&
(cur_node == MI || cur_node == MO ||
@@ -426,7 +431,7 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
cur_node == DESC ||
cur_node == TITLE))) {
err = process_as_in_secondary(treebuilder, token);
- } else if (type == B || type == BIG || type == BLOCKQUOTE ||
+ } else */if (type == B || type == BIG || type == BLOCKQUOTE ||
type == BODY || type == BR || type == CENTER ||
type == CODE || type == DD || type == DIV ||
type == DL || type == DT || type == EM ||
@@ -472,13 +477,15 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
} else {
hubbub_tag tag = token->data.tag;
- adjust_foreign_attributes(treebuilder, &tag);
-
if (cur_node_ns == HUBBUB_NS_SVG) {
adjust_svg_tagname(treebuilder, &tag);
adjust_svg_attributes(treebuilder, &tag);
+ } else if(cur_node_ns == HUBBUB_NS_MATHML) {
+ adjust_mathml_attributes(treebuilder, &tag);
}
+ adjust_foreign_attributes(treebuilder, &tag);
+
/* Set to the right namespace and insert */
tag.ns = cur_node_ns;
@@ -492,8 +499,29 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
}
break;
case HUBBUB_TOKEN_END_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+ uint32_t node;
+ element_context *stack = treebuilder->context.element_stack;
+
+ for (node = treebuilder->context.current_node; node > 0; node--) {
+ if(stack[node].type == type) {
+ hubbub_ns ns;
+ element_type type;
+ void *node_iterator;
+ while(node_iterator !=stack[node].node) {
+ element_stack_pop(treebuilder, &ns, &type, &node_iterator);
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node_iterator);
+ }
+ return HUBBUB_OK;
+ }
+ }
err = process_as_in_secondary(treebuilder, token);
- break;
+ }
+ break;
case HUBBUB_TOKEN_EOF:
foreign_break_out(treebuilder);
err = HUBBUB_REPROCESS;
diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h
index 58c21d6..1b59267 100644
--- a/src/treebuilder/internal.h
+++ b/src/treebuilder/internal.h
@@ -16,10 +16,10 @@ typedef enum
ADDRESS, AREA, ARTICLE, ASIDE, BASE, BASEFONT, BGSOUND, BLOCKQUOTE,
BODY, BR, CENTER, COL, COLGROUP, COMMAND, DATAGRID, DD, DETAILS,
DIALOG, DIR, DIV, DL, DT, EMBED, FIELDSET, FIGURE, FOOTER, FORM, FRAME,
- FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HEADER, HR, IFRAME, IMAGE, IMG,
- INPUT, ISINDEX, LI, LINK, LISTING, MENU, META, NAV, NOEMBED, NOFRAMES,
+ FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HEADER, HGROUP, HR, IFRAME, IMAGE, IMG,
+ INPUT, ISINDEX, LI, LINK, LISTING, MAIN, MENU, MENUITEM, META, NAV, NOEMBED, NOFRAMES,
NOSCRIPT, OL, OPTGROUP, OPTION, P, PARAM, PLAINTEXT, PRE, SCRIPT,
- SECTION, SELECT, SPACER, STYLE, TBODY, TEXTAREA, TFOOT, THEAD, TITLE,
+ SECTION, SELECT, SPACER, SOURCE, STYLE, SUMMARY, TBODY, TEMPLATE, TEXTAREA, TFOOT, THEAD, TITLE,
TR, UL, WBR,
/* Scoping */
APPLET, BUTTON, CAPTION, HTML, MARQUEE, OBJECT, TABLE, TD, TH,
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index a6a4b43..2358ff9 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -25,10 +25,12 @@ static const struct {
element_type type;
} name_type_map[] = {
{ S("address"), ADDRESS }, { S("area"), AREA },
+ { S("b"), B },
{ S("base"), BASE }, { S("basefont"), BASEFONT },
{ S("bgsound"), BGSOUND }, { S("blockquote"), BLOCKQUOTE },
{ S("body"), BODY }, { S("br"), BR },
{ S("center"), CENTER }, { S("col"), COL },
+ { S("code"), CODE },
{ S("colgroup"), COLGROUP }, { S("dd"), DD },
{ S("dir"), DIR }, { S("div"), DIV },
{ S("dl"), DL }, { S("dt"), DT },
@@ -519,13 +521,22 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
break;
/* The list of element types given in the spec here are the
- * scoping elements excluding TABLE and HTML. TABLE is handled
+ * scoping elements excluding TABLE and HTML and BUTTON. TABLE is handled
* in the previous conditional and HTML should only occur
* as the first node in the stack, which is never processed
* in this loop. */
- if (!in_table && (is_scoping_element(node_type) ||
- (node_type == FOREIGNOBJECT &&
- node_ns == HUBBUB_NS_SVG))) {
+ if (!in_table && node_type != BUTTON &&
+ (is_scoping_element(node_type) ||
+ (node_ns == HUBBUB_NS_SVG && (
+ node_type == FOREIGNOBJECT ||
+ node_type == DESC ||
+ node_type == TITLE)) ||
+ (node_ns ==HUBBUB_NS_MATHML && (
+ node_type == MI ||
+ node_type == MO ||
+ node_type == MN ||
+ node_type == MS ||
+ node_type == MTEXT)))) {
break;
}
}
@@ -1389,7 +1400,6 @@ hubbub_error formatting_list_remove(hubbub_treebuilder *treebuilder,
*type = entry->details.type;
*node = entry->details.node;
*stack_index = entry->stack_index;
-
if (entry->prev == NULL)
treebuilder->context.formatting_list = entry->next;
else
diff --git a/src/utils/string.c b/src/utils/string.c
index ce4f6a6..95e6232 100644
--- a/src/utils/string.c
+++ b/src/utils/string.c
@@ -56,3 +56,21 @@ bool hubbub_string_match_ci(const uint8_t *a, size_t a_len,
return true;
}
+
+/**
+ * Convert the string to lowercase
+ *
+ * \param str String to lower
+ * \param str_len Length of string
+ * \param ret Location to recieve the result
+ */
+void hubbub_string_lower(const uint8_t *str, size_t str_len,
+ uint8_t *ret, size_t *ret_len)
+{
+ while (str_len-- > 0) {
+ *(ret++) = *(str++);
+ *ret = *ret | 0x20;
+ }
+ *ret_len = str_len;
+ return;
+}
diff --git a/src/utils/string.h b/src/utils/string.h
index 2487428..c8e444d 100644
--- a/src/utils/string.h
+++ b/src/utils/string.h
@@ -16,4 +16,8 @@ bool hubbub_string_match(const uint8_t *a, size_t a_len,
bool hubbub_string_match_ci(const uint8_t *a, size_t a_len,
const uint8_t *b, size_t b_len);
+/** Convert string to all lowercase */
+void hubbub_string_lower(const uint8_t *str, size_t str_len,
+ uint8_t *ret, size_t *ret_len);
+
#endif
diff --git a/test/data/tree-construction/INDEX b/test/data/tree-construction/INDEX
index 7e7e38b..fa8cf72 100644
--- a/test/data/tree-construction/INDEX
+++ b/test/data/tree-construction/INDEX
@@ -2,8 +2,8 @@
#
# Test Description
-#adoption01.dat NA
-#adoption02.dat NA
+adoption01.dat NA
+adoption02.dat NA
#after-after-body.dat NA
#after-after-frameset.dat NA
#after-body.dat NA
diff --git a/test/data/tree-construction/tests1.dat b/test/data/tree-construction/tests1.dat
index f12e871..29508e5 100644
--- a/test/data/tree-construction/tests1.dat
+++ b/test/data/tree-construction/tests1.dat
@@ -1225,24 +1225,6 @@ Line1<br>Line2<br>Line3<br>Line4
| "aa"
#data
-<wbr><strike><code></strike><code><strike></code>
-#errors
-(1,5): expected-doctype-but-got-start-tag
-(1,28): adoption-agency-1.3
-(1,49): adoption-agency-1.3
-(1,49): expected-closing-tag-but-got-eof
-#document
-| <html>
-| <head>
-| <body>
-| <wbr>
-| <strike>
-| <code>
-| <code>
-| <code>
-| <strike>
-
-#data
<!DOCTYPE html><spacer>foo
#errors
(1,26): expected-closing-tag-but-got-eof
-----------------------------------------------------------------------
Summary of changes:
src/treebuilder/in_body.c | 78 ++++++++++++++-----------------
src/treebuilder/in_foreign_content.c | 44 +++++++++++++++---
src/treebuilder/internal.h | 6 +-
src/treebuilder/treebuilder.c | 20 ++++++--
src/utils/string.c | 18 +++++++
src/utils/string.h | 4 ++
test/data/tree-construction/INDEX | 4 +-
test/data/tree-construction/tests1.dat | 18 -------
8 files changed, 113 insertions(+), 79 deletions(-)
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index 5157e66..e685e0e 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -225,7 +225,8 @@ hubbub_error process_character(hubbub_treebuilder *treebuilder,
if (treebuilder->context.frameset_ok) {
for (p = dummy.ptr; p < dummy.ptr + dummy.len; p++) {
if (*p != 0x0009 && *p != 0x000a &&
- *p != 0x000c && *p != 0x0020) {
+ *p != 0x000c && *p != 0x0020 &&
+ *p != 0x000d) {
treebuilder->context.frameset_ok = false;
break;
}
@@ -324,7 +325,7 @@ hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
} else if (type == AREA || type == BASEFONT ||
type == BGSOUND || type == BR ||
type == EMBED || type == IMG || type == INPUT ||
- type == PARAM || type == SPACER || type == WBR) {
+ type == PARAM || type == WBR) {
err = reconstruct_active_formatting_list(treebuilder);
if (err != HUBBUB_OK)
return err;
@@ -997,36 +998,6 @@ hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder,
if (err != HUBBUB_OK)
return err;
- treebuilder->tree_handler->ref_node(
- treebuilder->tree_handler->ctx,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node);
-
- err = formatting_list_append(treebuilder, token->data.tag.ns, BUTTON,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node,
- treebuilder->context.current_node);
- if (err != HUBBUB_OK) {
- hubbub_ns ns;
- element_type type;
- void *node;
-
- remove_node_from_dom(treebuilder,
- treebuilder->context.element_stack[
- treebuilder->context.current_node].node);
-
- element_stack_pop(treebuilder, &ns, &type, &node);
-
- /* Unref twice (once for stack, once for formatting list) */
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, node);
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, node);
-
- return err;
- }
-
treebuilder->context.frameset_ok = false;
return HUBBUB_OK;
@@ -1668,11 +1639,11 @@ hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder,
hubbub_error err;
/* Welcome to the adoption agency */
-
- while (true) {
+ uint32_t counter = 0;
+ while (counter++ < 8) {
element_context *stack = treebuilder->context.element_stack;
- formatting_list_entry *entry;
+ formatting_list_entry *entry = NULL;
uint32_t formatting_element;
uint32_t common_ancestor;
uint32_t furthest_block;
@@ -1843,6 +1814,7 @@ hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder,
/* 13 */
}
+ return HUBBUB_OK;
}
/**
@@ -1861,10 +1833,13 @@ hubbub_error aa_find_and_validate_formatting_element(
formatting_list_entry *entry;
entry = aa_find_formatting_element(treebuilder, type);
+ if (entry == NULL) {
+ return process_0generic_in_body(treebuilder, type);
+ }
- if (entry == NULL || (entry->stack_index != 0 &&
+ if (entry->stack_index != 0 &&
element_in_scope(treebuilder, entry->details.type,
- false) != entry->stack_index)) {
+ false) != entry->stack_index) {
/** \todo parse error */
return HUBBUB_OK;
}
@@ -2002,7 +1977,7 @@ hubbub_error aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
}
/**
- * Adoption agency: this is step 6
+ * Adoption agency: this is step 13
*
* \param treebuilder The treebuilder instance
* \param formatting_element The stack index of the formatting element
@@ -2018,7 +1993,7 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
{
hubbub_error err;
element_context *stack = treebuilder->context.element_stack;
- uint32_t node, last, fb;
+ uint32_t node, last, fb, counter = 0;
formatting_list_entry *node_entry;
node = last = fb = *furthest_block;
@@ -2026,6 +2001,7 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
while (true) {
void *reparented;
+ counter += 1;
/* i */
node--;
@@ -2037,6 +2013,25 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
break;
}
+ /* iii */
+ if (node == formatting_element)
+ break;
+
+ if(node_entry != NULL && counter > 3) {
+ hubbub_ns ons;
+ element_type otype;
+ void *onode;
+ uint32_t oindex;
+
+ err = formatting_list_remove(treebuilder, node_entry,
+ &ons, &otype, &onode, &oindex);
+ assert(err == HUBBUB_OK);
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, onode);
+ node_entry = NULL;
+
+ }
+
/* Node is not in list of active formatting elements */
if (node_entry == NULL) {
err = aa_remove_element_stack_item(treebuilder,
@@ -2055,9 +2050,6 @@ hubbub_error aa_find_bookmark_location_reparenting_misnested(
continue;
}
- /* iii */
- if (node == formatting_element)
- break;
/* iv */
if (last == fb) {
@@ -2375,7 +2367,7 @@ hubbub_error process_0generic_in_body(hubbub_treebuilder *treebuilder,
uint32_t popped = 0;
element_type otype;
- close_implied_end_tags(treebuilder, UNKNOWN);
+ close_implied_end_tags(treebuilder, type);
while (treebuilder->context.current_node >= node) {
hubbub_ns ns;
diff --git a/src/treebuilder/in_foreign_content.c b/src/treebuilder/in_foreign_content.c
index d53be1f..fa68dfc 100644
--- a/src/treebuilder/in_foreign_content.c
+++ b/src/treebuilder/in_foreign_content.c
@@ -40,8 +40,6 @@ static const case_changes svg_attributes[] = {
{ S("contentstyletype"), "contentStyleType" },
{ S("diffuseconstant"), "diffuseConstant" },
{ S("edgemode"), "edgeMode" },
- { S("externalresourcesrequired"), "externalResourcesRequired" },
- { S("filterres"), "filterRes" },
{ S("filterunits"), "filterUnits" },
{ S("glyphref"), "glyphRef" },
{ S("gradienttransform"), "gradientTransform" },
@@ -110,6 +108,7 @@ static const case_changes svg_tagnames[] = {
{ S("fediffuselighting"), "feDiffuseLighting" },
{ S("fedisplacementmap"), "feDisplacementMap" },
{ S("fedistantlight"), "feDistantLight" },
+ { S("fedropshadow"), "feDropShadow"},
{ S("feflood"), "feFlood" },
{ S("fefunca"), "feFuncA" },
{ S("fefuncb"), "feFuncB" },
@@ -391,9 +390,15 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
hubbub_error err = HUBBUB_OK;
+ const uint8_t *c;
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
+ c = (token->data.character.ptr);
+ if(*c != '\t' && *c != '\r' && *c != ' ' && *c != '\n' && *c != '\f') {
+ treebuilder->context.frameset_ok = false;
+ }
+
err = append_text(treebuilder, &token->data.character);
break;
case HUBBUB_TOKEN_COMMENT:
@@ -409,11 +414,11 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
hubbub_ns cur_node_ns = treebuilder->context.element_stack[
treebuilder->context.current_node].ns;
- element_type cur_node = current_node(treebuilder);
+ // element_type cur_node = current_node(treebuilder);
element_type type = element_type_from_name(treebuilder,
&token->data.tag.name);
- if (cur_node_ns == HUBBUB_NS_HTML ||
+ /*if (cur_node_ns == HUBBUB_NS_HTML ||
(cur_node_ns == HUBBUB_NS_MATHML &&
(type != MGLYPH && type != MALIGNMARK) &&
(cur_node == MI || cur_node == MO ||
@@ -426,7 +431,7 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
cur_node == DESC ||
cur_node == TITLE))) {
err = process_as_in_secondary(treebuilder, token);
- } else if (type == B || type == BIG || type == BLOCKQUOTE ||
+ } else */if (type == B || type == BIG || type == BLOCKQUOTE ||
type == BODY || type == BR || type == CENTER ||
type == CODE || type == DD || type == DIV ||
type == DL || type == DT || type == EM ||
@@ -472,13 +477,15 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
} else {
hubbub_tag tag = token->data.tag;
- adjust_foreign_attributes(treebuilder, &tag);
-
if (cur_node_ns == HUBBUB_NS_SVG) {
adjust_svg_tagname(treebuilder, &tag);
adjust_svg_attributes(treebuilder, &tag);
+ } else if(cur_node_ns == HUBBUB_NS_MATHML) {
+ adjust_mathml_attributes(treebuilder, &tag);
}
+ adjust_foreign_attributes(treebuilder, &tag);
+
/* Set to the right namespace and insert */
tag.ns = cur_node_ns;
@@ -492,8 +499,29 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
}
break;
case HUBBUB_TOKEN_END_TAG:
+ {
+ element_type type = element_type_from_name(treebuilder,
+ &token->data.tag.name);
+ uint32_t node;
+ element_context *stack = treebuilder->context.element_stack;
+
+ for (node = treebuilder->context.current_node; node > 0; node--) {
+ if(stack[node].type == type) {
+ hubbub_ns ns;
+ element_type type;
+ void *node_iterator;
+ while(node_iterator !=stack[node].node) {
+ element_stack_pop(treebuilder, &ns, &type, &node_iterator);
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node_iterator);
+ }
+ return HUBBUB_OK;
+ }
+ }
err = process_as_in_secondary(treebuilder, token);
- break;
+ }
+ break;
case HUBBUB_TOKEN_EOF:
foreign_break_out(treebuilder);
err = HUBBUB_REPROCESS;
diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h
index 58c21d6..1b59267 100644
--- a/src/treebuilder/internal.h
+++ b/src/treebuilder/internal.h
@@ -16,10 +16,10 @@ typedef enum
ADDRESS, AREA, ARTICLE, ASIDE, BASE, BASEFONT, BGSOUND, BLOCKQUOTE,
BODY, BR, CENTER, COL, COLGROUP, COMMAND, DATAGRID, DD, DETAILS,
DIALOG, DIR, DIV, DL, DT, EMBED, FIELDSET, FIGURE, FOOTER, FORM, FRAME,
- FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HEADER, HR, IFRAME, IMAGE, IMG,
- INPUT, ISINDEX, LI, LINK, LISTING, MENU, META, NAV, NOEMBED, NOFRAMES,
+ FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HEADER, HGROUP, HR, IFRAME, IMAGE, IMG,
+ INPUT, ISINDEX, LI, LINK, LISTING, MAIN, MENU, MENUITEM, META, NAV, NOEMBED, NOFRAMES,
NOSCRIPT, OL, OPTGROUP, OPTION, P, PARAM, PLAINTEXT, PRE, SCRIPT,
- SECTION, SELECT, SPACER, STYLE, TBODY, TEXTAREA, TFOOT, THEAD, TITLE,
+ SECTION, SELECT, SPACER, SOURCE, STYLE, SUMMARY, TBODY, TEMPLATE, TEXTAREA, TFOOT, THEAD, TITLE,
TR, UL, WBR,
/* Scoping */
APPLET, BUTTON, CAPTION, HTML, MARQUEE, OBJECT, TABLE, TD, TH,
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index a6a4b43..2358ff9 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -25,10 +25,12 @@ static const struct {
element_type type;
} name_type_map[] = {
{ S("address"), ADDRESS }, { S("area"), AREA },
+ { S("b"), B },
{ S("base"), BASE }, { S("basefont"), BASEFONT },
{ S("bgsound"), BGSOUND }, { S("blockquote"), BLOCKQUOTE },
{ S("body"), BODY }, { S("br"), BR },
{ S("center"), CENTER }, { S("col"), COL },
+ { S("code"), CODE },
{ S("colgroup"), COLGROUP }, { S("dd"), DD },
{ S("dir"), DIR }, { S("div"), DIV },
{ S("dl"), DL }, { S("dt"), DT },
@@ -519,13 +521,22 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
break;
/* The list of element types given in the spec here are the
- * scoping elements excluding TABLE and HTML. TABLE is handled
+ * scoping elements excluding TABLE and HTML and BUTTON. TABLE is handled
* in the previous conditional and HTML should only occur
* as the first node in the stack, which is never processed
* in this loop. */
- if (!in_table && (is_scoping_element(node_type) ||
- (node_type == FOREIGNOBJECT &&
- node_ns == HUBBUB_NS_SVG))) {
+ if (!in_table && node_type != BUTTON &&
+ (is_scoping_element(node_type) ||
+ (node_ns == HUBBUB_NS_SVG && (
+ node_type == FOREIGNOBJECT ||
+ node_type == DESC ||
+ node_type == TITLE)) ||
+ (node_ns ==HUBBUB_NS_MATHML && (
+ node_type == MI ||
+ node_type == MO ||
+ node_type == MN ||
+ node_type == MS ||
+ node_type == MTEXT)))) {
break;
}
}
@@ -1389,7 +1400,6 @@ hubbub_error formatting_list_remove(hubbub_treebuilder *treebuilder,
*type = entry->details.type;
*node = entry->details.node;
*stack_index = entry->stack_index;
-
if (entry->prev == NULL)
treebuilder->context.formatting_list = entry->next;
else
diff --git a/src/utils/string.c b/src/utils/string.c
index ce4f6a6..95e6232 100644
--- a/src/utils/string.c
+++ b/src/utils/string.c
@@ -56,3 +56,21 @@ bool hubbub_string_match_ci(const uint8_t *a, size_t a_len,
return true;
}
+
+/**
+ * Convert the string to lowercase
+ *
+ * \param str String to lower
+ * \param str_len Length of string
+ * \param ret Location to recieve the result
+ */
+void hubbub_string_lower(const uint8_t *str, size_t str_len,
+ uint8_t *ret, size_t *ret_len)
+{
+ while (str_len-- > 0) {
+ *(ret++) = *(str++);
+ *ret = *ret | 0x20;
+ }
+ *ret_len = str_len;
+ return;
+}
diff --git a/src/utils/string.h b/src/utils/string.h
index 2487428..c8e444d 100644
--- a/src/utils/string.h
+++ b/src/utils/string.h
@@ -16,4 +16,8 @@ bool hubbub_string_match(const uint8_t *a, size_t a_len,
bool hubbub_string_match_ci(const uint8_t *a, size_t a_len,
const uint8_t *b, size_t b_len);
+/** Convert string to all lowercase */
+void hubbub_string_lower(const uint8_t *str, size_t str_len,
+ uint8_t *ret, size_t *ret_len);
+
#endif
diff --git a/test/data/tree-construction/INDEX b/test/data/tree-construction/INDEX
index 7e7e38b..fa8cf72 100644
--- a/test/data/tree-construction/INDEX
+++ b/test/data/tree-construction/INDEX
@@ -2,8 +2,8 @@
#
# Test Description
-#adoption01.dat NA
-#adoption02.dat NA
+adoption01.dat NA
+adoption02.dat NA
#after-after-body.dat NA
#after-after-frameset.dat NA
#after-body.dat NA
diff --git a/test/data/tree-construction/tests1.dat b/test/data/tree-construction/tests1.dat
index f12e871..29508e5 100644
--- a/test/data/tree-construction/tests1.dat
+++ b/test/data/tree-construction/tests1.dat
@@ -1225,24 +1225,6 @@ Line1<br>Line2<br>Line3<br>Line4
| "aa"
#data
-<wbr><strike><code></strike><code><strike></code>
-#errors
-(1,5): expected-doctype-but-got-start-tag
-(1,28): adoption-agency-1.3
-(1,49): adoption-agency-1.3
-(1,49): expected-closing-tag-but-got-eof
-#document
-| <html>
-| <head>
-| <body>
-| <wbr>
-| <strike>
-| <code>
-| <code>
-| <code>
-| <strike>
-
-#data
<!DOCTYPE html><spacer>foo
#errors
(1,26): expected-closing-tag-but-got-eof
--
HTML5 parser library
9 years, 3 months
libdom: branch rupindersingh/libdom updated. release/0.1.0-50-g2368ed2
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libdom.git/shortlog/2368ed205a9763573c6cea...
...commit http://git.netsurf-browser.org/libdom.git/commit/2368ed205a9763573c6cea8d...
...tree http://git.netsurf-browser.org/libdom.git/tree/2368ed205a9763573c6cea8df2...
The branch, rupindersingh/libdom has been updated
discards c51674fb67f4bc7e1d0b09a515eaab40628e262c (commit)
via 2368ed205a9763573c6cea8df23b8f1e0e6476e1 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (c51674fb67f4bc7e1d0b09a515eaab40628e262c)
\
N -- N -- N (2368ed205a9763573c6cea8df23b8f1e0e6476e1)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libdom.git/commit/?id=2368ed205a9763573c6c...
commit 2368ed205a9763573c6cea8df23b8f1e0e6476e1
Author: Rupinder Singh Khokhar <rsk1coder99(a)gmail.com>
Commit: Rupinder Singh Khokhar <rsk1coder99(a)gmail.com>
This tag gave me a headache for a day or two :P. The problem is that the parser isnt handling the isindex element properly. Most probably
diff --git a/Makefile b/Makefile
index 569e554..bcbc27b 100644
--- a/Makefile
+++ b/Makefile
@@ -134,6 +134,7 @@ INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/html_style_element.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/html_frameset_element.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/html_frame_element.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/html_iframe_element.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/html_isindex_element.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
diff --git a/include/dom/dom.h b/include/dom/dom.h
index 1392ee0..0dba25d 100644
--- a/include/dom/dom.h
+++ b/include/dom/dom.h
@@ -93,6 +93,7 @@
#include <dom/html/html_frameset_element.h>
#include <dom/html/html_frame_element.h>
#include <dom/html/html_iframe_element.h>
+#include <dom/html/html_isindex_element.h>
/* DOM Events header */
#include <dom/events/events.h>
diff --git a/include/dom/html/html_isindex_element.h b/include/dom/html/html_isindex_element.h
index 966b2d2..d41a149 100644
--- a/include/dom/html/html_isindex_element.h
+++ b/include/dom/html/html_isindex_element.h
@@ -9,6 +9,7 @@
#define dom_html_isindex_element_h_
#include <dom/core/exceptions.h>
+#include <dom/core/string.h>
struct dom_html_form_element;
diff --git a/src/html/Makefile b/src/html/Makefile
index 95550ab..c98ce9a 100644
--- a/src/html/Makefile
+++ b/src/html/Makefile
@@ -18,9 +18,8 @@ DIR_SOURCES := \
html_map_element.c html_script_element.c html_tablecaption_element.c \
html_tablecell_element.c html_tablecol_element.c html_tablesection_element.c \
html_table_element.c html_tablerow_element.c html_frameset_element.c \
- html_frame_element.c html_iframe_element.c
+ html_frame_element.c html_iframe_element.c html_isindex_element.c \
UNINMPLEMENTED_SOURCES := \
- html_isindex_element.c \
include $(NSBUILD)/Makefile.subdir
diff --git a/src/html/html_document.c b/src/html/html_document.c
index cd062a2..6adfedd 100644
--- a/src/html/html_document.c
+++ b/src/html/html_document.c
@@ -60,6 +60,7 @@
#include "html/html_frameset_element.h"
#include "html/html_frame_element.h"
#include "html/html_iframe_element.h"
+#include "html/html_isindex_element.h"
#include "core/attr.h"
#include "core/string.h"
@@ -378,6 +379,9 @@ _dom_html_document_create_element_internal(dom_html_document *html,
} else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_IFRAME])) {
exc = _dom_html_iframe_element_create(html, namespace, prefix,
(dom_html_iframe_element **) result);
+ } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_ISINDEX])) {
+ exc = _dom_html_isindex_element_create(html, namespace, prefix,
+ (dom_html_isindex_element **) result);
} else {
exc = _dom_html_element_create(html, tag_name, namespace,
prefix, result);
diff --git a/src/html/html_isindex_element.c b/src/html/html_isindex_element.c
index 6dc96b9..e79e011 100644
--- a/src/html/html_isindex_element.c
+++ b/src/html/html_isindex_element.c
@@ -7,9 +7,13 @@
#include <stdlib.h>
+#include <dom/html/html_isindex_element.h>
+
+#include "html/html_document.h"
#include "html/html_isindex_element.h"
#include "core/node.h"
+#include "core/attr.h"
#include "utils/utils.h"
static struct dom_element_protected_vtable _protect_vtable = {
@@ -22,55 +26,41 @@ static struct dom_element_protected_vtable _protect_vtable = {
/**
* Create a dom_html_isindex_element object
*
- * \param doc The document object
- * \param form The form element which contains this element
- * \param ele The returned element object
+ * \param doc The document object
+ * \param ele The returned element object
* \return DOM_NO_ERR on success, appropriate dom_exception on failure.
*/
dom_exception _dom_html_isindex_element_create(struct dom_html_document *doc,
- struct dom_html_form_element *form,
+ dom_string *namespace, dom_string *prefix,
struct dom_html_isindex_element **ele)
{
struct dom_node_internal *node;
-
*ele = malloc(sizeof(dom_html_isindex_element));
if (*ele == NULL)
return DOM_NO_MEM_ERR;
-
+
/* Set up vtables */
node = (struct dom_node_internal *) *ele;
node->base.vtable = &_dom_html_element_vtable;
node->vtable = &_protect_vtable;
- return _dom_html_isindex_element_initialise(doc, form, *ele);
+ return _dom_html_isindex_element_initialise(doc, namespace, prefix, *ele);
}
/**
* Initialise a dom_html_isindex_element object
*
- * \param doc The document object
- * \param form The form element which contains this element
- * \param ele The dom_html_isindex_element object
+ * \param doc The document object
+ * \param ele The dom_html_isindex_element object
* \return DOM_NO_ERR on success, appropriate dom_exception on failure.
*/
dom_exception _dom_html_isindex_element_initialise(struct dom_html_document *doc,
- struct dom_html_form_element *form,
+ dom_string *namespace, dom_string *prefix,
struct dom_html_isindex_element *ele)
{
- dom_string *name = NULL;
- dom_exception err;
-
- UNUSED(form);
-
- err = dom_string_create((const uint8_t *) "ISINDEX", SLEN("ISINDEX"),
- &name);
- if (err != DOM_NO_ERR)
- return err;
-
- err = _dom_html_element_initialise(doc, &ele->base, name, NULL, NULL);
- dom_string_unref(name);
-
- return err;
+ return _dom_html_element_initialise(doc, &ele->base,
+ doc->memoised[hds_ISINDEX],
+ namespace, prefix);
}
/**
@@ -125,7 +115,46 @@ dom_exception _dom_html_isindex_element_copy(dom_node_internal *old,
return _dom_html_element_copy(old, copy);
}
-
+/*-----------------------------------------------------------------------*/
+/* API functions */
+
+#define SIMPLE_GET(attr) \
+ dom_exception dom_html_isindex_element_get_##attr( \
+ dom_html_isindex_element *element, \
+ dom_string **attr) \
+ { \
+ dom_exception ret; \
+ dom_string *_memo_##attr; \
+ \
+ _memo_##attr = \
+ ((struct dom_html_document *) \
+ ((struct dom_node_internal *)element)->owner)->\
+ memoised[hds_##attr]; \
+ \
+ ret = dom_element_get_attribute(element, _memo_##attr, attr); \
+ \
+ return ret; \
+ }
+#define SIMPLE_SET(attr) \
+dom_exception dom_html_isindex_element_set_##attr( \
+ dom_html_isindex_element *element, \
+ dom_string *attr) \
+ { \
+ dom_exception ret; \
+ dom_string *_memo_##attr; \
+ \
+ _memo_##attr = \
+ ((struct dom_html_document *) \
+ ((struct dom_node_internal *)element)->owner)->\
+ memoised[hds_##attr]; \
+ \
+ ret = dom_element_set_attribute(element, _memo_##attr, attr); \
+ \
+ return ret; \
+ }
+
+#define SIMPLE_GET_SET(attr) SIMPLE_GET(attr) SIMPLE_SET(attr)
+SIMPLE_GET_SET(prompt);
/*-----------------------------------------------------------------------*/
/* Public APIs */
diff --git a/src/html/html_isindex_element.h b/src/html/html_isindex_element.h
index 12ad26e..a39170b 100644
--- a/src/html/html_isindex_element.h
+++ b/src/html/html_isindex_element.h
@@ -19,12 +19,12 @@ struct dom_html_isindex_element {
/* Create a dom_html_isindex_element object */
dom_exception _dom_html_isindex_element_create(struct dom_html_document *doc,
- struct dom_html_form_element *form,
+ dom_string *namespace, dom_string *prefix,
struct dom_html_isindex_element **ele);
/* Initialise a dom_html_isindex_element object */
dom_exception _dom_html_isindex_element_initialise(struct dom_html_document *doc,
- struct dom_html_form_element *form,
+ dom_string *namespace, dom_string *prefix,
struct dom_html_isindex_element *ele);
/* Finalise a dom_html_isindex_element object */
-----------------------------------------------------------------------
Summary of changes:
src/html/html_isindex_element.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/src/html/html_isindex_element.c b/src/html/html_isindex_element.c
index dd5ab3b..e79e011 100644
--- a/src/html/html_isindex_element.c
+++ b/src/html/html_isindex_element.c
@@ -30,13 +30,11 @@ static struct dom_element_protected_vtable _protect_vtable = {
* \param ele The returned element object
* \return DOM_NO_ERR on success, appropriate dom_exception on failure.
*/
-#include<stdio.h>
dom_exception _dom_html_isindex_element_create(struct dom_html_document *doc,
dom_string *namespace, dom_string *prefix,
struct dom_html_isindex_element **ele)
{
struct dom_node_internal *node;
- fprintf(stderr,"isindex created\n");
*ele = malloc(sizeof(dom_html_isindex_element));
if (*ele == NULL)
return DOM_NO_MEM_ERR;
--
Document Object Model library
9 years, 3 months
netsurf: branch master updated. release/3.1-288-gdfc095b
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/dfc095bd900b37fb7e1dd...
...commit http://git.netsurf-browser.org/netsurf.git/commit/dfc095bd900b37fb7e1ddb2...
...tree http://git.netsurf-browser.org/netsurf.git/tree/dfc095bd900b37fb7e1ddb25f...
The branch, master has been updated
via dfc095bd900b37fb7e1ddb25fd2a85bf1839e41c (commit)
from 80cc3266580e9fbd77f07b094f6248326cf2cee3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=dfc095bd900b37fb7e1...
commit dfc095bd900b37fb7e1ddb25fd2a85bf1839e41c
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Display U+FFFD for characters > U+FFFF.
diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c
index e514b12..4edb4ee 100644
--- a/framebuffer/font_internal.c
+++ b/framebuffer/font_internal.c
@@ -221,6 +221,12 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style)
unsigned int offset;
uint16_t g_offset;
+ /* Internal font has no glyphs beyond U+FFFF and there isn't
+ * space to render a >4 digit codepoint; just show replacement
+ * character. */
+ if (ucs4 > 0xffff)
+ ucs4 = 0xfffd;
+
switch (style) {
case FB_BOLD_ITALIC:
section = fb_bold_italic_section_table[ucs4 / 256];
-----------------------------------------------------------------------
Summary of changes:
framebuffer/font_internal.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c
index e514b12..4edb4ee 100644
--- a/framebuffer/font_internal.c
+++ b/framebuffer/font_internal.c
@@ -221,6 +221,12 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style)
unsigned int offset;
uint16_t g_offset;
+ /* Internal font has no glyphs beyond U+FFFF and there isn't
+ * space to render a >4 digit codepoint; just show replacement
+ * character. */
+ if (ucs4 > 0xffff)
+ ucs4 = 0xfffd;
+
switch (style) {
case FB_BOLD_ITALIC:
section = fb_bold_italic_section_table[ucs4 / 256];
--
NetSurf Browser
9 years, 3 months