mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +03:00
Experimental new frames code.
svn path=/trunk/netsurf/; revision=2906
This commit is contained in:
parent
b51f807fe3
commit
74fa727509
Binary file not shown.
Binary file not shown.
@ -363,6 +363,11 @@ Encoding1:detected
|
||||
Encoding2:from <meta>
|
||||
EncodingUnk:Unknown
|
||||
|
||||
# Misc
|
||||
#
|
||||
Selecting:Selecting
|
||||
FrameDrag:Resizing frames
|
||||
|
||||
|
||||
# Errors
|
||||
# ======
|
||||
@ -809,9 +814,10 @@ HelpContentConfig:\Tcontent configuration \w
|
||||
HelpContentConfig2:This indicates whether NetSurf will atempt to block advertisements on web pages|MIn rare circumstances, this option may cause valid content to be blocked too.
|
||||
HelpContentConfig3:This indicates whether NetSurf will stop web sites from automatically opening new windows on your desktop.
|
||||
HelpContentConfig4:This indicates whether NetSurf will allow external plug-ins to handle additional types of content, such as Flash.
|
||||
HelpContentConfig5:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig6:\Sclose this \w without saving changes.|M\Areturn the cache options to the last saved configuration.
|
||||
HelpContentConfig7:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
HelpContentConfig7:This indicates whether NetSurf will allow links to open in new windows.
|
||||
HelpContentConfig8:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig9:\Sclose this \w without saving changes.|M\Areturn the cache options to the last saved configuration.
|
||||
HelpContentConfig10:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
|
||||
HelpFontConfig:\font configuration \w
|
||||
HelpFontConfig3:\Tcurrently selected sans-serif font.|MNetSurf will use this font wherever a web page specifies a sans-serif typeface.
|
||||
|
Binary file not shown.
@ -363,6 +363,11 @@ Encoding1:detected
|
||||
Encoding2:from <meta>
|
||||
EncodingUnk:Unknown
|
||||
|
||||
# Misc
|
||||
#
|
||||
Selecting:Selecting
|
||||
FrameDrag:Resizing frames
|
||||
|
||||
|
||||
# Errors
|
||||
# ======
|
||||
@ -809,9 +814,10 @@ HelpContentConfig:\Tcontent configuration \w
|
||||
HelpContentConfig2:This indicates whether NetSurf will attempt to block advertisements on web pages|MIn rare circumstances, this option may cause valid content to be blocked too.
|
||||
HelpContentConfig3:This indicates whether NetSurf will stop web sites from automatically opening new windows on your desktop.
|
||||
HelpContentConfig4:This indicates whether NetSurf will allow external plug-ins to handle additional types of content, such as Flash.
|
||||
HelpContentConfig5:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig6:\Sclose this \w without saving changes.|M\Areturn the content options to the last saved configuration.
|
||||
HelpContentConfig7:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
HelpContentConfig7:This indicates whether NetSurf will allow links to open in new windows.
|
||||
HelpContentConfig8:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig9:\Sclose this \w without saving changes.|M\Areturn the content options to the last saved configuration.
|
||||
HelpContentConfig10:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
|
||||
HelpFontConfig:\Tfont configuration \w
|
||||
HelpFontConfig3:\Tcurrently selected sans-serif font.|MNetSurf will use this font wherever a web page specifies a sans-serif typeface.
|
||||
|
Binary file not shown.
@ -363,6 +363,11 @@ Encoding1:détecté
|
||||
Encoding2:de <meta>
|
||||
EncodingUnk:Inconnu
|
||||
|
||||
# Misc
|
||||
#
|
||||
Selecting:Selecting
|
||||
FrameDrag:Resizing frames
|
||||
|
||||
|
||||
# Errors
|
||||
# ======
|
||||
@ -806,12 +811,13 @@ HelpConnectConfig28:\Sfermer cette fenêtre sans sauvegarder les changements.|M\
|
||||
HelpConnectConfig29:\Ssauver ces réglages et fermer la fenêtre.|M\Asauver ces réglages sans fermer la fenêtre.
|
||||
|
||||
HelpContentConfig:\Tla fenêtre de configuration du Contenu
|
||||
HelpContentConfig2:Ceci indique si Netsurf doit essayer de bloquer les pubs sur les pages web.|MEn de rares circonstances, cette option peut également bloquer du contenu valide.
|
||||
HelpContentConfig2:Ceci indique si Netsurf doit essayer de bloquer les pubs sur les pages web.|MEn de rares circonstances, cette option peut également bloquer du contenu valide.
|
||||
HelpContentConfig3:Ceci indique si Netsurf doit empêcher les sites web d'ouvrir automatiquement de nouvelles fenêtres sur votre Bureau.
|
||||
HelpContentConfig4:Ceci indique si Netsurf doit autoriser les plug-ins externes à manipuler des types de contenu supplémentaires, comme le Flash.
|
||||
HelpContentConfig5:\Srevenir aux valeurs par défaut des options du Contenu.
|
||||
HelpContentConfig6:\Sfermer cette fenêtre sans sauver les changements|M\Arevenir aux options de Contenu précédemment sauvegardées.
|
||||
HelpContentConfig7:\Ssauver ces réglages et fermer la fenêtre.|M\Asauver ces réglages sans fermer la fenêtre.
|
||||
HelpContentConfig7:This indicates whether NetSurf will allow links to open in new windows.
|
||||
HelpContentConfig8:\Srevenir aux valeurs par défaut des options du Contenu.
|
||||
HelpContentConfig9:\Sfermer cette fenêtre sans sauver les changements|M\Arevenir aux options de Contenu précédemment sauvegardées.
|
||||
HelpContentConfig10:\Ssauver ces réglages et fermer la fenêtre.|M\Asauver ces réglages sans fermer la fenêtre.
|
||||
|
||||
HelpFontConfig:\Tla fenêtre de configuration de Fontes
|
||||
HelpFontConfig3:\Tla fonte sans-sérif actuellement sélectionnée.|MNetsurf utilisera cette fonte à chaque fois qu'une page web spécifiera une police sans-sérif.
|
||||
|
Binary file not shown.
@ -363,6 +363,11 @@ Encoding1:detected
|
||||
Encoding2:from <meta>
|
||||
EncodingUnk:Unknown
|
||||
|
||||
# Misc
|
||||
#
|
||||
Selecting:Selecting
|
||||
FrameDrag:Resizing frames
|
||||
|
||||
|
||||
# Errors
|
||||
# ======
|
||||
@ -809,9 +814,10 @@ HelpContentConfig:\Tcontent configuration \w
|
||||
HelpContentConfig2:This indicates whether NetSurf will atempt to block advertisements on web pages|MIn rare circumstances, this option may cause valid content to be blocked too.
|
||||
HelpContentConfig3:This indicates whether NetSurf will stop web sites from automatically opening new windows on your desktop.
|
||||
HelpContentConfig4:This indicates whether NetSurf will allow external plug-ins to handle additional types of content, such as Flash.
|
||||
HelpContentConfig5:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig6:\Sclose this \w without saving changes.|M\Areturn the cache options to the last saved configuration.
|
||||
HelpContentConfig7:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
HelpContentConfig7:This indicates whether NetSurf will allow links to open in new windows.
|
||||
HelpContentConfig8:\Sreset the Content options back to their default values.
|
||||
HelpContentConfig9:\Sclose this \w without saving changes.|M\Areturn the cache options to the last saved configuration.
|
||||
HelpContentConfig10:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
|
||||
|
||||
HelpFontConfig:\font configuration \w
|
||||
HelpFontConfig3:\Tcurrently selected sans-serif font.|MNetSurf will use this font wherever a web page specifies a sans-serif typeface.
|
||||
|
Binary file not shown.
@ -816,7 +816,6 @@ void content_destroy(struct content *c)
|
||||
|
||||
if (c->type < HANDLER_MAP_COUNT && handler_map[c->type].destroy)
|
||||
handler_map[c->type].destroy(c);
|
||||
|
||||
talloc_free(c);
|
||||
}
|
||||
|
||||
@ -855,6 +854,7 @@ void content_quit(void)
|
||||
while (content_list && progress) {
|
||||
progress = false;
|
||||
for (c = content_list; c; c = next) {
|
||||
assert(c->next != c);
|
||||
next = c->next;
|
||||
|
||||
if (c->user_list->next &&
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "netsurf/image/bitmap.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/content/urldb.h"
|
||||
#include "netsurf/desktop/cookies.h"
|
||||
#include "netsurf/desktop/options.h"
|
||||
@ -89,6 +90,7 @@
|
||||
#include "netsurf/riscos/bitmap.h"
|
||||
#endif
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/filename.h"
|
||||
#include "netsurf/utils/url.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
@ -117,6 +119,10 @@ struct auth_data {
|
||||
* username:password */
|
||||
};
|
||||
|
||||
struct cache_internal_data {
|
||||
char filename[12]; /**< Cached filename, or first byte 0 for none */
|
||||
};
|
||||
|
||||
struct url_internal_data {
|
||||
char *title; /**< Resource title */
|
||||
unsigned int visits; /**< Visit count */
|
||||
@ -135,6 +141,7 @@ struct path_data {
|
||||
|
||||
struct bitmap *thumb; /**< Thumbnail image of resource */
|
||||
struct url_internal_data urld; /**< URL data for resource */
|
||||
struct cache_internal_data cache; /**< Cache data for resource */
|
||||
struct auth_data auth; /**< Authentication data for resource */
|
||||
struct cookie_internal_data *cookies; /**< Cookies associated with resource */
|
||||
|
||||
@ -3361,6 +3368,60 @@ void urldb_save_cookie_paths(FILE *fp, struct path_data *parent)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the content data associated with a particular URL
|
||||
*
|
||||
* \param url the URL to associate content with
|
||||
* \param content the content to associate
|
||||
* \return true on success, false otherwise
|
||||
*/
|
||||
bool urldb_set_cache_data(const char *url, const struct content *content) {
|
||||
struct path_data *p;
|
||||
char *filename;
|
||||
|
||||
assert(url && content);
|
||||
|
||||
p = urldb_find_url(url);
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
/* new filename needed */
|
||||
if (p->cache.filename[0] == 0) {
|
||||
filename = filename_request();
|
||||
if (!filename)
|
||||
return false;
|
||||
sprintf(p->cache.filename, filename);
|
||||
}
|
||||
|
||||
/* todo: save content, set cache data etc */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a file:// URL for the cached data associated with a URL
|
||||
*
|
||||
* \param url the URL to get the associated content for
|
||||
* \return a local URL allocated on heap, or NULL
|
||||
*/
|
||||
char *urldb_get_cache_data(const char *url) {
|
||||
struct path_data *p;
|
||||
|
||||
assert(url);
|
||||
|
||||
p = urldb_find_url(url);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
/* no file cache */
|
||||
if (p->cache.filename[0] == 0)
|
||||
return NULL;
|
||||
|
||||
/* todo: handle cache expiry etc */
|
||||
return filename_as_url(p->cache.filename);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_URLDB
|
||||
int option_expire_url = 0;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/content/content_type.h"
|
||||
|
||||
typedef enum {
|
||||
@ -100,4 +101,8 @@ void urldb_delete_cookie(const char *domain, const char *path, const char *name)
|
||||
void urldb_load_cookies(const char *filename);
|
||||
void urldb_save_cookies(const char *filename);
|
||||
|
||||
/* Cache */
|
||||
bool urldb_set_cache_data(const char *url, const struct content *content);
|
||||
char *urldb_get_cache_data(const char *url);
|
||||
|
||||
#endif
|
||||
|
1109
desktop/browser.c
1109
desktop/browser.c
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include "netsurf/render/html.h"
|
||||
|
||||
struct box;
|
||||
struct content;
|
||||
@ -38,6 +39,8 @@ typedef bool (*browser_paste_callback)(struct browser_window *bw,
|
||||
typedef void (*browser_move_callback)(struct browser_window *bw,
|
||||
void *p);
|
||||
|
||||
|
||||
|
||||
/** Browser window data. */
|
||||
struct browser_window {
|
||||
/** Page currently displayed, or 0. Must have status READY or DONE. */
|
||||
@ -84,20 +87,26 @@ struct browser_window {
|
||||
DRAGGING_HSCROLL,
|
||||
DRAGGING_SELECTION,
|
||||
DRAGGING_PAGE_SCROLL,
|
||||
DRAGGING_2DSCROLL
|
||||
DRAGGING_2DSCROLL,
|
||||
DRAGGING_FRAME
|
||||
} drag_type;
|
||||
|
||||
/** Box currently being scrolled, or 0. */
|
||||
struct box *scrolling_box;
|
||||
/** Mouse position at start of current scroll drag. */
|
||||
int scrolling_start_x;
|
||||
int scrolling_start_y;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
/** Scroll offsets at start of current scroll draw. */
|
||||
int scrolling_start_scroll_x;
|
||||
int scrolling_start_scroll_y;
|
||||
int drag_start_scroll_x;
|
||||
int drag_start_scroll_y;
|
||||
/** Well dimensions for current scroll drag. */
|
||||
int scrolling_well_width;
|
||||
int scrolling_well_height;
|
||||
int drag_well_width;
|
||||
int drag_well_height;
|
||||
/** Frame resize directions for current frame resize drag. */
|
||||
unsigned int drag_resize_left : 1;
|
||||
unsigned int drag_resize_right : 1;
|
||||
unsigned int drag_resize_up : 1;
|
||||
unsigned int drag_resize_down : 1;
|
||||
|
||||
/** Referer for current fetch, or 0. */
|
||||
char *referer;
|
||||
@ -107,6 +116,50 @@ struct browser_window {
|
||||
|
||||
/** Refresh interval (-1 if undefined) */
|
||||
int refresh_interval;
|
||||
|
||||
/** Window dimensions */
|
||||
int x0;
|
||||
int y0;
|
||||
int x1;
|
||||
int y1;
|
||||
|
||||
/** Window characteristics */
|
||||
enum {
|
||||
BROWSER_WINDOW_NORMAL,
|
||||
BROWSER_WINDOW_IFRAME,
|
||||
BROWSER_WINDOW_FRAME,
|
||||
BROWSER_WINDOW_FRAMESET,
|
||||
} browser_window_type;
|
||||
|
||||
/** frameset characteristics */
|
||||
int rows;
|
||||
int cols;
|
||||
|
||||
/** frame dimensions */
|
||||
struct frame_dimension frame_width;
|
||||
struct frame_dimension frame_height;
|
||||
int margin_width;
|
||||
int margin_height;
|
||||
|
||||
/** frame name for targetting */
|
||||
char *name;
|
||||
|
||||
/** frame characteristics */
|
||||
bool no_resize;
|
||||
frame_scrolling scrolling;
|
||||
bool border;
|
||||
colour border_colour;
|
||||
|
||||
/** iframe parent box */
|
||||
struct box *box;
|
||||
|
||||
/** [cols * rows] children */
|
||||
struct browser_window *children;
|
||||
struct browser_window *parent;
|
||||
|
||||
/** [iframe_count] iframes */
|
||||
int iframe_count;
|
||||
struct browser_window *iframes;
|
||||
};
|
||||
|
||||
|
||||
@ -129,6 +182,7 @@ extern struct browser_window *current_redraw_browser;
|
||||
|
||||
struct browser_window * browser_window_create(const char *url,
|
||||
struct browser_window *clone, char *referer, bool history_add);
|
||||
struct browser_window * browser_window_owner(struct browser_window *bw);
|
||||
void browser_window_go(struct browser_window *bw, const char *url,
|
||||
char *referer, bool history_add);
|
||||
void browser_window_go_post(struct browser_window *bw, const char *url,
|
||||
@ -139,6 +193,12 @@ void browser_window_stop(struct browser_window *bw);
|
||||
void browser_window_reload(struct browser_window *bw, bool all);
|
||||
void browser_window_destroy(struct browser_window *bw);
|
||||
void browser_window_update(struct browser_window *bw, bool scroll_to_top);
|
||||
void browser_window_create_iframes(struct browser_window *bw,
|
||||
struct content_html_iframe *iframe);
|
||||
void browser_window_recalculate_iframes(struct browser_window *bw);
|
||||
void browser_window_create_frameset(struct browser_window *bw,
|
||||
struct content_html_frames *frameset);
|
||||
void browser_window_recalculate_frameset(struct browser_window *bw);
|
||||
|
||||
void browser_window_mouse_click(struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y);
|
||||
|
@ -65,9 +65,12 @@ bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy);
|
||||
void gui_window_set_scroll(struct gui_window *g, int sx, int sy);
|
||||
void gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
|
||||
int x1, int y1);
|
||||
void gui_window_position_frame(struct gui_window *g, int x0, int y0,
|
||||
int x1, int y1);
|
||||
void gui_window_get_dimensions(struct gui_window *g, int *width, int *height);
|
||||
int gui_window_get_width(struct gui_window *g);
|
||||
int gui_window_get_height(struct gui_window *g);
|
||||
void gui_window_set_extent(struct gui_window *g, int width, int height);
|
||||
void gui_window_update_extent(struct gui_window *g);
|
||||
void gui_window_set_status(struct gui_window *g, const char *text);
|
||||
void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape);
|
||||
void gui_window_hide_pointer(struct gui_window *g);
|
||||
@ -81,6 +84,7 @@ bool gui_window_scroll_start(struct gui_window *g);
|
||||
bool gui_window_box_scroll_start(struct gui_window *g,
|
||||
int x0, int y0, int x1, int y1);
|
||||
void gui_window_save_as_link(struct gui_window *g, struct content *c);
|
||||
bool gui_window_frame_resize_start(struct gui_window *g);
|
||||
|
||||
struct gui_download_window *gui_download_window_create(const char *url,
|
||||
const char *mime_type, struct fetch *fetch,
|
||||
|
@ -33,12 +33,15 @@
|
||||
#define RIGHT_MARGIN 50
|
||||
#define BOTTOM_MARGIN 30
|
||||
|
||||
|
||||
/** A node in the history tree. */
|
||||
struct history_entry {
|
||||
struct history_page {
|
||||
char *url; /**< Page URL. */
|
||||
char *frag_id; /** Fragment identifier */
|
||||
char *title; /**< Page title. */
|
||||
};
|
||||
|
||||
/** A node in the history tree. */
|
||||
struct history_entry {
|
||||
struct history_page page;
|
||||
struct history_entry *back; /**< Parent. */
|
||||
struct history_entry *next; /**< Next sibling. */
|
||||
struct history_entry *forward; /**< First child. */
|
||||
@ -153,16 +156,16 @@ struct history_entry *history_clone_entry(struct history *history,
|
||||
if (!new_entry)
|
||||
return 0;
|
||||
memcpy(new_entry, entry, sizeof *entry);
|
||||
new_entry->url = strdup(entry->url);
|
||||
if (entry->frag_id)
|
||||
new_entry->frag_id = strdup(entry->frag_id);
|
||||
new_entry->title = strdup(entry->title);
|
||||
if (((entry->url) && (!new_entry->url)) ||
|
||||
((entry->title) && (!new_entry->title)) ||
|
||||
((entry->frag_id) && (!new_entry->frag_id))) {
|
||||
free(new_entry->url);
|
||||
free(new_entry->title);
|
||||
free(new_entry->frag_id);
|
||||
new_entry->page.url = strdup(entry->page.url);
|
||||
if (entry->page.frag_id)
|
||||
new_entry->page.frag_id = strdup(entry->page.frag_id);
|
||||
new_entry->page.title = strdup(entry->page.title);
|
||||
if (((entry->page.url) && (!new_entry->page.url)) ||
|
||||
((entry->page.title) && (!new_entry->page.title)) ||
|
||||
((entry->page.frag_id) && (!new_entry->page.frag_id))) {
|
||||
free(new_entry->page.url);
|
||||
free(new_entry->page.title);
|
||||
free(new_entry->page.frag_id);
|
||||
free(new_entry);
|
||||
return 0;
|
||||
}
|
||||
@ -230,9 +233,9 @@ void history_add(struct history *history, struct content *content,
|
||||
return;
|
||||
}
|
||||
|
||||
entry->url = url;
|
||||
entry->frag_id = frag_id ? strdup(frag_id) : 0;
|
||||
entry->title = title;
|
||||
entry->page.url = url;
|
||||
entry->page.frag_id = frag_id ? strdup(frag_id) : 0;
|
||||
entry->page.title = title;
|
||||
entry->back = history->current;
|
||||
entry->next = 0;
|
||||
entry->forward = entry->forward_pref = entry->forward_last = 0;
|
||||
@ -282,12 +285,12 @@ void history_update(struct history *history, struct content *content)
|
||||
if (!history || !history->current || !history->current->bitmap)
|
||||
return;
|
||||
|
||||
if (history->current->title)
|
||||
free(history->current->title);
|
||||
if (history->current->page.title)
|
||||
free(history->current->page.title);
|
||||
if (content->title)
|
||||
history->current->title = strdup(content->title);
|
||||
history->current->page.title = strdup(content->title);
|
||||
else
|
||||
history->current->title = 0;
|
||||
history->current->page.title = 0;
|
||||
|
||||
thumbnail_create(content, history->current->bitmap, 0);
|
||||
}
|
||||
@ -318,10 +321,10 @@ void history_free_entry(struct history_entry *entry)
|
||||
return;
|
||||
history_free_entry(entry->forward);
|
||||
history_free_entry(entry->next);
|
||||
free(entry->url);
|
||||
if (entry->frag_id)
|
||||
free(entry->frag_id);
|
||||
free(entry->title);
|
||||
free(entry->page.url);
|
||||
if (entry->page.frag_id)
|
||||
free(entry->page.frag_id);
|
||||
free(entry->page.title);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
@ -397,16 +400,17 @@ void history_go(struct browser_window *bw, struct history *history,
|
||||
char *url;
|
||||
struct history_entry *current;
|
||||
|
||||
if (entry->frag_id) {
|
||||
url = malloc(strlen(entry->url) + strlen(entry->frag_id) + 5);
|
||||
if (entry->page.frag_id) {
|
||||
url = malloc(strlen(entry->page.url) +
|
||||
strlen(entry->page.frag_id) + 5);
|
||||
if (!url) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
sprintf(url, "%s#%s", entry->url, entry->frag_id);
|
||||
sprintf(url, "%s#%s", entry->page.url, entry->page.frag_id);
|
||||
}
|
||||
else
|
||||
url = entry->url;
|
||||
url = entry->page.url;
|
||||
|
||||
if (new_window) {
|
||||
current = history->current;
|
||||
@ -418,7 +422,7 @@ void history_go(struct browser_window *bw, struct history *history,
|
||||
browser_window_go(bw, url, 0, false);
|
||||
}
|
||||
|
||||
if (entry->frag_id)
|
||||
if (entry->page.frag_id)
|
||||
free(url);
|
||||
}
|
||||
|
||||
@ -552,19 +556,19 @@ bool history_redraw_entry(struct history *history,
|
||||
struct history_entry *child;
|
||||
colour c = entry == history->current ? 0x0000ff : 0x333333;
|
||||
int tailsize = 5;
|
||||
|
||||
if (!plot.bitmap(entry->x, entry->y, WIDTH, HEIGHT, entry->bitmap,
|
||||
0xffffff))
|
||||
|
||||
if (!plot.bitmap(entry->x, entry->y, WIDTH, HEIGHT,
|
||||
entry->bitmap, 0xffffff))
|
||||
return false;
|
||||
if (!plot.rectangle(entry->x - 1, entry->y - 1, WIDTH + 1, HEIGHT + 1,
|
||||
entry == history->current ? 2 : 1, c, false, false))
|
||||
return false;
|
||||
|
||||
if (!nsfont_position_in_string(&css_base_style, entry->title,
|
||||
strlen(entry->title), WIDTH, &char_offset, &actual_x))
|
||||
if (!nsfont_position_in_string(&css_base_style, entry->page.title,
|
||||
strlen(entry->page.title), WIDTH, &char_offset, &actual_x))
|
||||
return false;
|
||||
if (!plot.text(entry->x, entry->y + HEIGHT + 12, &css_base_style,
|
||||
entry->title, char_offset, 0xffffff, c))
|
||||
entry->page.title, char_offset, 0xffffff, c))
|
||||
return false;
|
||||
|
||||
for (child = entry->forward; child; child = child->next) {
|
||||
@ -635,7 +639,7 @@ const char *history_position_url(struct history *history, int x, int y)
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
||||
return entry->url;
|
||||
return entry->page.url;
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,10 +102,15 @@ void netsurf_poll(void)
|
||||
|
||||
void netsurf_exit(void)
|
||||
{
|
||||
LOG(("Closing GUI"));
|
||||
gui_quit();
|
||||
LOG(("Closing content"));
|
||||
content_quit();
|
||||
LOG(("Closing fetches"));
|
||||
fetch_quit();
|
||||
LOG(("Closing utf8"));
|
||||
utf8_finalise();
|
||||
LOG(("Exited successfully"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,7 +124,8 @@ int option_max_fetchers_per_host = 2;
|
||||
* is this plus option_max_fetchers.
|
||||
*/
|
||||
int option_max_cached_fetch_handles = 6;
|
||||
/** Whether to use knockout rendering */
|
||||
/** Whether to allow target="_blank" */
|
||||
bool option_target_blank = true;
|
||||
|
||||
EXTRA_OPTION_DEFINE
|
||||
|
||||
@ -174,6 +175,8 @@ struct {
|
||||
OPTION_INTEGER, &option_max_fetchers_per_host },
|
||||
{ "max_cached_fetch_handles",
|
||||
OPTION_INTEGER, &option_max_cached_fetch_handles },
|
||||
{ "target_blank",
|
||||
OPTION_BOOL, &option_target_blank },
|
||||
EXTRA_OPTION_TABLE
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@ extern char *option_ca_bundle;
|
||||
extern char *option_cookie_file;
|
||||
extern char *option_cookie_jar;
|
||||
extern char *option_homepage_url;
|
||||
extern bool option_target_blank;
|
||||
extern bool option_url_suggestion;
|
||||
extern int option_window_x;
|
||||
extern int option_window_y;
|
||||
|
@ -253,6 +253,7 @@ struct object_param {
|
||||
extern const char *TARGET_SELF;
|
||||
extern const char *TARGET_PARENT;
|
||||
extern const char *TARGET_TOP;
|
||||
extern const char *TARGET_BLANK;
|
||||
|
||||
|
||||
#define UNKNOWN_WIDTH INT_MAX
|
||||
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
|
||||
* Copyright 2005 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
* Copyright 2006 Richard Wilson <info@tinct.net>
|
||||
*/
|
||||
|
||||
/** \file
|
||||
@ -22,6 +23,7 @@
|
||||
#include "netsurf/utils/config.h"
|
||||
#include "netsurf/content/content.h"
|
||||
#include "netsurf/css/css.h"
|
||||
#include "netsurf/desktop/browser.h"
|
||||
#include "netsurf/desktop/options.h"
|
||||
#include "netsurf/render/box.h"
|
||||
#include "netsurf/render/form.h"
|
||||
@ -37,13 +39,6 @@
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
|
||||
/** MultiLength, as defined by HTML 4.01. */
|
||||
struct box_multi_length {
|
||||
enum { LENGTH_PX, LENGTH_PERCENT, LENGTH_RELATIVE } type;
|
||||
float value;
|
||||
};
|
||||
|
||||
|
||||
static const content_type image_types[] = {
|
||||
#ifdef WITH_JPEG
|
||||
CONTENT_JPEG,
|
||||
@ -77,6 +72,7 @@ static const content_type image_types[] = {
|
||||
const char *TARGET_SELF = "_self";
|
||||
const char *TARGET_PARENT = "_parent";
|
||||
const char *TARGET_TOP = "_top";
|
||||
const char *TARGET_BLANK = "_blank";
|
||||
|
||||
|
||||
static bool convert_xml_to_box(xmlNode *n, struct content *content,
|
||||
@ -114,6 +110,8 @@ static bool box_input(BOX_SPECIAL_PARAMS);
|
||||
static bool box_input_text(BOX_SPECIAL_PARAMS, bool password);
|
||||
static bool box_button(BOX_SPECIAL_PARAMS);
|
||||
static bool box_frameset(BOX_SPECIAL_PARAMS);
|
||||
static bool box_create_frameset(struct content_html_frames *f, xmlNode *n,
|
||||
struct content *content);
|
||||
static bool box_select_add_option(struct form_control *control, xmlNode *n);
|
||||
static bool box_object(BOX_SPECIAL_PARAMS);
|
||||
static bool box_embed(BOX_SPECIAL_PARAMS);
|
||||
@ -122,13 +120,13 @@ static bool box_pre(BOX_SPECIAL_PARAMS);
|
||||
static bool box_iframe(BOX_SPECIAL_PARAMS);
|
||||
static bool box_get_attribute(xmlNode *n, const char *attribute,
|
||||
void *context, char **value);
|
||||
static struct box_multi_length *box_parse_multi_lengths(const char *s,
|
||||
unsigned int *count, void *context);
|
||||
static struct frame_dimension *box_parse_multi_lengths(const char *s,
|
||||
unsigned int *count);
|
||||
|
||||
|
||||
/* element_table must be sorted by name */
|
||||
struct element_entry {
|
||||
char name[10]; /* element type */
|
||||
char name[10]; /* element type */
|
||||
bool (*convert)(BOX_SPECIAL_PARAMS);
|
||||
};
|
||||
static const struct element_entry element_table[] = {
|
||||
@ -228,17 +226,17 @@ static const box_type box_map[] = {
|
||||
/**
|
||||
* Recursively construct a box tree from an xml tree and stylesheets.
|
||||
*
|
||||
* \param n fragment of xml tree
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param n fragment of xml tree
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param parent_style style at this point in xml tree
|
||||
* \param parent parent in box tree
|
||||
* \param parent parent in box tree
|
||||
* \param inline_container current inline container box, or 0, updated to
|
||||
* new current inline container on exit
|
||||
* new current inline container on exit
|
||||
* \param containing_block current containing block for absolutes, as defined
|
||||
* by CSS 2.1 10.1 4
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* by CSS 2.1 10.1 4
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* \return true on success, false on memory exhaustion
|
||||
*/
|
||||
|
||||
@ -266,17 +264,17 @@ bool convert_xml_to_box(xmlNode *n, struct content *content,
|
||||
/**
|
||||
* Construct the box tree for an XML element.
|
||||
*
|
||||
* \param n XML node of type XML_ELEMENT_NODE
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param n XML node of type XML_ELEMENT_NODE
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param parent_style style at this point in xml tree
|
||||
* \param parent parent in box tree
|
||||
* \param parent parent in box tree
|
||||
* \param inline_container current inline container box, or 0, updated to
|
||||
* new current inline container on exit
|
||||
* new current inline container on exit
|
||||
* \param containing_block current containing block for absolutes, as defined
|
||||
* by CSS 2.1 10.1 4
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* by CSS 2.1 10.1 4
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* \return true on success, false on memory exhaustion
|
||||
*/
|
||||
|
||||
@ -471,8 +469,8 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
xmlFree(s);
|
||||
}
|
||||
if (strcmp((const char *) n->name, "table") == 0) {
|
||||
border_color = 0x888888; /* default colour */
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
border_color = 0x888888; /* default colour */
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "cellpadding"))) {
|
||||
char *endp;
|
||||
long value = strtol(s, &endp, 10);
|
||||
@ -481,7 +479,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
box_set_cellpadding(box, value);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "bordercolor"))) {
|
||||
unsigned int r, g, b;
|
||||
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
||||
@ -490,7 +488,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
border_color = named_colour(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "border"))) {
|
||||
int value = atoi(s);
|
||||
if (!strrchr(s, '%') && 0 < value) /* % not implemented */
|
||||
@ -501,7 +499,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
|
||||
/* transfer <tr height="n"> down to the <td> elements */
|
||||
if (strcmp((const char *) n->name, "tr") == 0) {
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "height"))) {
|
||||
float value = atof(s);
|
||||
if (value < 0 || strlen(s) == 0) {
|
||||
@ -515,12 +513,12 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
struct box *child;
|
||||
float current;
|
||||
for (child = box->children; child; child = child->next) {
|
||||
if (child->type == BOX_TABLE_CELL) {
|
||||
current = css_len2px(
|
||||
&child->style->height.length,
|
||||
child->style);
|
||||
value = (value > current) ?
|
||||
value : current;
|
||||
if (child->type == BOX_TABLE_CELL) {
|
||||
current = css_len2px(
|
||||
&child->style->height.length,
|
||||
child->style);
|
||||
value = (value > current) ?
|
||||
value : current;
|
||||
child->style->height.height =
|
||||
CSS_HEIGHT_LENGTH;
|
||||
child->style->height.length.unit =
|
||||
@ -538,7 +536,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
if (style->background_image.type == CSS_BACKGROUND_IMAGE_URI) {
|
||||
if (!html_fetch_object(content, style->background_image.uri,
|
||||
box, image_types, content->available_width,
|
||||
1000, true, 0))
|
||||
1000, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -549,15 +547,15 @@ bool box_construct_element(xmlNode *n, struct content *content,
|
||||
/**
|
||||
* Construct the box tree for an XML text node.
|
||||
*
|
||||
* \param n XML node of type XML_TEXT_NODE
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param n XML node of type XML_TEXT_NODE
|
||||
* \param content content of type CONTENT_HTML that is being processed
|
||||
* \param parent_style style at this point in xml tree
|
||||
* \param parent parent in box tree
|
||||
* \param parent parent in box tree
|
||||
* \param inline_container current inline container box, or 0, updated to
|
||||
* new current inline container on exit
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* new current inline container on exit
|
||||
* \param href current link URL, or 0 if not in a link
|
||||
* \param target current link target, or 0 if none
|
||||
* \param title current title, or 0 if none
|
||||
* \return true on success, false on memory exhaustion
|
||||
*/
|
||||
|
||||
@ -726,9 +724,9 @@ bool box_construct_text(xmlNode *n, struct content *content,
|
||||
/**
|
||||
* Get the style for an element.
|
||||
*
|
||||
* \param c content of type CONTENT_HTML that is being processed
|
||||
* \param c content of type CONTENT_HTML that is being processed
|
||||
* \param parent_style style at this point in xml tree
|
||||
* \param n node in xml tree
|
||||
* \param n node in xml tree
|
||||
* \return the new style, or 0 on memory exhaustion
|
||||
*
|
||||
* The style is collected from three sources:
|
||||
@ -985,7 +983,7 @@ struct css_style * box_get_style(struct content *c,
|
||||
* by CSS 2.1 9.7.
|
||||
*
|
||||
* \param style style to update
|
||||
* \param root this is the root element
|
||||
* \param root this is the root element
|
||||
*/
|
||||
|
||||
void box_solve_display(struct css_style *style, bool root)
|
||||
@ -1016,7 +1014,7 @@ void box_solve_display(struct css_style *style, bool root)
|
||||
/**
|
||||
* Set the cellpadding on a table.
|
||||
*
|
||||
* \param box box to set cellpadding on
|
||||
* \param box box to set cellpadding on
|
||||
* \param value padding in pixels
|
||||
*
|
||||
* The descendants of the box are searched for table cells, and the padding is
|
||||
@ -1046,7 +1044,7 @@ void box_set_cellpadding(struct box *box, int value)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1054,7 +1052,7 @@ void box_set_cellpadding(struct box *box, int value)
|
||||
/**
|
||||
* Set the borders on a table.
|
||||
*
|
||||
* \param box box to set cellpadding on
|
||||
* \param box box to set cellpadding on
|
||||
* \param value border in pixels
|
||||
*
|
||||
* The descendants of the box are searched for table cells, and the border is
|
||||
@ -1067,8 +1065,8 @@ void box_set_table_border(struct box *box, int value, colour color)
|
||||
|
||||
if (box->type == BOX_TABLE) {
|
||||
for (unsigned int i = 0; i != 4; i++) {
|
||||
if (box->style->border[i].style ==
|
||||
CSS_BORDER_STYLE_NONE) {
|
||||
if (box->style->border[i].style ==
|
||||
CSS_BORDER_STYLE_NONE) {
|
||||
box->style->border[i].color = color;
|
||||
box->style->border[i].width.width =
|
||||
CSS_BORDER_WIDTH_LENGTH;
|
||||
@ -1092,8 +1090,8 @@ void box_set_table_border(struct box *box, int value, colour color)
|
||||
break;
|
||||
case BOX_TABLE_CELL:
|
||||
for (unsigned int i = 0; i != 4; i++) {
|
||||
if (child->style->border[i].style ==
|
||||
CSS_BORDER_STYLE_NONE) {
|
||||
if (child->style->border[i].style ==
|
||||
CSS_BORDER_STYLE_NONE) {
|
||||
child->style->border[i].color = color;
|
||||
child->style->border[i].width.width =
|
||||
CSS_BORDER_WIDTH_LENGTH;
|
||||
@ -1108,7 +1106,7 @@ void box_set_table_border(struct box *box, int value, colour color)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1116,9 +1114,9 @@ void box_set_table_border(struct box *box, int value, colour color)
|
||||
/**
|
||||
* Apply the CSS text-transform property to given text for its ASCII chars.
|
||||
*
|
||||
* \param s string to transform
|
||||
* \param s string to transform
|
||||
* \param len length of s
|
||||
* \param tt transform type
|
||||
* \param tt transform type
|
||||
*/
|
||||
|
||||
void box_text_transform(char *s, unsigned int len,
|
||||
@ -1231,11 +1229,13 @@ bool box_a(BOX_SPECIAL_PARAMS)
|
||||
|
||||
/* target frame [16.3] */
|
||||
if ((s = xmlGetProp(n, (const xmlChar *) "target"))) {
|
||||
if (!strcmp(s, "_blank") || !strcmp(s, "_top"))
|
||||
if (!strcasecmp(s, "_blank"))
|
||||
box->target = TARGET_BLANK;
|
||||
else if (!strcasecmp(s, "_top"))
|
||||
box->target = TARGET_TOP;
|
||||
else if (!strcmp(s, "_parent"))
|
||||
else if (!strcasecmp(s, "_parent"))
|
||||
box->target = TARGET_PARENT;
|
||||
else if (!strcmp(s, "_self"))
|
||||
else if (!strcasecmp(s, "_self"))
|
||||
/* the default may have been overridden by a
|
||||
* <base target=...>, so this is different to 0 */
|
||||
box->target = TARGET_SELF;
|
||||
@ -1246,7 +1246,7 @@ bool box_a(BOX_SPECIAL_PARAMS)
|
||||
xmlFree(s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlFree(s);
|
||||
}
|
||||
|
||||
@ -1294,7 +1294,7 @@ bool box_image(BOX_SPECIAL_PARAMS)
|
||||
|
||||
/* start fetch */
|
||||
ok = html_fetch_object(content, url, box, image_types,
|
||||
content->available_width, 1000, false, 0);
|
||||
content->available_width, 1000, false);
|
||||
free(url);
|
||||
return ok;
|
||||
}
|
||||
@ -1406,7 +1406,7 @@ bool box_object(BOX_SPECIAL_PARAMS)
|
||||
|
||||
/* start fetch (MIME type is ok or not specified) */
|
||||
if (!html_fetch_object(content, params->data, box, 0,
|
||||
content->available_width, 1000, false, 0))
|
||||
content->available_width, 1000, false))
|
||||
return false;
|
||||
|
||||
/* convert children and place into fallback */
|
||||
@ -1563,96 +1563,117 @@ no_memory:
|
||||
|
||||
bool box_frameset(BOX_SPECIAL_PARAMS)
|
||||
{
|
||||
unsigned int row, col;
|
||||
unsigned int rows = 1, cols = 1;
|
||||
int object_width, object_height;
|
||||
char *s, *s1, *url, *name;
|
||||
struct box *row_box;
|
||||
struct box *cell_box;
|
||||
struct box *frameset_box;
|
||||
struct css_style *style = box->style;
|
||||
struct css_style *row_style;
|
||||
struct css_style *cell_style;
|
||||
struct box_multi_length *row_height = 0, *col_width = 0;
|
||||
xmlNode *c;
|
||||
url_func_result res;
|
||||
bool ok;
|
||||
|
||||
box->type = BOX_TABLE;
|
||||
if (content->data.html.frameset) {
|
||||
LOG(("Error: multiple framesets in document."));
|
||||
return false;
|
||||
}
|
||||
|
||||
content->data.html.frameset = talloc_zero(content, struct content_html_frames);
|
||||
if (!content->data.html.frameset)
|
||||
return false;
|
||||
|
||||
ok = box_create_frameset(content->data.html.frameset, n, content);
|
||||
if (ok)
|
||||
box->style->display = CSS_DISPLAY_NONE;
|
||||
|
||||
if (convert_children)
|
||||
*convert_children = false;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool box_create_frameset(struct content_html_frames *f, xmlNode *n,
|
||||
struct content *content) {
|
||||
unsigned int row, col, index, i;
|
||||
unsigned int rows = 1, cols = 1;
|
||||
char *s, *url;
|
||||
struct frame_dimension *row_height = 0, *col_width = 0;
|
||||
xmlNode *c;
|
||||
struct content_html_frames *frame;
|
||||
bool default_border = true;
|
||||
colour default_border_colour = 0x000000;
|
||||
|
||||
/* parse rows and columns */
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) {
|
||||
row_height = box_parse_multi_lengths(s, &rows, content);
|
||||
row_height = box_parse_multi_lengths(s, &rows);
|
||||
xmlFree(s);
|
||||
if (!row_height)
|
||||
return false;
|
||||
} else {
|
||||
row_height = calloc(1, sizeof(struct frame_dimension));
|
||||
if (!row_height)
|
||||
return false;
|
||||
row_height->value = 100;
|
||||
row_height->unit = FRAME_DIMENSION_PERCENT;
|
||||
}
|
||||
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols"))) {
|
||||
col_width = box_parse_multi_lengths(s, &cols, content);
|
||||
col_width = box_parse_multi_lengths(s, &cols);
|
||||
xmlFree(s);
|
||||
if (!col_width)
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(("rows %u, cols %u", rows, cols));
|
||||
|
||||
box->min_width = 1;
|
||||
box->max_width = 10000;
|
||||
box->col = talloc_array(content, struct column, cols);
|
||||
if (!box->col)
|
||||
return false;
|
||||
|
||||
if (col_width) {
|
||||
for (col = 0; col != cols; col++) {
|
||||
if (col_width[col].type == LENGTH_PX) {
|
||||
box->col[col].type = COLUMN_WIDTH_FIXED;
|
||||
box->col[col].width = col_width[col].value;
|
||||
} else if (col_width[col].type == LENGTH_PERCENT) {
|
||||
box->col[col].type = COLUMN_WIDTH_PERCENT;
|
||||
box->col[col].width = col_width[col].value;
|
||||
} else {
|
||||
box->col[col].type = COLUMN_WIDTH_RELATIVE;
|
||||
box->col[col].width = col_width[col].value;
|
||||
}
|
||||
box->col[col].min = 1;
|
||||
box->col[col].max = 10000;
|
||||
}
|
||||
} else {
|
||||
box->col[0].type = COLUMN_WIDTH_RELATIVE;
|
||||
box->col[0].width = 1;
|
||||
box->col[0].min = 1;
|
||||
box->col[0].max = 10000;
|
||||
col_width = calloc(1, sizeof(struct frame_dimension));
|
||||
if (!col_width)
|
||||
return false;
|
||||
col_width->value = 100;
|
||||
col_width->unit = FRAME_DIMENSION_PERCENT;
|
||||
}
|
||||
|
||||
/* create the frameset table */
|
||||
/* common extension: border="0|1" to control all children */
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "border"))) {
|
||||
if ((s[0] == '0') && (s[1] == '\0'))
|
||||
default_border = false;
|
||||
xmlFree(s);
|
||||
}
|
||||
/* common extension: frameborder="yes|no" to control all children */
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "frameborder"))) {
|
||||
if (!strcasecmp(s, "no"))
|
||||
default_border = false;
|
||||
xmlFree(s);
|
||||
}
|
||||
/* common extension: bordercolor="#RRGGBB|<named colour>" to control all children */
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "bordercolor"))) {
|
||||
unsigned int r, g, b;
|
||||
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
||||
default_border_colour = (b << 16) | (g << 8) | r;
|
||||
else if (s[0] != '#')
|
||||
default_border_colour = named_colour(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
|
||||
/* update frameset and create default children */
|
||||
f->cols = cols;
|
||||
f->rows = rows;
|
||||
f->scrolling = SCROLLING_NO;
|
||||
f->children = talloc_array(content, struct content_html_frames, (rows * cols));
|
||||
for (row = 0; row < rows; row++) {
|
||||
for (col = 0; col < cols; col++) {
|
||||
index = (row * cols) + col;
|
||||
frame = &f->children[index];
|
||||
frame->cols = 0;
|
||||
frame->rows = 0;
|
||||
frame->width = col_width[col];
|
||||
frame->height = row_height[row];
|
||||
frame->margin_width = -1;
|
||||
frame->margin_height = -1;
|
||||
frame->name = NULL;
|
||||
frame->url = NULL;
|
||||
frame->no_resize = false;
|
||||
frame->scrolling = SCROLLING_AUTO;
|
||||
frame->border = default_border;
|
||||
frame->border_colour = default_border_colour;
|
||||
frame->children = NULL;
|
||||
}
|
||||
}
|
||||
free(col_width);
|
||||
free(row_height);
|
||||
|
||||
/* create the frameset windows */
|
||||
c = n->children;
|
||||
for (row = 0; c && row != rows; row++) {
|
||||
row_style = talloc_memdup(content, style, sizeof *style);
|
||||
if (!row_style)
|
||||
return false;
|
||||
object_height = 1000; /** \todo get available height */
|
||||
/* if (row_height) {
|
||||
row_style->height.height = CSS_HEIGHT_LENGTH;
|
||||
row_style->height.length.unit = CSS_UNIT_PX;
|
||||
if (row_height[row].type == LENGTH_PERCENT)
|
||||
row_style->height.length.value = 1000 *
|
||||
row_height[row].value / 100;
|
||||
else if (row_height[row].type == LENGTH_RELATIVE)
|
||||
row_style->height.length.value = 100 *
|
||||
row_height[row].value;
|
||||
else
|
||||
row_style->height.length.value =
|
||||
row_height[row].value;
|
||||
object_height = row_style->height.length.value;
|
||||
}*/
|
||||
row_box = box_create(row_style, 0, 0, 0, 0, content);
|
||||
if (!row_box)
|
||||
return false;
|
||||
|
||||
row_box->type = BOX_TABLE_ROW;
|
||||
box_add_child(box, row_box);
|
||||
|
||||
for (col = 0; c && col != cols; col++) {
|
||||
for (row = 0; c && row < rows; row++) {
|
||||
for (col = 0; c && col < cols; col++) {
|
||||
while (c && !(c->type == XML_ELEMENT_NODE && (
|
||||
strcmp((const char *) c->name, "frame") == 0 ||
|
||||
strcmp((const char *) c->name, "frameset") == 0
|
||||
@ -1661,83 +1682,91 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
/* estimate frame width */
|
||||
object_width = content->available_width;
|
||||
if (col_width && col_width[col].type == LENGTH_PX)
|
||||
object_width = col_width[col].value;
|
||||
|
||||
cell_style = talloc_memdup(content, style,
|
||||
sizeof *style);
|
||||
if (!cell_style)
|
||||
return false;
|
||||
cell_style->overflow = CSS_OVERFLOW_AUTO;
|
||||
|
||||
cell_box = box_create(cell_style, 0, 0, 0, 0, content);
|
||||
if (!cell_box)
|
||||
return false;
|
||||
cell_box->type = BOX_TABLE_CELL;
|
||||
box_add_child(row_box, cell_box);
|
||||
/* get current frame */
|
||||
index = (row * cols) + col;
|
||||
frame = &f->children[index];
|
||||
|
||||
/* nest framesets */
|
||||
if (strcmp((const char *) c->name, "frameset") == 0) {
|
||||
LOG(("frameset"));
|
||||
frameset_box = box_create(cell_style, 0, 0, 0,
|
||||
0, content);
|
||||
if (!frameset_box)
|
||||
frame->border = 0;
|
||||
if (!box_create_frameset(frame, c, content))
|
||||
return false;
|
||||
if (!box_frameset(c, content, frameset_box, 0))
|
||||
return false;
|
||||
box_add_child(cell_box, frameset_box);
|
||||
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get frame URL */
|
||||
if (!(s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "src"))) {
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
s1 = strip(s);
|
||||
res = url_join(s1, content->data.html.base_url, &url);
|
||||
if (!box_extract_link(s, content->data.html.base_url, &url)) {
|
||||
xmlFree(s);
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
xmlFree(s);
|
||||
/* if url is equivalent to the parent's url,
|
||||
* we've got infinite inclusion. stop it here.
|
||||
* also bail if url_join failed.
|
||||
*/
|
||||
if (res != URL_FUNC_OK || strcasecmp(url,
|
||||
content->data.html.base_url) == 0) {
|
||||
LOG(("url_join failed"));
|
||||
if (!url) {
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
name = xmlGetProp(c, (const xmlChar *) "name");
|
||||
/* don't include ourself */
|
||||
if (strcmp(content->data.html.base_url, url) == 0) {
|
||||
free(url);
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG(("frame, url '%s', name '%s'", url, name));
|
||||
/* fill in specified values */
|
||||
frame->url = talloc_strdup(content, url);
|
||||
if ((s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "name"))) {
|
||||
frame->name = talloc_strdup(content, s);
|
||||
xmlFree(s);
|
||||
}
|
||||
frame->no_resize = xmlHasProp(c,
|
||||
(const xmlChar *) "noresize");
|
||||
if ((s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "frameborder"))) {
|
||||
i = atoi(s);
|
||||
frame->border = (i != 0);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "scrolling"))) {
|
||||
if (!strcasecmp(s, "yes"))
|
||||
frame->scrolling = SCROLLING_YES;
|
||||
else if (!strcasecmp(s, "no"))
|
||||
frame->scrolling = SCROLLING_NO;
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "marginwidth"))) {
|
||||
frame->margin_width = atoi(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(c,
|
||||
(const xmlChar *) "marginheight"))) {
|
||||
frame->margin_width = atoi(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(c, (const xmlChar *) "bordercolor"))) {
|
||||
unsigned int r, g, b;
|
||||
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
||||
frame->border_colour = (b << 16) | (g << 8) | r;
|
||||
else if (s[0] != '#')
|
||||
frame->border_colour = named_colour(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
|
||||
if (!html_fetch_object(content, url,
|
||||
cell_box, 0,
|
||||
object_width, object_height, false,
|
||||
name))
|
||||
return false;
|
||||
/* release temporary memory */
|
||||
free(url);
|
||||
|
||||
if (name)
|
||||
xmlFree(name);
|
||||
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(row_height);
|
||||
talloc_free(col_width);
|
||||
|
||||
style->width.width = CSS_WIDTH_PERCENT;
|
||||
style->width.value.percent = 100;
|
||||
|
||||
if (convert_children)
|
||||
*convert_children = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1748,33 +1777,93 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
|
||||
|
||||
bool box_iframe(BOX_SPECIAL_PARAMS)
|
||||
{
|
||||
bool ok;
|
||||
char *url;
|
||||
xmlChar *src;
|
||||
char *url, *s;
|
||||
struct content_html_iframe *iframe;
|
||||
int i;
|
||||
|
||||
/* get frame URL */
|
||||
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
|
||||
if (!(s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "src")))
|
||||
return true;
|
||||
if (!box_extract_link((char *) src, content->data.html.base_url, &url))
|
||||
if (!box_extract_link(s, content->data.html.base_url, &url)) {
|
||||
xmlFree(s);
|
||||
return false;
|
||||
}
|
||||
xmlFree(s);
|
||||
if (!url)
|
||||
return true;
|
||||
|
||||
/* Don't include ourself */
|
||||
/* don't include ourself */
|
||||
if (strcmp(content->data.html.base_url, url) == 0) {
|
||||
free(url);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* start fetch */
|
||||
ok = html_fetch_object(content, url, box, 0,
|
||||
content->available_width, 0, false, 0);
|
||||
/* create a new iframe */
|
||||
iframe = talloc(content, struct content_html_iframe);
|
||||
if (!iframe) {
|
||||
free(url);
|
||||
return false;
|
||||
}
|
||||
iframe->box = box;
|
||||
iframe->margin_width = -1;
|
||||
iframe->margin_height = -1;
|
||||
iframe->name = NULL;
|
||||
iframe->url = talloc_strdup(content, url);
|
||||
iframe->scrolling = SCROLLING_AUTO;
|
||||
iframe->border = true;
|
||||
iframe->next = content->data.html.iframe;
|
||||
content->data.html.iframe = iframe;
|
||||
|
||||
/* fill in specified values */
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "name"))) {
|
||||
iframe->name = talloc_strdup(content, s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "frameborder"))) {
|
||||
i = atoi(s);
|
||||
iframe->border = (i != 0);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "bordercolor"))) {
|
||||
unsigned int r, g, b;
|
||||
if (s[0] == '#' && sscanf(s + 1, "%2x%2x%2x", &r, &g, &b) == 3)
|
||||
iframe->border_colour = (b << 16) | (g << 8) | r;
|
||||
else if (s[0] != '#')
|
||||
iframe->border_colour = named_colour(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "scrolling"))) {
|
||||
if (!strcasecmp(s, "yes"))
|
||||
iframe->scrolling = SCROLLING_YES;
|
||||
else if (!strcasecmp(s, "no"))
|
||||
iframe->scrolling = SCROLLING_NO;
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "marginwidth"))) {
|
||||
iframe->margin_width = atoi(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
if ((s = (char *) xmlGetProp(n,
|
||||
(const xmlChar *) "marginheight"))) {
|
||||
iframe->margin_width = atoi(s);
|
||||
xmlFree(s);
|
||||
}
|
||||
|
||||
/* release temporary memory */
|
||||
free(url);
|
||||
|
||||
*convert_children = false;
|
||||
/* box */
|
||||
box->type = BOX_INLINE_BLOCK;
|
||||
assert(box->style);
|
||||
|
||||
return ok;
|
||||
if (convert_children)
|
||||
*convert_children = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1976,12 +2065,12 @@ bool box_input(BOX_SPECIAL_PARAMS)
|
||||
if (!html_fetch_object(content, url,
|
||||
box, image_types,
|
||||
content->available_width,
|
||||
1000, false, 0)) {
|
||||
1000, false)) {
|
||||
free(url);
|
||||
goto no_memory;
|
||||
}
|
||||
}
|
||||
free(url);
|
||||
}
|
||||
}
|
||||
free(url);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -2244,7 +2333,7 @@ no_memory:
|
||||
* Add an option to a form select control (helper function for box_select()).
|
||||
*
|
||||
* \param control select containing the option
|
||||
* \param n xml element node for <option>
|
||||
* \param n xml element node for <option>
|
||||
* \return true on success, false on memory exhaustion
|
||||
*/
|
||||
|
||||
@ -2432,7 +2521,7 @@ bool box_embed(BOX_SPECIAL_PARAMS)
|
||||
|
||||
/* start fetch */
|
||||
return html_fetch_object(content, params->data, box, 0,
|
||||
content->available_width, 1000, false, 0);
|
||||
content->available_width, 1000, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2443,7 +2532,7 @@ bool box_embed(BOX_SPECIAL_PARAMS)
|
||||
/**
|
||||
* Get the value of an XML element's attribute.
|
||||
*
|
||||
* \param n xmlNode, of type XML_ELEMENT_NODE
|
||||
* \param n xmlNode, of type XML_ELEMENT_NODE
|
||||
* \param attribute name of attribute
|
||||
* \param context talloc context for result buffer
|
||||
* \param value updated to value, if the attribute is present
|
||||
@ -2471,8 +2560,8 @@ bool box_get_attribute(xmlNode *n, const char *attribute,
|
||||
* Extract a URL from a relative link, handling junk like whitespace and
|
||||
* attempting to read a real URL from "javascript:" links.
|
||||
*
|
||||
* \param rel relative URL taken from page
|
||||
* \param base base for relative URLs
|
||||
* \param rel relative URL taken from page
|
||||
* \param base base for relative URLs
|
||||
* \param result updated to target URL on heap, unchanged if extract failed
|
||||
* \return true on success, false on memory exhaustion
|
||||
*/
|
||||
@ -2537,24 +2626,23 @@ bool box_extract_link(const char *rel, const char *base, char **result)
|
||||
/**
|
||||
* Parse a multi-length-list, as defined by HTML 4.01.
|
||||
*
|
||||
* \param s string to parse
|
||||
* \param s string to parse
|
||||
* \param count updated to number of entries
|
||||
* \param context talloc context block
|
||||
* \return array of struct box_multi_length, or 0 on memory exhaustion
|
||||
*/
|
||||
|
||||
struct box_multi_length *box_parse_multi_lengths(const char *s,
|
||||
unsigned int *count, void *context)
|
||||
struct frame_dimension *box_parse_multi_lengths(const char *s,
|
||||
unsigned int *count)
|
||||
{
|
||||
char *end;
|
||||
unsigned int i, n;
|
||||
struct box_multi_length *length;
|
||||
struct frame_dimension *length;
|
||||
|
||||
for (i = 0, n = 1; s[i]; i++)
|
||||
if (s[i] == ',')
|
||||
n++;
|
||||
|
||||
length = talloc_array(context, struct box_multi_length, n);
|
||||
length = calloc(n, sizeof(struct frame_dimension));
|
||||
if (!length)
|
||||
return NULL;
|
||||
|
||||
@ -2566,9 +2654,15 @@ struct box_multi_length *box_parse_multi_lengths(const char *s,
|
||||
length[i].value = 1;
|
||||
s = end;
|
||||
switch (*s) {
|
||||
case '%': length[i].type = LENGTH_PERCENT; break;
|
||||
case '*': length[i].type = LENGTH_RELATIVE; break;
|
||||
default: length[i].type = LENGTH_PX; break;
|
||||
case '%':
|
||||
length[i].unit = FRAME_DIMENSION_PERCENT;
|
||||
break;
|
||||
case '*':
|
||||
length[i].unit = FRAME_DIMENSION_RELATIVE;
|
||||
break;
|
||||
default:
|
||||
length[i].unit = FRAME_DIMENSION_PIXELS;
|
||||
break;
|
||||
}
|
||||
while (*s && *s != ',')
|
||||
s++;
|
||||
|
186
render/html.c
186
render/html.c
@ -53,8 +53,8 @@ static void html_object_failed(struct box *box, struct content *content,
|
||||
static bool html_object_type_permitted(const content_type type,
|
||||
const content_type *permitted_types);
|
||||
static void html_object_refresh(void *p);
|
||||
static bool html_find_frame(struct content *c, const char *frame,
|
||||
struct content **page, unsigned int *i);
|
||||
static void html_destroy_frameset(struct content_html_frames *frameset);
|
||||
static void html_destroy_iframe(struct content_html_iframe *iframe);
|
||||
|
||||
|
||||
/**
|
||||
@ -75,6 +75,7 @@ bool html_create(struct content *c, const char *params[])
|
||||
html->encoding = 0;
|
||||
html->getenc = true;
|
||||
html->base_url = c->url;
|
||||
html->base_target = NULL;
|
||||
html->layout = 0;
|
||||
html->background_colour = TRANSPARENT;
|
||||
html->stylesheet_count = 0;
|
||||
@ -86,6 +87,8 @@ bool html_create(struct content *c, const char *params[])
|
||||
html->forms = 0;
|
||||
html->imagemaps = 0;
|
||||
html->bw = 0;
|
||||
html->frameset = 0;
|
||||
html->iframe = 0;
|
||||
html->page = 0;
|
||||
html->index = 0;
|
||||
html->box = 0;
|
||||
@ -494,6 +497,7 @@ bool html_meta_refresh(struct content *c, xmlNode *head)
|
||||
bool html_head(struct content *c, xmlNode *head)
|
||||
{
|
||||
xmlNode *node;
|
||||
xmlChar *s;
|
||||
|
||||
c->title = 0;
|
||||
|
||||
@ -528,6 +532,21 @@ bool html_head(struct content *c, xmlNode *head)
|
||||
}
|
||||
xmlFree(href);
|
||||
}
|
||||
/* don't use the central values to ease freeing later on */
|
||||
if ((s = xmlGetProp(node, (const xmlChar *) "target"))) {
|
||||
if ((!strcasecmp(s, "_blank")) || (!strcasecmp(s, "_top")) ||
|
||||
(!strcasecmp(s, "_parent")) ||
|
||||
(!strcasecmp(s, "_self")) ||
|
||||
('a' <= s[0] && s[0] <= 'z') ||
|
||||
('A' <= s[0] && s[0] <= 'Z')) { /* [6.16] */
|
||||
c->data.html.base_target = talloc_strdup(c, s);
|
||||
if (!c->data.html.base_target) {
|
||||
xmlFree(s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
xmlFree(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -903,7 +922,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
|
||||
bool html_fetch_object(struct content *c, char *url, struct box *box,
|
||||
const content_type *permitted_types,
|
||||
int available_width, int available_height,
|
||||
bool background, char *frame)
|
||||
bool background)
|
||||
{
|
||||
unsigned int i = c->data.html.object_count;
|
||||
struct content_html_object *object;
|
||||
@ -935,9 +954,6 @@ bool html_fetch_object(struct content *c, char *url, struct box *box,
|
||||
c->data.html.object[i].permitted_types = permitted_types;
|
||||
c->data.html.object[i].background = background;
|
||||
c->data.html.object[i].content = c_fetch;
|
||||
c->data.html.object[i].frame = 0;
|
||||
if (frame)
|
||||
c->data.html.object[i].frame = talloc_strdup(c, frame);
|
||||
c->data.html.object_count++;
|
||||
c->active++;
|
||||
|
||||
@ -1388,6 +1404,7 @@ void html_stop(struct content *c)
|
||||
void html_reformat(struct content *c, int width, int height)
|
||||
{
|
||||
struct box *doc;
|
||||
|
||||
layout_document(c, width, height);
|
||||
doc = c->data.html.layout;
|
||||
|
||||
@ -1396,6 +1413,11 @@ void html_reformat(struct content *c, int width, int height)
|
||||
|
||||
c->height = doc->descendant_y1 +
|
||||
doc->margin[TOP] + doc->margin[BOTTOM];
|
||||
|
||||
if ((c->data.html.frameset) && (c->data.html.bw))
|
||||
browser_window_recalculate_frameset(c->data.html.bw);
|
||||
if ((c->data.html.iframe) && (c->data.html.bw))
|
||||
browser_window_recalculate_iframes(c->data.html.bw);
|
||||
}
|
||||
|
||||
|
||||
@ -1418,6 +1440,25 @@ void html_destroy(struct content *c)
|
||||
if (c->data.html.parser)
|
||||
htmlFreeParserCtxt(c->data.html.parser);
|
||||
|
||||
/* Free base target */
|
||||
if (c->data.html.base_target) {
|
||||
talloc_free(c->data.html.base_target);
|
||||
c->data.html.base_target = NULL;
|
||||
}
|
||||
|
||||
/* Free frameset */
|
||||
if (c->data.html.frameset) {
|
||||
html_destroy_frameset(c->data.html.frameset);
|
||||
talloc_free(c->data.html.frameset);
|
||||
c->data.html.frameset = NULL;
|
||||
}
|
||||
|
||||
/* Free iframes */
|
||||
if (c->data.html.iframe) {
|
||||
html_destroy_iframe(c->data.html.iframe);
|
||||
c->data.html.iframe = NULL;
|
||||
}
|
||||
|
||||
/* Free stylesheets */
|
||||
if (c->data.html.stylesheet_count) {
|
||||
for (i = 0; i != c->data.html.stylesheet_count; i++) {
|
||||
@ -1430,7 +1471,7 @@ void html_destroy(struct content *c)
|
||||
}
|
||||
|
||||
talloc_free(c->data.html.working_stylesheet);
|
||||
|
||||
|
||||
/*if (c->data.html.style)
|
||||
css_free_style(c->data.html.style);*/
|
||||
|
||||
@ -1447,6 +1488,48 @@ void html_destroy(struct content *c)
|
||||
}
|
||||
}
|
||||
|
||||
void html_destroy_frameset(struct content_html_frames *frameset) {
|
||||
int i;
|
||||
|
||||
if (frameset->name) {
|
||||
talloc_free(frameset->name);
|
||||
frameset->name = NULL;
|
||||
}
|
||||
if (frameset->url) {
|
||||
talloc_free(frameset->url);
|
||||
frameset->url = NULL;
|
||||
}
|
||||
if (frameset->children) {
|
||||
for (i = 0; i < (frameset->rows * frameset->cols); i++) {
|
||||
if (frameset->children[i].name) {
|
||||
talloc_free(frameset->children[i].name);
|
||||
frameset->children[i].name = NULL;
|
||||
}
|
||||
if (frameset->children[i].url) {
|
||||
talloc_free(frameset->children[i].url);
|
||||
frameset->children[i].url = NULL;
|
||||
}
|
||||
if (frameset->children[i].children)
|
||||
html_destroy_frameset(&frameset->children[i]);
|
||||
}
|
||||
talloc_free(frameset->children);
|
||||
frameset->children = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void html_destroy_iframe(struct content_html_iframe *iframe) {
|
||||
struct content_html_iframe *next;
|
||||
next = iframe;
|
||||
while ((iframe = next) != NULL) {
|
||||
next = iframe->next;
|
||||
if (iframe->name)
|
||||
talloc_free(iframe->name);
|
||||
if (iframe->url)
|
||||
talloc_free(iframe->url);
|
||||
talloc_free(iframe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a window containing a CONTENT_HTML being opened.
|
||||
@ -1471,6 +1554,11 @@ void html_open(struct content *c, struct browser_window *bw,
|
||||
c->data.html.object[i].box,
|
||||
c->data.html.object[i].box->object_params);
|
||||
}
|
||||
|
||||
if (c->data.html.frameset)
|
||||
browser_window_create_frameset(bw, c->data.html.frameset);
|
||||
if (c->data.html.iframe)
|
||||
browser_window_create_iframes(bw, c->data.html.iframe);
|
||||
}
|
||||
|
||||
|
||||
@ -1491,87 +1579,3 @@ void html_close(struct content *c)
|
||||
content_close(c->data.html.object[i].content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the target frame for a link.
|
||||
*
|
||||
* \param c content containing the link, of type CONTENT_HTML
|
||||
* \param target target frame
|
||||
* \retval page updated to content containing target object, or 0 if the
|
||||
* target should replace the top-level content
|
||||
* \retval i updated to index of target object in page->data.html.object
|
||||
*/
|
||||
|
||||
void html_find_target(struct content *c, const char *target,
|
||||
struct content **page, unsigned int *i)
|
||||
{
|
||||
*page = 0;
|
||||
|
||||
assert(c->type == CONTENT_HTML);
|
||||
|
||||
if (!target) {
|
||||
/** \todo get target from <base target=...> */
|
||||
*page = c->data.html.page;
|
||||
*i = c->data.html.index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (target == TARGET_SELF) {
|
||||
*page = c->data.html.page;
|
||||
*i = c->data.html.index;
|
||||
return;
|
||||
} else if (target == TARGET_PARENT) {
|
||||
if (c->data.html.page && c->data.html.page->data.html.page) {
|
||||
*page = c->data.html.page->data.html.page;
|
||||
*i = c->data.html.page->data.html.index;
|
||||
}
|
||||
return;
|
||||
} else if (target == TARGET_TOP) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* recursively search for a frame named target, starting with the
|
||||
* top-level content in the frameset */
|
||||
while (c->data.html.page)
|
||||
c = c->data.html.page;
|
||||
|
||||
html_find_frame(c, target, page, i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively search a frameset for a frame.
|
||||
*
|
||||
* \param c frameset page, of type CONTENT_HTML
|
||||
* \param frame name of frame
|
||||
* \retval page updated to content containing the frame, if true returned
|
||||
* \retval i updated to index of target frame in page->data.html.object
|
||||
* \return true iff the frame was found
|
||||
*/
|
||||
|
||||
bool html_find_frame(struct content *c, const char *frame,
|
||||
struct content **page, unsigned int *i)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
assert(c->type == CONTENT_HTML);
|
||||
|
||||
for (j = 0; j != c->data.html.object_count; j++) {
|
||||
if (c->data.html.object[j].frame &&
|
||||
!strcmp(c->data.html.object[j].frame, frame)) {
|
||||
*page = c;
|
||||
*i = j;
|
||||
return true;
|
||||
}
|
||||
if (c->data.html.object[j].content &&
|
||||
c->data.html.object[j].content->type ==
|
||||
CONTENT_HTML) {
|
||||
if (html_find_frame(c->data.html.object[j].content,
|
||||
frame, page, i))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -37,6 +37,22 @@ struct plotters;
|
||||
extern char *default_stylesheet_url;
|
||||
extern char *adblock_stylesheet_url;
|
||||
|
||||
struct frame_dimension {
|
||||
float value;
|
||||
enum {
|
||||
FRAME_DIMENSION_PIXELS, /* '100', '200' */
|
||||
FRAME_DIMENSION_PERCENT, /* '5%', '20%' */
|
||||
FRAME_DIMENSION_RELATIVE /* '*', '2*' */
|
||||
} unit;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SCROLLING_AUTO,
|
||||
SCROLLING_YES,
|
||||
SCROLLING_NO
|
||||
} frame_scrolling;
|
||||
|
||||
|
||||
/** An object (<img>, <object>, etc.) in a CONTENT_HTML document. */
|
||||
struct content_html_object {
|
||||
char *url; /**< URL of this object. */
|
||||
@ -46,7 +62,44 @@ struct content_html_object {
|
||||
* CONTENT_UNKNOWN, or 0 if any type is acceptable. */
|
||||
const content_type *permitted_types;
|
||||
bool background; /**< This object is a background image. */
|
||||
char *frame; /**< Name of frame, or 0 if not a frame. */
|
||||
};
|
||||
|
||||
/** Frame tree (<frameset>, <frame>) */
|
||||
struct content_html_frames {
|
||||
int cols; /** number of columns in frameset */
|
||||
int rows; /** number of rows in frameset */
|
||||
|
||||
struct frame_dimension width; /** frame width */
|
||||
struct frame_dimension height; /** frame width */
|
||||
int margin_width; /** frame margin width */
|
||||
int margin_height; /** frame margin height */
|
||||
|
||||
char *name; /** frame name (for targetting) */
|
||||
char *url; /** frame url */
|
||||
|
||||
bool no_resize; /** frame is not resizable */
|
||||
frame_scrolling scrolling; /** scrolling characteristics */
|
||||
bool border; /** frame has a border */
|
||||
colour border_colour; /** frame border colour */
|
||||
|
||||
struct content_html_frames *children; /** [cols * rows] children */
|
||||
};
|
||||
|
||||
/** Inline frame list (<iframe>) */
|
||||
struct content_html_iframe {
|
||||
struct box *box;
|
||||
|
||||
int margin_width; /** frame margin width */
|
||||
int margin_height; /** frame margin height */
|
||||
|
||||
char *name; /** frame name (for targetting) */
|
||||
char *url; /** frame url */
|
||||
|
||||
frame_scrolling scrolling; /** scrolling characteristics */
|
||||
bool border; /** frame has a border */
|
||||
colour border_colour; /** frame border colour */
|
||||
|
||||
struct content_html_iframe *next;
|
||||
};
|
||||
|
||||
/** Data specific to CONTENT_HTML. */
|
||||
@ -63,6 +116,7 @@ struct content_html_data {
|
||||
* wasn't specified in the Content-Type header. */
|
||||
|
||||
char *base_url; /**< Base URL (may be a copy of content->url). */
|
||||
char *base_target; /**< Base target */
|
||||
|
||||
struct box *layout; /**< Box tree, or 0. */
|
||||
colour background_colour; /**< Document background colour. */
|
||||
@ -87,6 +141,12 @@ struct content_html_data {
|
||||
/** Browser window containing this document, or 0 if not open. */
|
||||
struct browser_window *bw;
|
||||
|
||||
/** Frameset information */
|
||||
struct content_html_frames *frameset;
|
||||
|
||||
/** Inline frame information */
|
||||
struct content_html_iframe *iframe;
|
||||
|
||||
/** Content of type CONTENT_HTML containing this, or 0 if not an object
|
||||
* within a page. */
|
||||
struct content *page;
|
||||
@ -108,7 +168,7 @@ void html_destroy(struct content *c);
|
||||
bool html_fetch_object(struct content *c, char *url, struct box *box,
|
||||
const content_type *permitted_types,
|
||||
int available_width, int available_height,
|
||||
bool background, char *frame);
|
||||
bool background);
|
||||
bool html_replace_object(struct content *c, unsigned int i, char *url,
|
||||
char *post_urlenc,
|
||||
struct form_successful_control *post_multipart);
|
||||
@ -117,8 +177,6 @@ void html_open(struct content *c, struct browser_window *bw,
|
||||
struct content *page, unsigned int index, struct box *box,
|
||||
struct object_params *params);
|
||||
void html_close(struct content *c);
|
||||
void html_find_target(struct content *c, const char *target,
|
||||
struct content **page, unsigned int *i);
|
||||
|
||||
/* in render/html_redraw.c */
|
||||
bool html_redraw(struct content *c, int x, int y,
|
||||
|
@ -20,9 +20,10 @@
|
||||
#define CONTENT_BLOCK_ADVERTISEMENTS 2
|
||||
#define CONTENT_BLOCK_POPUPS 3
|
||||
#define CONTENT_NO_PLUGINS 4
|
||||
#define CONTENT_DEFAULT_BUTTON 5
|
||||
#define CONTENT_CANCEL_BUTTON 6
|
||||
#define CONTENT_OK_BUTTON 7
|
||||
#define CONTENT_TARGET_BLANK 7
|
||||
#define CONTENT_DEFAULT_BUTTON 8
|
||||
#define CONTENT_CANCEL_BUTTON 9
|
||||
#define CONTENT_OK_BUTTON 10
|
||||
|
||||
static void ro_gui_options_content_default(wimp_pointer *pointer);
|
||||
static bool ro_gui_options_content_ok(wimp_w w);
|
||||
@ -35,11 +36,14 @@ bool ro_gui_options_content_initialise(wimp_w w) {
|
||||
option_block_popups);
|
||||
ro_gui_set_icon_selected_state(w, CONTENT_NO_PLUGINS,
|
||||
option_no_plugins);
|
||||
ro_gui_set_icon_selected_state(w, CONTENT_TARGET_BLANK,
|
||||
option_target_blank);
|
||||
|
||||
/* initialise all functions for a newly created window */
|
||||
ro_gui_wimp_event_register_checkbox(w, CONTENT_BLOCK_ADVERTISEMENTS);
|
||||
ro_gui_wimp_event_register_checkbox(w, CONTENT_BLOCK_POPUPS);
|
||||
ro_gui_wimp_event_register_checkbox(w, CONTENT_NO_PLUGINS);
|
||||
ro_gui_wimp_event_register_checkbox(w, CONTENT_TARGET_BLANK);
|
||||
ro_gui_wimp_event_register_button(w, CONTENT_DEFAULT_BUTTON,
|
||||
ro_gui_options_content_default);
|
||||
ro_gui_wimp_event_register_cancel(w, CONTENT_CANCEL_BUTTON);
|
||||
@ -59,6 +63,8 @@ void ro_gui_options_content_default(wimp_pointer *pointer) {
|
||||
false);
|
||||
ro_gui_set_icon_selected_state(pointer->w, CONTENT_NO_PLUGINS,
|
||||
false);
|
||||
ro_gui_set_icon_selected_state(pointer->w, CONTENT_TARGET_BLANK,
|
||||
true);
|
||||
}
|
||||
|
||||
bool ro_gui_options_content_ok(wimp_w w) {
|
||||
@ -68,6 +74,8 @@ bool ro_gui_options_content_ok(wimp_w w) {
|
||||
CONTENT_BLOCK_POPUPS);
|
||||
option_no_plugins = ro_gui_get_icon_selected_state(w,
|
||||
CONTENT_NO_PLUGINS);
|
||||
option_target_blank = ro_gui_get_icon_selected_state(w,
|
||||
CONTENT_TARGET_BLANK);
|
||||
|
||||
ro_gui_save_options();
|
||||
return true;
|
||||
|
34
riscos/gui.c
34
riscos/gui.c
@ -156,7 +156,7 @@ static bool gui_track = false;
|
||||
/** Handle of window which the pointer is over. */
|
||||
static wimp_w gui_track_wimp_w;
|
||||
/** Browser window which the pointer is over, or 0 if none. */
|
||||
static struct gui_window *gui_track_gui_window;
|
||||
struct gui_window *gui_track_gui_window;
|
||||
|
||||
/** Some windows have been resized, and should be reformatted. */
|
||||
bool gui_reformat_pending = false;
|
||||
@ -727,10 +727,6 @@ void gui_init2(int argc, char** argv)
|
||||
option_language);
|
||||
}
|
||||
|
||||
#ifdef WITH_KIOSK_BROWSING
|
||||
open_window = true;
|
||||
#endif
|
||||
|
||||
if (open_window)
|
||||
browser_window_create(url, NULL, 0, true);
|
||||
|
||||
@ -754,7 +750,7 @@ void gui_quit(void)
|
||||
rufl_quit();
|
||||
free(gui_sprites);
|
||||
xwimp_close_down(task_handle);
|
||||
free(default_stylesheet_url);
|
||||
free(default_stylesheet_url);
|
||||
free(adblock_stylesheet_url);
|
||||
xhourglass_off();
|
||||
}
|
||||
@ -1008,6 +1004,7 @@ void ro_gui_null_reason_code(void)
|
||||
|
||||
case GUI_DRAG_SELECTION:
|
||||
case GUI_DRAG_SCROLL:
|
||||
case GUI_DRAG_FRAME:
|
||||
assert(gui_track_gui_window);
|
||||
ro_gui_window_mouse_at(gui_track_gui_window, &pointer);
|
||||
break;
|
||||
@ -1168,6 +1165,7 @@ void ro_gui_pointer_leaving_window(wimp_leaving *leaving)
|
||||
case GUI_DRAG_SELECTION:
|
||||
case GUI_DRAG_SCROLL:
|
||||
case GUI_DRAG_SAVE:
|
||||
case GUI_DRAG_FRAME:
|
||||
/* ignore Pointer_Leaving_Window event that the Wimp mysteriously
|
||||
issues when a Wimp_DragBox drag operation is started */
|
||||
break;
|
||||
@ -1186,10 +1184,20 @@ void ro_gui_pointer_leaving_window(wimp_leaving *leaving)
|
||||
|
||||
void ro_gui_pointer_entering_window(wimp_entering *entering)
|
||||
{
|
||||
gui_track_wimp_w = entering->w;
|
||||
gui_track_gui_window = ro_gui_window_lookup(entering->w);
|
||||
gui_track = gui_track_gui_window || gui_track_wimp_w == history_window ||
|
||||
gui_track_wimp_w == dialog_url_complete;
|
||||
switch (gui_current_drag_type) {
|
||||
case GUI_DRAG_SELECTION:
|
||||
case GUI_DRAG_SCROLL:
|
||||
case GUI_DRAG_SAVE:
|
||||
case GUI_DRAG_FRAME:
|
||||
/* ignore entering new windows/frames */
|
||||
break;
|
||||
default:
|
||||
gui_track_wimp_w = entering->w;
|
||||
gui_track_gui_window = ro_gui_window_lookup(entering->w);
|
||||
gui_track = gui_track_gui_window || gui_track_wimp_w == history_window ||
|
||||
gui_track_wimp_w == dialog_url_complete;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1284,6 +1292,10 @@ void ro_gui_drag_end(wimp_dragged *drag)
|
||||
ro_gui_theme_toolbar_editor_drag_end(drag);
|
||||
break;
|
||||
|
||||
case GUI_DRAG_FRAME:
|
||||
ro_gui_window_frame_resize_end(gui_track_gui_window, drag);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(gui_current_drag_type == GUI_DRAG_NONE);
|
||||
break;
|
||||
@ -1500,6 +1512,8 @@ void ro_msg_dataload(wimp_message *message)
|
||||
|
||||
g = ro_gui_window_lookup(message->data.data_xfer.w);
|
||||
if (g) {
|
||||
while (g->bw->parent)
|
||||
g = g->bw->parent->window;
|
||||
if (ro_gui_window_dataload(g, message))
|
||||
return;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ extern wimp_w dialog_info, dialog_saveas, dialog_zoom, dialog_pageinfo,
|
||||
dialog_objinfo, dialog_tooltip, dialog_warning, dialog_openurl,
|
||||
dialog_debug, dialog_folder, dialog_entry, dialog_url_complete,
|
||||
dialog_search, dialog_print, dialog_theme_install;
|
||||
extern struct gui_window *gui_track_gui_window;
|
||||
extern wimp_w current_menu_window;
|
||||
extern bool current_menu_open;
|
||||
extern wimp_menu *font_menu; /* font.c */
|
||||
@ -58,7 +59,7 @@ extern struct tree *hotlist_tree, *global_history_tree, *cookies_tree;
|
||||
typedef enum { GUI_DRAG_NONE, GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE,
|
||||
GUI_DRAG_SAVE, GUI_DRAG_SCROLL, GUI_DRAG_STATUS_RESIZE,
|
||||
GUI_DRAG_TREE_SELECT, GUI_DRAG_TREE_MOVE,
|
||||
GUI_DRAG_TOOLBAR_CONFIG } gui_drag_type;
|
||||
GUI_DRAG_TOOLBAR_CONFIG, GUI_DRAG_FRAME } gui_drag_type;
|
||||
|
||||
extern gui_drag_type gui_current_drag_type;
|
||||
|
||||
@ -88,6 +89,8 @@ struct gui_window {
|
||||
int throbtime; /**< Time of last throbber frame. */
|
||||
|
||||
int iconise_icon; /**< ID number of icon when window is iconised */
|
||||
|
||||
char validation[12]; /**< Validation string for colours */
|
||||
|
||||
/** Options. */
|
||||
struct {
|
||||
@ -164,6 +167,7 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons);
|
||||
bool ro_gui_shift_pressed(void);
|
||||
bool ro_gui_ctrl_pressed(void);
|
||||
void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag);
|
||||
void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag);
|
||||
void ro_gui_window_set_scale(struct gui_window *g, float scale);
|
||||
void ro_gui_window_iconise(struct gui_window *g,
|
||||
wimp_full_message_window_info *wi);
|
||||
|
@ -1375,6 +1375,7 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
|
||||
int xeig, yeig;
|
||||
os_coord pixel = {1, 1};
|
||||
int top, bottom, right;
|
||||
bool parent_hscroll;
|
||||
|
||||
/* calculate 1px in OS units */
|
||||
ro_convert_pixels_to_os_units(&pixel, (os_mode)-1);
|
||||
@ -1411,7 +1412,7 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
|
||||
warn_user("WimpError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
|
||||
parent_hscroll = state.flags & wimp_WINDOW_HSCROLL;
|
||||
height = state.visible.y1 - state.visible.y0 + 2;
|
||||
|
||||
/* We can't obscure the height of the scroll bar as we
|
||||
@ -1677,7 +1678,7 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
|
||||
|
||||
/* Open or close the window
|
||||
*/
|
||||
if (!toolbar->display_status) {
|
||||
if ((!toolbar->display_status) || (!parent_hscroll)) {
|
||||
if (state.flags & wimp_WINDOW_OPEN)
|
||||
xwimp_close_window(toolbar->status_handle);
|
||||
} else {
|
||||
|
859
riscos/window.c
859
riscos/window.c
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include "netsurf/utils/filename.h"
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/url.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
#define FULL_WORD (unsigned int)4294967295
|
||||
@ -422,3 +423,26 @@ static struct directory *filename_create_directory(const char *prefix) {
|
||||
|
||||
return new_dir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a filename into a local URL
|
||||
*
|
||||
* \param filename the filename to convert
|
||||
* \return a local URL allocated on heap, or NULL on failure.
|
||||
*/
|
||||
char *filename_as_url(const char *filename) {
|
||||
char *temp, *url;
|
||||
int length;
|
||||
|
||||
length = strlen(TEMP_FILENAME_PREFIX) + strlen(filename) + 2;
|
||||
temp = malloc(length);
|
||||
if (!temp) {
|
||||
LOG(("No memory for malloc()"));
|
||||
return NULL;
|
||||
}
|
||||
sprintf(temp, "%s/%s", TEMP_FILENAME_PREFIX, filename);
|
||||
url = path_to_url(temp);
|
||||
free(temp);
|
||||
return url;
|
||||
}
|
||||
|
@ -21,5 +21,6 @@ bool filename_claim(const char *filename);
|
||||
void filename_release(const char *filename);
|
||||
bool filename_initialise(void);
|
||||
void filename_flush(void);
|
||||
char *filename_as_url(const char *filename);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user