The dom_string design
by Bo Yang
Hi,
After some thoughts about how to integrate lwc_string to libDOM, I
finally figure out a method. I propose as following, any advice are
welcomed.
1. Why we intern strings using lwc_string?
Of course, for squeezing space and efficient string comparison. But
also, interning string has its own cost, so I think interning all
strings in a webpage (or s/dom_string/lwc_string/g) is not a good
idea. There may be hundreds and thousands of strings, intern all these
will cause more collision in the hashtable and waste much memory.
2. Which type of string should we intern?
According 1, I propose to intern strings optionally. We should use
lwc_string to restore the strings, which appears multiple times and
which are necessary to compare frequently. Generally, I mean HTML tag
name, attribute name, enum-like attribute value (such as attribute
"display"'s value which include "inline", "block", "inline-block"...).
And the id attribute value as well as the class attribute value are
also good candidates for intern.
3. When to intern strings?
I think the best time to import lwc_string is when the webpage is
being parsed. The hubbub parser should create lwc_string when it come
across the above types of strings. I propose this way because, if the
hubbub did not create a lwc_string, we should create one in the libDOM
and this require two times of string scanning (one time when page get
parsed in hubbub and one time in libDOM for interning) and of course
not efficient.
For the XML parser, the only way left for us is to intern string in
libDOM. I mean, in the callbacks of libDOM binding.
4. What does the dom_string look like?
I propose, Change a little:
The origin is:
struct dom_string {
uint8_t *ptr; /**< Pointer to string data */
size_t len; /**< Byte length of string */
dom_alloc alloc; /**< Memory (de)allocation function */
void *pw; /**< Client-specific data */
uint32_t refcnt; /**< Reference count */
};
It should be changed to:
struct dom_string {
void *ptr; /**< Pointer to string data when
len >= 0, else pointer to the lwc_string which contain the real
string*/
int len; /**< Byte length of string when
len >=0 and if len == -1, it means the dom_string is intern in ptr */
dom_alloc alloc; /**< Memory (de)allocation function */
void *pw; /**< Client-specific data */
uint32_t refcnt; /**< Reference count */
};
I hope the above comment explain my intent well. The member len takes
two responsibility now. When it equals to -1, it means that the ptr
points to a lwc_string, otherwise if the "len >= 0", it means the ptr
points to a real string buffer. So, our dom_string comparison code
will like:
bool cmp(dom_string *str1, dom_string *str2){
if (str1->len==-1 && str2->len == -1)
return lwc_string_compare((lwc_string *)str1->ptr, (lwc_string
*)str2->ptr);
uint8_t *s1 = (uint8_t *)str1->ptr, *s2 = (uint8_t *)str2->ptr;
if (str1->len==-1)
s1 = STR_OF(str1->ptr);
if (str2->len == -1)
s2 = STR_OF(str2->ptr);
// Compare the two strings
}
5. Some more consideration...
When I think about the strings, I also suspect how we store a
character? Now, we use uint8_t in libDOM, but I think we should use
UTF-16 encoding in DOM. And use uint16_t to replace uint8_t.
I hope I have expressed my idea clearly, if anybody get confused by
me, please shot any question to me. Any criticism and advice will be
appreciated very much! Thanks!
Regards!
Bo
14 years, 4 months
Possible copyright infringement in your software distribution
by Rob Kendrick
Hi,
At the Wakefield Show this weekend, several people said they were using
NetSurf as it was shipped with a product you sold. I just thought I'd
drop you a line to make sure that you are distributing this software
legally, as it is surprising how many people don't realise they have
requirements if they wish to do so; otherwise they are essentially
pirating the software. If you are not distributing NetSurf in any
form, then sorry for the noise, although its contents of this email may
be applicable to any other software you distribute that is licenced
under the GPL (like many modern pieces of RISC OS 'freeware').
Basically, if you distribute a binary version of NetSurf, you are
compelled by the licence agreement under which you received NetSurf in
the first place to either include all of the source code alongside, or
provide a written offer valid for three years from the date of
distribution to provide it. Specifically, you should read section
three of the GPL, which I will include here;
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for
software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than
your cost of physically performing source distribution, a
complete machine-readable copy of the corresponding source
code, to be distributed under the terms of Sections 1 and 2
above on a medium customarily used for software interchange;
or,
c) Accompany it with the information you received as to
the offer to distribute corresponding source code. (This
alternative is allowed only for noncommercial distribution
and only if you received the program in object code or
executable form with such an offer, in accord with
Subsection b above.)
The entire licence, along with the other licences that effect NetSurf
(which are more liberal than the GPL, and thus most likely won't
concern you) are available from;
<http://www.netsurf-browser.org/about/licence>
You should note that you must also distribute a copy of the GPL licence
text along with NetSurf.
The easiest way to make sure you comply with the licence agreement you
have agreed to by redistributing NetSurf is to simply include a piece
of paper in any physical distribution that has the following written on
it;
"Some parts of this product are licenced under the General
Public Licence. You can request a copy of all the sources
to the parts of the software you are entitled to by sending
a request to <email address/postal address>."
You will get bonus points if you include a printed copy of the GPL
text, in addition to a digital copy. The GPL was written before the
internet was widespread, and so "written offer" is slightly confusing.
Most large companies include a physical sheet of paper in their
physical products to completely cover themselves. (Consider Netgear's
routers, which are based on Linux.)
You should also note that it is your responsibility to ensure you can
honour any source requests for three years, and not the NetSurf's
project's. As such, you should keep a copy of the sources for
everything that is GPLed that you distributed; simply forwarding on
your customers to a third party's website is unwise, as that site may
not be assessable in three years time.
If you have any questions or concerns, please don't hesitate to contact
me.
B.
14 years, 4 months
Review: Mark Benjamin: favs
by Daniel Silverstone
Precis:
This is the first issued review of Mark Benjamin's branch which implements
favicon support for the browser core and the GTK frontend.
Added files
Index: render/favicon.c
===================================================================
--- /dev/null 2008-11-24 10:09:14.252162000 +0000
+++ render/favicon.c 2009-04-28 16:01:49.412080078 +0100
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2007 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin(a)dfgh.net>
+ *
+ * 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/>.
+ */
+
+#include <string.h>
+#include "content/fetch.h"
+#include "content/fetchcache.h"
+#include "render/favicon.h"
+#include "render/html.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/talloc.h"
+#include "utils/url.h"
+#include "utils/utils.h"
+
+static char *html_get_icon_ref(struct content *c, xmlNode *html);
+static void html_favicon_callback(content_msg msg, struct content *icon,
+ intptr_t p1, intptr_t p2, union content_msg_data data);
+static unsigned long hash(char *str);
+
+unsigned long hash(char *str)
+{
+ if (str == NULL)
+ return 0;
+ unsigned long hash = 5381;
+ int c;
+ while ((c = (unsigned char) *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ return hash;
+}
+
+/**
+ * retrieve 1 url reference to 1 favicon
+ * \param html xml node of html element
+ * \return pointer to url; NULL for no icon
+ */
+char *html_get_icon_ref(struct content *c, xmlNode *html)
+{
+ xmlNode *node;
+ char *rel, *type, *href, *url, *suf, *url2;
+ url2 = NULL;
+ url_func_result res;
+ int score, hiscore;
+ hiscore = 0;
+ /* hashed values - saves calculating them afresh every time */
+ #define HHICON 0x7c98572e
+ /* icon */
+ #define HHSHORTCUTICON 0xfcbccdca
+ /* shortcut icon */
+ #define HHAPPLETOUCHICON 0x024c6ddd
+ /* apple-touch-icon */
+ #define HHIMAGEPNG 0x7382417c
+ /* image/png */
+ #define HHIMAGEGIF 0x73821a8d
+ /* image/gif */
+ #define HHIMAGEVNDMICROSOFTICON 0xdae02bba
+ /* image.vnd.microsoft.icon */
+ #define HHIMAGEJPEG 0xe3c72f5d
+ /* image/jpeg */
+ #define HHIMAGEJPG 0x73822838
+ /* image/jpg */
+ #define HHIMAGEICO 0x73822252
+ /* image/ico */
+ #define HHIMAGEICON 0xe3c66d00
+ /* image/icon */
+ #define HHIMAGEXICON 0x0e3e78e5
+ /* image/x-icon */
+ #define HHTEXTICO 0x17e966a2
+ /* text/icon */
+ #define HHAPPLICATIONICO 0x087b6fb4
+ /*application/icon*/
+ #define HHSUFICO 0x0b887ec0
+ /* ico */
+ #define HHSUFPNG 0x0b889dea
+ /* png */
+ #define HHSUFGIF 0x0b8876fb
+ /* gif */
+ #define HHSUFJPG 0x0b888486
+ /* jpg */
+ #define HHSUFJPEG 0x7c99198b
+ /* jpeg */
+
+ union content_msg_data msg_data;
+
+ node = html;
+ while (node) {
+ score = 0;
+ suf = NULL;
+ if (node->children) { /* children */
+ node = node->children;
+ } else if (node->next) { /* siblings */
+ node = node->next;
+ } else { /* ancestor siblings */
+ while (node && !node->next)
+ node = node->parent;
+ if (!node)
+ break;
+ node = node->next;
+ }
+ assert(node);
+
+ if (node->type != XML_ELEMENT_NODE)
+ continue;
+
+ if (strcmp((const char *) node->name, "link") == 0) {
+ /* rel=<space separated list, including 'icon'> */
+ if ((rel = (char *) xmlGetProp(node,
+ (const xmlChar *) "rel")) == NULL)
+ continue;
+ if (strcasestr(rel, "icon") == 0) {
+ xmlFree(rel);
+ continue;
+ }
+ LOG(("icon node found"));
+ switch(hash(rel)) {
+ case HHICON:
+ LOG(("icon"));
+ score = 3;
+ break;
+ case HHSHORTCUTICON:
+ LOG(("shortcut icon"));
+ score = 5;
+ break;
+ case HHAPPLETOUCHICON:
+ LOG(("apple-touch-icon"));
+ score = 1;
+ break;
+ }
+ xmlFree(rel);
+ /* current implementation scores candidates according
+ * to how closely they seem to adhere to standards,
+ * scoring system may be modified in the future */
+ if ((type = (char *) xmlGetProp(node,
+ (const xmlChar *) "type")) != NULL) {
+ switch(hash(type)) {
+ case HHIMAGEPNG:
+ score += 5;
+ break;
+ case HHIMAGEGIF:
+ score += 5;
+ break;
+ case HHIMAGEVNDMICROSOFTICON:
+ score += 5;
+ break;
+ case HHIMAGEJPEG:
+ score += 5;
+ break;
+ case HHIMAGEJPG:
+ score += 5;
+ break;
+ case HHIMAGEICO:
+ score += 5;
+ break;
+ case HHIMAGEICON:
+ score += 5;
+ break;
+ case HHIMAGEXICON:
+ score += 5;
+ break;
+ case HHTEXTICO:
+ score += 2;
+ break;
+ case HHAPPLICATIONICO:
+ score += 1;
+ break;
+ }
+ xmlFree(type);
+ }
+ if ((href = (char *) xmlGetProp(node,
+ (const xmlChar *) "href")) == NULL)
+ continue;
+ suf = strrchr(href, '.');
+ if (suf != NULL) {
+ suf ++;
+ switch(hash(suf)) {
+ case HHSUFICO:
+ score += 10;
+ break;
+ case HHSUFPNG:
+ score += 10;
+ break;
+ case HHSUFGIF:
+ score += 10;
+ break;
+ case HHSUFJPG:
+ score += 7;
+ break;
+ case HHSUFJPEG:
+ score += 7;
+ break;
+ }
+ }
+ if (score > hiscore) {
+ res = url_join(href, c->data.html.base_url,
+ &url);
+ xmlFree(href);
+ if (res != URL_FUNC_OK)
+ continue;
+
+ LOG(("best favicon so far '%s'", url));
+ res = url_normalize(url, &url2);
+ if (res != URL_FUNC_OK) {
+ url2 = NULL;
+ if (res == URL_FUNC_NOMEM)
+ goto no_memory;
+ continue;
+ }
+ hiscore = score;
+ free(url);
+ }
+ }
+ }
+ if (url2 == NULL) {
+ struct url_components comp;
+ if (url_get_components(c->data.html.base_url, &comp) !=
+ URL_FUNC_OK)
+ return NULL;
+ if (url_normalize(comp.authority,
+ &url) != URL_FUNC_OK)
+ return NULL;
+ url_destroy_components(&comp);
+ if (url_join("/favicon.ico", url, &url2) != URL_FUNC_OK)
+ return NULL;
+ free(url);
+ }
+ LOG(("Best favicon %s", url2));
+ return url2;
+no_memory:
+ msg_data.error = messages_get("NoMemory");
+ /* content_broadcast(c, CONTENT_MSG_ERROR, msg_data); */
+ return false;
+}
+
+/**
+ * retrieve 1 favicon
+ * \param c content structure
+ * \param html xml node of html element
+ * \return true for success, false for error
+ */
+
+bool html_get_icon(struct content *c, xmlNode *html)
+{
+ union content_msg_data msg_data;
+ char *url = html_get_icon_ref(c, html);
+ struct content *favcontent = NULL;
+ if (url != NULL)
+ favcontent = fetchcache(url, html_favicon_callback,
+ (intptr_t) c, 0, c->width, c->height, true, 0,
+ 0, false, false);
+ free(url);
+ if (favcontent == NULL)
+ return false;
+
+ c->data.html.favicon = favcontent;
+
+ fetchcache_go(favcontent, c->url, html_favicon_callback,
+ (intptr_t) c, 0, c->width, c->height,
+ 0, 0, false, c->url);
+
+ if (!c->data.html.favicon) {
+ msg_data.error = "Favicon failed to load";
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Callback for fetchcache() for linked favicon
+ */
+
+void html_favicon_callback(content_msg msg, struct content *icon,
+ intptr_t p1, intptr_t p2, union content_msg_data data)
+{
+ struct content *c = (struct content *) p1;
+ unsigned int i = p2;
+
+ switch (msg) {
+ case CONTENT_MSG_LOADING:
+ /* check that the favicon is really a correct image
+ * type */
+
+ if ((icon->type == CONTENT_ICO) ||
+ (icon->type == CONTENT_PNG) ||
+ (icon->type == CONTENT_GIF)) {
+
+ /* may need call to content_open() */
+
+ } else {
+ c->data.html.favicon = 0;
+ LOG(("%s is not a favicon", icon->url));
+ content_add_error(c, "NotFavIco", 0);
+ html_set_status(c, messages_get("NotFavIco"));
+ content_broadcast(c, CONTENT_MSG_STATUS, data);
+ content_remove_user(icon,
+ html_favicon_callback,
+ (intptr_t) c, i);
+ if (!icon->user_list->next) {
+ /* we were the only user and we
+ * don't want this content, so
+ * stop it fetching and mark it
+ * as having an error so it gets
+ * removed from the cache next time
+ * content_clean() gets called */
+ fetch_abort(icon->fetch);
+ icon->fetch = 0;
+ icon->status = CONTENT_STATUS_ERROR;
+ }
+ }
+ break;
+
+ case CONTENT_MSG_READY:
+ break;
+
+ case CONTENT_MSG_DONE:
+ LOG(("got favicon '%s'", icon->url));
+ break;
+
+ case CONTENT_MSG_LAUNCH:
+ /* Fall through */
+ case CONTENT_MSG_ERROR:
+ LOG(("favicon %s failed: %s", icon->url, data.error));
+ /* The favicon we were fetching may have been
+ * redirected, in that case, the object pointers
+ * will differ, so ensure that the object that's
+ * in error is still in use by us before invalidating
+ * the pointer */
+ if (c->data.html.favicon == icon) {
+ c->data.html.favicon = 0;
+ content_add_error(c, "?", 0);
+ }
+ break;
+
+ case CONTENT_MSG_STATUS:
+ html_set_status(c, icon->status_message);
+ content_broadcast(c, CONTENT_MSG_STATUS, data);
+ break;
+
+ case CONTENT_MSG_NEWPTR:
+ c->data.html.favicon = icon;
+ break;
+
+ case CONTENT_MSG_AUTH:
+ c->data.html.favicon = 0;
+ content_add_error(c, "?", 0);
+ break;
+
+ case CONTENT_MSG_SSL:
+ c->data.html.favicon = 0;
+ content_add_error(c, "?", 0);
+ break;
+
+ default:
+ assert(0);
+ }
+}
Index: render/favicon.h
===================================================================
--- /dev/null 2008-11-24 10:09:14.252162000 +0000
+++ render/favicon.h 2009-04-28 16:01:49.412080078 +0100
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2007 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin(a)dfgh.net>
+ *
+ * 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/>.
+ */
+
+#ifndef __NETSURF_RENDER_FAVICON_H__
+#define __NETSURF_RENDER_FAVICON_H__
+
+bool html_get_icon(struct content *c, xmlNode *html);
+
+#endif
Changed files
!NetSurf/Resources/en/Messages | 1
Makefile.sources | 2
amiga/gui.c | 4 +
beos/beos_scaffolding.cpp | 4 +
desktop/browser.c | 17 ++++++
desktop/gui.h | 1
desktop/print.c | 2
framebuffer/fb_gui.c | 4 +
gtk/dialogs/gtk_options.c | 41 +++++++++-----
gtk/dialogs/gtk_source.c | 36 +++++++++++++
gtk/gtk_bitmap.c | 7 +-
gtk/gtk_scaffolding.c | 99 ++++++++++++++++++++++++++++++++++-
gtk/gtk_scaffolding.h | 44 +--------------
gtk/gtk_tabs.c | 2
gtk/options.h | 7 +-
gtk/res/netsurf.glade | 113 ++++++++++++++++++++++++-----------------
gtk/res/options.glade | 60 +++++++++++++++++++++
image/ico.c | 9 +++
image/ico.h | 2
render/html.c | 60 +++++++++++++--------
render/html.h | 3 +
riscos/window.c | 3 +
22 files changed, 386 insertions(+), 135 deletions(-)
Index: render/html.c
===================================================================
--- render/html.c (revision 7353)
+++ render/html.c (working copy)
@@ -36,7 +36,11 @@
#include "desktop/gui.h"
#include "desktop/options.h"
#include "image/bitmap.h"
+#include "image/png.h"
+#include "image/gif.h"
+#include "image/ico.h"
#include "render/box.h"
+#include "render/favicon.h"
#include "render/font.h"
#include "render/form.h"
#include "render/html.h"
@@ -73,7 +77,6 @@ static bool html_object_type_permitted(c
static void html_object_refresh(void *p);
static void html_destroy_frameset(struct content_html_frames *frameset);
static void html_destroy_iframe(struct content_html_iframe *iframe);
-static void html_set_status(struct content *c, const char *extra);
#if ALWAYS_DUMP_FRAMESET
static void html_dump_frameset(struct content_html_frames *frame,
unsigned int depth);
@@ -161,7 +164,7 @@ bool html_create(struct content *c, cons
error:
if (error == BINDING_BADENCODING) {
- LOG(("Bad encoding: %s", html->encoding ? html->encoding : ""));
+ LOG(("Bad encoding: %s", html->encoding ? html->encoding :""));
msg_data.error = messages_get("ParsingFail");
} else
msg_data.error = messages_get("NoMemory");
@@ -283,6 +286,7 @@ encoding_change:
*
* - parsing to an XML tree is completed
* - stylesheets are fetched
+ * - favicon is retrieved
* - the XML tree is converted to a box tree and object fetches are started
* - the box tree is laid out
*
@@ -399,6 +403,9 @@ bool html_convert(struct content *c, int
if (!html_find_stylesheets(c, html))
return false;
+ /* get icon */
+ html_get_icon(c, html);
+
/* Retrieve forms from parser */
c->data.html.forms = binding_get_forms(c->data.html.parser_binding);
for (f = c->data.html.forms; f != NULL; f = f->prev) {
@@ -534,17 +541,20 @@ bool html_head(struct content *c, xmlNod
}
xmlFree(href);
}
- /* don't use the central values to ease freeing later on */
- if ((s = xmlGetProp(node, (const xmlChar *) "target"))) {
- if ((!strcasecmp((const char *) s, "_blank")) ||
- (!strcasecmp((const char *) s,
- "_top")) ||
- (!strcasecmp((const char *) s,
- "_parent")) ||
- (!strcasecmp((const char *) s,
- "_self")) ||
+ /* don't use the central values to ease freeing later
+ * on */
+ if ((s = xmlGetProp(node, (const xmlChar *)
+ "target"))) {
+ if ((!strcasecmp((const char *) s, "_blank"))
+ ||(!strcasecmp((const char *)
+ s, "_top")) || (!strcasecmp(
+ (const char *) s, "_parent"))
+ || (!strcasecmp((const char *)
+ s, "_self")) ||
('a' <= s[0] && s[0] <= 'z') ||
- ('A' <= s[0] && s[0] <= 'Z')) { /* [6.16] */
+ ('A' <= s[0] && s[0] <= 'Z')
+ ) {
+ /* [6.16] */
c->data.html.base_target =
talloc_strdup(c,
(const char *) s);
@@ -615,7 +625,8 @@ bool html_meta_refresh(struct content *c
end = (char *) content + strlen((const char *) content);
- /* content := *LWS intpart fracpart? *LWS [';' *LWS *1url *LWS]
+ /* content := *LWS intpart fracpart? *LWS [';' *LWS *1url
+ * *LWS]
* intpart := 1*DIGIT
* fracpart := 1*('.' | DIGIT)
* url := "url" *LWS '=' *LWS (url-nq | url-sq | url-dq)
@@ -758,14 +769,13 @@ bool html_meta_refresh(struct content *c
return true;
}
-
/**
* Process inline stylesheets and fetch linked stylesheets.
*
* Uses STYLE and LINK elements inside and outside HEAD
*
* \param c content structure
- * \param head xml node of html element
+ * \param html xml node of html element
* \return true on success, false if an error occurred
*/
@@ -844,7 +854,7 @@ bool html_find_stylesheets(struct conten
if (strcmp((const char *) node->name, "link") == 0) {
- /* rel=<space separated list, including 'stylesheet'> */
+ /* rel=<space separated list, including 'stylesheet'>*/
if ((rel = (char *) xmlGetProp(node,
(const xmlChar *) "rel")) == NULL)
continue;
@@ -872,7 +882,8 @@ bool html_find_stylesheets(struct conten
if ((media = (char *) xmlGetProp(node,
(const xmlChar *) "media")) != NULL) {
if (strcasestr(media, "screen") == 0 &&
- strcasestr(media, "all") == 0) {
+ strcasestr(media, "all")
+ == 0) {
xmlFree(media);
continue;
}
@@ -947,7 +958,8 @@ bool html_find_stylesheets(struct conten
html_convert_css_callback,
(intptr_t) c, STYLESHEET_STYLE)) {
/* no memory */
- c->data.html.stylesheet_content[STYLESHEET_STYLE] = 0;
+ c->data.html.stylesheet_content[
+ STYLESHEET_STYLE] = 0;
goto no_memory;
}
} else {
@@ -1127,7 +1139,8 @@ void html_convert_css_callback(content_m
case CONTENT_MSG_LAUNCH:
/* Fall through */
case CONTENT_MSG_ERROR:
- LOG(("stylesheet %s failed: %s", css->url, data.error));
+ LOG(("stylesheet %s failed: %s", css->url,
+ data.error));
/* The stylesheet we were fetching may have been
* redirected, in that case, the object pointers
* will differ, so ensure that the object that's
@@ -1672,7 +1685,8 @@ void html_stop(struct content *c)
(intptr_t) c, i);
else {
content_remove_user(c->data.html.object[i].content,
- html_object_callback, (intptr_t) c, i);
+ html_object_callback, (intptr_t) c,
+ i);
c->data.html.object[i].content = 0;
}
}
@@ -1778,8 +1792,10 @@ void html_destroy(struct content *c)
LOG(("object %i %p", i, c->data.html.object[i].content));
if (c->data.html.object[i].content) {
content_remove_user(c->data.html.object[i].content,
- html_object_callback, (intptr_t) c, i);
- if (c->data.html.object[i].content->type == CONTENT_HTML)
+ html_object_callback, (intptr_t) c,
+ i);
+ if (c->data.html.object[i].content->type ==
+ CONTENT_HTML)
schedule_remove(html_object_refresh,
c->data.html.object[i].content);
}
Index: render/html.h
===================================================================
--- render/html.h (revision 7353)
+++ render/html.h (working copy)
@@ -128,6 +128,8 @@ struct content_html_data {
colour background_colour; /**< Document background colour. */
const struct font_functions *font_func;
+ struct content *favicon;
+
/** Number of entries in stylesheet_content. */
unsigned int stylesheet_count;
/** Stylesheets. Each may be 0. */
@@ -184,6 +186,7 @@ void html_open(struct content *c, struct
struct content *page, unsigned int index, struct box *box,
struct object_params *params);
void html_close(struct content *c);
+void html_set_status(struct content *c, const char *extra);
/* in render/html_redraw.c */
bool html_redraw(struct content *c, int x, int y,
Index: image/ico.c
===================================================================
--- image/ico.c (revision 7353)
+++ image/ico.c (working copy)
@@ -114,6 +114,15 @@ bool nsico_redraw(struct content *c, int
background_colour, c);
}
+bool nsico_set_bitmap_from_size(struct content *c, int width, int height)
+{
+ struct bmp_image *bmp = ico_find(c->data.ico.ico, width, height);
+ if (!bmp->decoded)
+ if (bmp_decode(bmp) != BMP_OK)
+ return false;
+ c->bitmap = bmp->bitmap;
+ return true;
+}
bool nsico_redraw_tiled(struct content *c, int x, int y,
int width, int height,
Index: image/ico.h
===================================================================
--- image/ico.h (revision 7353)
+++ image/ico.h (working copy)
@@ -47,7 +47,7 @@ bool nsico_redraw_tiled(struct content *
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale, colour background_colour,
bool repeat_x, bool repeat_y);
-
+bool nsico_set_bitmap_from_size(struct content *c, int width, int height);
#endif /* WITH_BMP */
#endif
Index: framebuffer/fb_gui.c
===================================================================
--- framebuffer/fb_gui.c (revision 7353)
+++ framebuffer/fb_gui.c (working copy)
@@ -1000,6 +1000,10 @@ void gui_window_stop_throbber(struct gui
}
+void gui_window_set_icon(struct gui_window *g, struct content *icon)
+{
+}
+
void gui_window_place_caret(struct gui_window *g, int x, int y, int height)
{
}
Index: gtk/options.h
===================================================================
--- gtk/options.h (revision 7353)
+++ gtk/options.h (working copy)
@@ -34,6 +34,7 @@ extern int option_history_age;
extern bool option_hover_urls;
extern bool option_focus_new;
extern bool option_new_blank;
+extern bool option_source_tab;
#define EXTRA_OPTION_DEFINE \
bool option_render_resample = false; \
@@ -48,7 +49,8 @@ bool option_disable_plugins = false; \
int option_history_age = 0; \
bool option_hover_urls = false; \
bool option_focus_new = false; \
-bool option_new_blank = false;
+bool option_new_blank = false; \
+bool option_source_tab = false;
#define EXTRA_OPTION_TABLE \
{ "render_resample", OPTION_BOOL, &option_render_resample }, \
@@ -63,6 +65,7 @@ bool option_new_blank = false;
{ "history_age", OPTION_INTEGER, &option_history_age}, \
{ "hover_urls", OPTION_BOOL, &option_hover_urls}, \
{ "focus_new", OPTION_BOOL, &option_focus_new}, \
-{ "new_blank", OPTION_BOOL, &option_new_blank}
+{ "new_blank", OPTION_BOOL, &option_new_blank}, \
+{ "source_tab", OPTION_BOOL, &option_source_tab}
#endif
Index: gtk/gtk_bitmap.c
===================================================================
--- gtk/gtk_bitmap.c (revision 7353)
+++ gtk/gtk_bitmap.c (working copy)
@@ -34,6 +34,9 @@
#include "utils/log.h"
+#define MIN_PRETILE_WIDTH 256
+#define MIN_PRETILE_HEIGHT 256
+
struct bitmap {
GdkPixbuf *primary;
GdkPixbuf *pretile_x;
@@ -41,10 +44,6 @@ struct bitmap {
GdkPixbuf *pretile_xy;
};
-#define MIN_PRETILE_WIDTH 256
-#define MIN_PRETILE_HEIGHT 256
-
-
/**
* Create a bitmap.
*
Index: gtk/gtk_scaffolding.c
===================================================================
--- gtk/gtk_scaffolding.c (revision 7353)
+++ gtk/gtk_scaffolding.c (working copy)
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libxml/debugXML.h>
#include "content/content.h"
#include "desktop/browser.h"
@@ -37,6 +38,7 @@
#endif
#include "desktop/selection.h"
#include "desktop/textinput.h"
+#include "gtk/gtk_bitmap.h"
#include "gtk/gtk_completion.h"
#include "gtk/dialogs/gtk_options.h"
#include "gtk/dialogs/gtk_about.h"
@@ -52,6 +54,7 @@
#include "gtk/gtk_throbber.h"
#include "gtk/gtk_window.h"
#include "gtk/options.h"
+#include "image/ico.h"
#include "render/box.h"
#include "render/font.h"
#include "render/form.h"
@@ -77,6 +80,44 @@ struct menu_events {
GCallback handler;
};
+struct gtk_scaffolding {
+ GtkWindow *window;
+ GtkNotebook *notebook;
+ GtkEntry *url_bar;
+ GtkEntryCompletion *url_bar_completion;
+ GtkStatusbar *status_bar;
+ GtkMenuItem *edit_menu;
+ GtkMenuItem *tabs_menu;
+ GtkToolbar *tool_bar;
+ GtkToolButton *back_button;
+ GtkToolButton *history_button;
+ GtkToolButton *forward_button;
+ GtkToolButton *stop_button;
+ GtkToolButton *reload_button;
+ GtkToolItem *toolFav;
+ GtkMenuBar *menu_bar;
+ GtkMenuItem *back_menu;
+ GtkMenuItem *forward_menu;
+ GtkMenuItem *stop_menu;
+ GtkMenuItem *reload_menu;
+ GtkImage *throbber;
+ GtkPaned *status_pane;
+
+ GladeXML *xml;
+
+ GladeXML *popup_xml;
+ GtkMenu *popup_menu;
+
+ struct gtk_history_window *history_window;
+ GtkDialog *preferences_dialog;
+
+ int throb_frame;
+ struct gui_window *top_level;
+ int being_destroyed;
+
+ bool fullscreen;
+};
+
static int open_windows = 0; /**< current number of open browsers */
static struct gtk_scaffolding *current_model; /**< current window for model
dialogue use */
@@ -1238,6 +1279,7 @@ nsgtk_scaffolding *nsgtk_new_scaffolding
g->forward_menu = GTK_MENU_ITEM(GET_WIDGET("forward"));
g->stop_menu = GTK_MENU_ITEM(GET_WIDGET("stop"));
g->reload_menu = GTK_MENU_ITEM(GET_WIDGET("reload"));
+ g->toolFav = GTK_TOOL_ITEM(GET_WIDGET("toolFav"));
g->throbber = GTK_IMAGE(GET_WIDGET("throbber"));
g->preferences_dialog = NULL;
@@ -1378,8 +1420,10 @@ nsgtk_scaffolding *nsgtk_new_scaffolding
/* connect history window signals to their handlers */
CONNECT(g->history_window->drawing_area, "expose_event",
nsgtk_history_expose_event, g->history_window);
-// CONNECT(g->history_window->drawing_area, "motion_notify_event",
-// nsgtk_history_motion_notify_event, g->history_window);
+ /*
+ CONNECT(g->history_window->drawing_area, "motion_notify_event",
+ nsgtk_history_motion_notify_event, g->history_window);
+ */
CONNECT(g->history_window->drawing_area, "button_press_event",
nsgtk_history_button_press_event, g->history_window);
CONNECT(g->history_window->window, "delete_event",
@@ -1546,6 +1590,40 @@ void gui_window_stop_throbber(struct gui
gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]);
}
+/**
+ * set favicon
+ */
+void gui_window_set_icon(struct gui_window *_g, struct content *icon)
+{
+ struct gtk_scaffolding *g = nsgtk_get_scaffold(_g);
+ GtkWidget *currenticon = gtk_bin_get_child(GTK_BIN(g->toolFav));
+ GtkImage *iconImage = NULL;
+ if (currenticon != NULL) {
+ gtk_container_remove(GTK_CONTAINER(g->toolFav),
+ currenticon);
+ }
+ if ((icon != NULL) && (icon->type == CONTENT_ICO)) {
+ nsico_set_bitmap_from_size(icon, 20, 20);
+ }
+ if ((icon != NULL) && (icon->bitmap != NULL)) {
+ GdkPixbuf *pb = gtk_bitmap_get_primary(icon->bitmap);
+ if ((pb != NULL) && (gdk_pixbuf_get_width(pb) > 0) &&
+ (gdk_pixbuf_get_height(pb) > 0)) {
+ pb = gdk_pixbuf_scale_simple(pb, 20, 20,
+ GDK_INTERP_HYPER);
+ iconImage = GTK_IMAGE(
+ gtk_image_new_from_pixbuf(pb));
+ } else {
+ iconImage = NULL;
+ }
+ }
+ if (iconImage == NULL)
+ iconImage = GTK_IMAGE(gtk_image_new_from_file(g_strconcat(
+ res_dir_location, "netsurf-16x16.xpm", NULL)));
+ gtk_container_add(GTK_CONTAINER(g->toolFav), GTK_WIDGET(
+ iconImage));
+ gtk_widget_show_all(GTK_WIDGET(g->toolFav));
+}
gboolean nsgtk_scaffolding_is_busy(struct gtk_scaffolding *scaffold)
{
@@ -1563,14 +1641,24 @@ GtkNotebook* nsgtk_scaffolding_get_noteb
return g->scaffold->notebook;
}
+GtkEntry *nsgtk_scaffolding_get_urlbar(struct gui_window *g)
+{
+ return g->scaffold->url_bar;
+}
+
+GtkToolbar *nsgtk_scaffolding_get_toolbar(struct gui_window *g)
+{
+ return g->scaffold->tool_bar;
+}
+
+
void nsgtk_scaffolding_set_top_level (struct gui_window *gw)
{
gw->scaffold->top_level = gw;
-
/* Synchronise the history (will also update the URL bar) */
nsgtk_window_update_back_forward(gw->scaffold);
- /* Ensure the window's title bar is updated */
+ /* Ensure the window's title bar as well as favicon are updated */
if (gw->bw != NULL && gw->bw->current_content != NULL) {
if (gw->bw->current_content->title != NULL) {
gui_window_set_title(gw,
@@ -1578,6 +1666,9 @@ void nsgtk_scaffolding_set_top_level (st
} else {
gui_window_set_title(gw, gw->bw->current_content->url);
}
+ if (gw->bw->current_content->type == CONTENT_HTML)
+ gui_window_set_icon(gw, gw->bw->current_content->
+ data.html.favicon);
}
}
Index: gtk/gtk_scaffolding.h
===================================================================
--- gtk/gtk_scaffolding.h (revision 7353)
+++ gtk/gtk_scaffolding.h (working copy)
@@ -26,52 +26,16 @@
typedef struct gtk_scaffolding nsgtk_scaffolding;
-struct gtk_scaffolding {
- GtkWindow *window;
- GtkNotebook *notebook;
- GtkEntry *url_bar;
- GtkEntryCompletion *url_bar_completion;
- GtkStatusbar *status_bar;
- GtkMenuItem *edit_menu;
- GtkMenuItem *tabs_menu;
- GtkToolbar *tool_bar;
- GtkToolButton *back_button;
- GtkToolButton *history_button;
- GtkToolButton *forward_button;
- GtkToolButton *stop_button;
- GtkToolButton *reload_button;
- GtkMenuBar *menu_bar;
- GtkMenuItem *back_menu;
- GtkMenuItem *forward_menu;
- GtkMenuItem *stop_menu;
- GtkMenuItem *reload_menu;
- GtkImage *throbber;
- GtkPaned *status_pane;
-
- GladeXML *xml;
-
- GladeXML *popup_xml;
- GtkMenu *popup_menu;
-
- struct gtk_history_window *history_window;
- GtkDialog *preferences_dialog;
-
- int throb_frame;
- struct gui_window *top_level;
- int being_destroyed;
-
- bool fullscreen;
-};
-
GtkWindow *nsgtk_get_window_for_scaffold(struct gtk_scaffolding *g);
nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel);
gboolean nsgtk_scaffolding_is_busy(nsgtk_scaffolding *scaffold);
-GtkWindow* nsgtk_scaffolding_get_window (struct gui_window *g);
-
-GtkNotebook* nsgtk_scaffolding_get_notebook (struct gui_window *g);
+GtkWindow *nsgtk_scaffolding_get_window (struct gui_window *g);
+GtkNotebook *nsgtk_scaffolding_get_notebook (struct gui_window *g);
+GtkEntry *nsgtk_scaffolding_get_urlbar(struct gui_window *g);
+GtkToolbar *nsgtk_scaffolding_get_toolbar(struct gui_window *g);
void nsgtk_scaffolding_set_top_level (struct gui_window *gw);
Index: gtk/gtk_tabs.c
===================================================================
--- gtk/gtk_tabs.c (revision 7353)
+++ gtk/gtk_tabs.c (working copy)
@@ -81,7 +81,7 @@ void nsgtk_tab_add(struct gui_window *wi
}
if (background)
gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), remember);
- gtk_widget_grab_focus(GTK_WIDGET(window->scaffold->url_bar));
+ gtk_widget_grab_focus(GTK_WIDGET(nsgtk_scaffolding_get_urlbar(window)));
}
void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
Index: gtk/dialogs/gtk_options.c
===================================================================
--- gtk/dialogs/gtk_options.c (revision 7353)
+++ gtk/dialogs/gtk_options.c (working copy)
@@ -97,6 +97,8 @@ DECLARE(checkRequestOverwrite);
DECLARE(fileChooserDownloads);
DECLARE(checkFocusNew);
DECLARE(checkNewBlank);
+DECLARE(sourceButtonTab);
+static GtkWidget *sourceButtonWindow;
DECLARE(spinMarginTop);
DECLARE(spinMarginBottom);
@@ -133,6 +135,12 @@ GtkDialog* nsgtk_options_init(struct bro
"dlgPreferences"));
gtk_window_set_transient_for (GTK_WINDOW(wndPreferences), parent);
+ FIND_WIDGET(sourceButtonTab);
+ FIND_WIDGET(sourceButtonWindow);
+ GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(
+ sourceButtonWindow));
+ gtk_radio_button_set_group(GTK_RADIO_BUTTON(sourceButtonTab), group);
+
/* set the widgets to reflect the current options */
nsgtk_options_load();
@@ -187,6 +195,7 @@ GtkDialog* nsgtk_options_init(struct bro
CONNECT(checkFocusNew, "toggled");
CONNECT(checkNewBlank, "toggled");
+ CONNECT(sourceButtonTab, "toggled");
CONNECT(spinMarginTop, "value-changed");
CONNECT(spinMarginBottom, "value-changed");
@@ -388,6 +397,7 @@ void nsgtk_options_load(void)
SET_CHECK(checkFocusNew, option_focus_new);
SET_CHECK(checkNewBlank, option_new_blank);
+ SET_CHECK(sourceButtonTab, option_source_tab);
SET_SPIN(spinMarginTop, option_margin_top);
SET_SPIN(spinMarginBottom, option_margin_bottom);
@@ -647,26 +657,26 @@ COMBO_CHANGED(comboButtonType, option_bu
while (current) {
switch(option_button_type) {
case 1:
- gtk_toolbar_set_style(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_TOOLBAR_ICONS);
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_toolbar_set_style(nsgtk_scaffolding_get_toolbar(
+ current), GTK_TOOLBAR_ICONS);
+ gtk_toolbar_set_icon_size(nsgtk_scaffolding_get_toolbar(
+ current), GTK_ICON_SIZE_SMALL_TOOLBAR);
break;
case 2:
- gtk_toolbar_set_style(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_TOOLBAR_ICONS);
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_toolbar_set_style(nsgtk_scaffolding_get_toolbar(
+ current), GTK_TOOLBAR_ICONS);
+ gtk_toolbar_set_icon_size(nsgtk_scaffolding_get_toolbar(
+ current), GTK_ICON_SIZE_LARGE_TOOLBAR);
break;
case 3:
- gtk_toolbar_set_style(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_TOOLBAR_BOTH);
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_toolbar_set_style(nsgtk_scaffolding_get_toolbar(
+ current), GTK_TOOLBAR_BOTH);
+ gtk_toolbar_set_icon_size(nsgtk_scaffolding_get_toolbar(
+ current), GTK_ICON_SIZE_LARGE_TOOLBAR);
break;
case 4:
- gtk_toolbar_set_style(GTK_TOOLBAR(current->scaffold->tool_bar),
- GTK_TOOLBAR_TEXT);
+ gtk_toolbar_set_style(nsgtk_scaffolding_get_toolbar(
+ current), GTK_TOOLBAR_TEXT);
default:
break;
}
@@ -696,6 +706,9 @@ END_HANDLER
CHECK_CHANGED(checkNewBlank, option_new_blank)
END_HANDLER
+CHECK_CHANGED(sourceButtonTab, option_source_tab)
+END_HANDLER
+
SPIN_CHANGED(spinMarginTop, option_margin_top)
END_HANDLER
Index: gtk/dialogs/gtk_source.c
===================================================================
--- gtk/dialogs/gtk_source.c (revision 7353)
+++ gtk/dialogs/gtk_source.c (working copy)
@@ -28,8 +28,10 @@
#include "gtk/gtk_gui.h"
#include "gtk/gtk_print.h"
#include "gtk/gtk_selection.h"
+#include "gtk/options.h"
#include "desktop/netsurf.h"
#include "desktop/print.h"
+#include "desktop/options.h"
#include "utils/messages.h"
#include "utils/url.h"
#include "utils/utils.h"
@@ -61,6 +63,7 @@ static gchar *glade_Location;
static struct nsgtk_source_window *nsgtk_source_list = 0;
static char source_zoomlevel = 10;
+void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw);
static void nsgtk_attach_source_menu_handlers(GladeXML *xml, gpointer g);
static gboolean nsgtk_source_delete_event(GtkWindow *window, gpointer g);
static gboolean nsgtk_source_destroy_event(GtkWindow *window, gpointer g);
@@ -103,6 +106,10 @@ MENUEVENT(source_about),
void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
{
+ if (option_source_tab) {
+ nsgtk_source_tab_init(parent, bw);
+ return;
+ }
if (bw->current_content->type == CONTENT_HTML) {
glade_Location = g_strconcat(res_dir_location, "source.glade",
NULL);
@@ -208,6 +215,35 @@ void nsgtk_source_dialog_init(GtkWindow
}
}
+void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw)
+{
+ char *ndata = 0;
+ utf8_convert_ret r = utf8_from_enc(
+ bw->current_content->source_data,
+ bw->current_content->data.html.encoding,
+ bw->current_content->source_size,
+ &ndata);
+ if (r == UTF8_CONVERT_NOMEM) {
+ warn_user("NoMemory",0);
+ return;
+ } else if (r == UTF8_CONVERT_BADENC) {
+ warn_user("EncNotRec",0);
+ return;
+ }
+ gchar *filename;
+ gint handle = g_file_open_tmp("nsgtksourceXXXXXX", &filename, NULL);
+ close (handle); /* in case it was binary mode */
+ FILE *f = fopen(filename, "w");
+ fprintf(f, "%s", ndata);
+ fclose(f);
+ struct browser_window *newbw = browser_window_create(g_strconcat(
+ "file://", filename, NULL), bw, NULL, false, true);
+ if (newbw->current_content)
+ newbw->current_content->title = g_strconcat("source of ",
+ bw->current_content->url , NULL);
+}
+
+
void nsgtk_attach_source_menu_handlers(GladeXML *xml, gpointer g)
{
struct menu_events *event = source_menu_events;
Index: gtk/res/netsurf.glade
===================================================================
--- gtk/res/netsurf.glade (revision 7353)
+++ gtk/res/netsurf.glade (working copy)
@@ -790,7 +790,7 @@
<property name="stock_id">gtk-go-back</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -802,7 +802,7 @@
<property name="icon">arrow_down_8x32.png</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -811,7 +811,7 @@
<property name="stock_id">gtk-go-forward</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -820,7 +820,7 @@
<property name="stock_id">gtk-stop</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -829,7 +829,7 @@
<property name="stock_id">gtk-refresh</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -838,7 +838,22 @@
<property name="stock_id">gtk-home</property>
</widget>
<packing>
- <property name="homogeneous">True</property>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolFav">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="FavIcon">
+ <property name="visible">True</property>
+ <property name="pixbuf">netsurf-16x16.xpm</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
</packing>
</child>
<child>
@@ -852,6 +867,10 @@
</widget>
</child>
</widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
</child>
<child>
<widget class="GtkToolItem" id="toolthrobber">
@@ -864,6 +883,10 @@
</widget>
</child>
</widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
</child>
</widget>
<packing>
@@ -956,106 +979,106 @@
<property name="column_spacing">11</property>
<property name="row_spacing">10</property>
<child>
- <widget class="GtkLabel" id="labelLoginHost">
+ <widget class="GtkEntry" id="entryLoginUser">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">moo.yoo.com</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="text" translatable="yes">sesame</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="x_options"></property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label57">
+ <widget class="GtkEntry" id="entryLoginPass">
<property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Password</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ <property name="activates_default">True</property>
+ <property name="text" translatable="yes">opensesame</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="x_options"></property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label56">
+ <widget class="GtkLabel" id="labelLoginRealm">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Username</property>
+ <property name="label" translatable="yes">my sekr3t area</property>
</widget>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label54">
+ <widget class="GtkLabel" id="label55">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Host</property>
+ <property name="label" translatable="yes">Realm</property>
</widget>
<packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label55">
+ <widget class="GtkLabel" id="label54">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Realm</property>
+ <property name="label" translatable="yes">Host</property>
</widget>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="labelLoginRealm">
+ <widget class="GtkLabel" id="label56">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">my sekr3t area</property>
+ <property name="label" translatable="yes">Username</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options"></property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="entryLoginPass">
+ <widget class="GtkLabel" id="label57">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="activates_default">True</property>
- <property name="text" translatable="yes">opensesame</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="y_options"></property>
+ <property name="x_options"></property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="entryLoginUser">
+ <widget class="GtkLabel" id="labelLoginHost">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="text" translatable="yes">sesame</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">moo.yoo.com</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
+ <property name="x_options"></property>
</packing>
</child>
</widget>
Index: gtk/res/options.glade
===================================================================
--- gtk/res/options.glade (revision 7353)
+++ gtk/res/options.glade (working copy)
@@ -1742,6 +1742,66 @@ Text only</property>
</packing>
</child>
<child>
+ <widget class="GtkFrame" id="frame9">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment9">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkHBox" id="hbox9">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkRadioButton" id="sourceButtonWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">in own window </property>
+ <property name="response_id">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="sourceButtonTab">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">in new tab</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>View Source</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
<placeholder/>
</child>
</widget>
Index: !NetSurf/Resources/en/Messages
===================================================================
--- !NetSurf/Resources/en/Messages (revision 7353)
+++ !NetSurf/Resources/en/Messages (working copy)
@@ -607,6 +607,7 @@ Done:Document done
BadRedirect:Bad redirect URL
FetchFailed:Unable to fetch document
NotCSS:Warning: stylesheet is not CSS
+NotFavIco:Favicon not supported
BadObject:Warning: bad object type
ObjError:Error loading object: %s
ParsingFail:Parsing the document failed.
Index: beos/beos_scaffolding.cpp
===================================================================
--- beos/beos_scaffolding.cpp (revision 7353)
+++ beos/beos_scaffolding.cpp (working copy)
@@ -2312,6 +2312,10 @@ void gui_window_stop_throbber(struct gui
g->top_view->UnlockLooper();
}
+void gui_window_set_icon(struct gui_window *g, struct content *icon)
+{
+}
+
#warning XXX
#if 0 /* GTK */
gboolean nsbeos_scaffolding_is_busy(nsbeos_scaffolding *scaffold)
Index: Makefile.sources
===================================================================
--- Makefile.sources (revision 7353)
+++ Makefile.sources (working copy)
@@ -8,7 +8,7 @@
S_CONTENT := content.c fetch.c fetchcache.c urldb.c \
fetchers/fetch_curl.c fetchers/fetch_data.c
S_CSS := css.c css_enum.c parser.c ruleset.c scanner.c
-S_RENDER := box.c box_construct.c box_normalise.c directory.c \
+S_RENDER := box.c box_construct.c box_normalise.c directory.c favicon.c \
form.c html.c html_redraw.c hubbub_binding.c imagemap.c \
layout.c list.c loosen.c table.c textplain.c
S_UTILS := base64.c filename.c hashtable.c locale.c messages.c talloc.c \
Index: riscos/window.c
===================================================================
--- riscos/window.c (revision 7353)
+++ riscos/window.c (working copy)
@@ -1092,6 +1092,9 @@ void gui_window_stop_throbber(struct gui
}
}
+void gui_window_set_icon(struct gui_window *g, struct content *icon)
+{
+}
/**
* Place the caret in a browser window.
Index: desktop/browser.c
===================================================================
--- desktop/browser.c (revision 7353)
+++ desktop/browser.c (working copy)
@@ -85,6 +85,7 @@ static bool browser_window_check_throbbe
static void browser_window_convert_to_download(struct browser_window *bw);
static void browser_window_start_throbber(struct browser_window *bw);
static void browser_window_stop_throbber(struct browser_window *bw);
+static void browser_window_set_icon(struct browser_window *bw);
static void browser_window_set_status(struct browser_window *bw,
const char *text);
static void browser_window_set_pointer(struct gui_window *g,
@@ -491,6 +492,7 @@ void browser_window_callback(content_msg
browser_window_update(bw, false);
browser_window_set_status(bw, c->status_message);
browser_window_stop_throbber(bw);
+ browser_window_set_icon(bw);
history_update(bw->history, c);
hotlist_visited(c);
free(bw->referer);
@@ -763,6 +765,21 @@ bool browser_window_check_throbber(struc
return false;
}
+/**
+ * when ready, set icon at top level
+ * \param bw browser_window
+ * current implementation ignores lower-levels' link rels completely
+ */
+void browser_window_set_icon(struct browser_window *bw)
+{
+ while (bw->parent)
+ bw = bw->parent;
+ if ((bw->current_content != NULL) && (bw->current_content->type == CONTENT_HTML))
+ gui_window_set_icon(bw->window,
+ bw->current_content->data.html.favicon);
+ else
+ gui_window_set_icon(bw->window, NULL);
+}
/**
* Redraw browser window, set extent to content, and update title.
Index: desktop/gui.h
===================================================================
--- desktop/gui.h (revision 7353)
+++ desktop/gui.h (working copy)
@@ -88,6 +88,7 @@ void gui_window_hide_pointer(struct gui_
void gui_window_set_url(struct gui_window *g, const char *url);
void gui_window_start_throbber(struct gui_window *g);
void gui_window_stop_throbber(struct gui_window *g);
+void gui_window_set_icon(struct gui_window *g, struct content *icon);
void gui_window_place_caret(struct gui_window *g, int x, int y, int height);
void gui_window_remove_caret(struct gui_window *g);
void gui_window_new_content(struct gui_window *g);
Index: desktop/print.c
===================================================================
--- desktop/print.c (revision 7353)
+++ desktop/print.c (working copy)
@@ -197,7 +197,7 @@ struct content *print_init(struct conten
}
/**
- * The content is resized to fit page width. In case it is to wide, it is
+ * The content is resized to fit page width. In case it is too wide, it is
* loosened.
*
* \param content The content to be printed
Index: amiga/gui.c
===================================================================
--- amiga/gui.c (revision 7353)
+++ amiga/gui.c (working copy)
@@ -2658,6 +2658,10 @@ void gui_window_stop_throbber(struct gui
g->shared->throbber_frame = 0;
}
+void gui_window_set_icon(struct gui_window *g, struct content *icon)
+{
+}
+
void ami_update_throbber(struct gui_window_2 *g,bool redraw)
{
struct IBox *bbox;
Conflicted files
Removed files
14 years, 5 months
Aborting downloads
by Chris Young
What's the correct way to abort downloads? If I just call
gui_download_window_done() will NetSurf still be trying to fetch the
file in the background?
Chris
14 years, 5 months
NetSurf quitting - news.google.ru
by Chris Young
Hello!
I've compiled libjson and the test programs for Hubbub. I can't run
the testrunner.pl script, but I've conducted some of the included
tests manually and the ones I've tried all pass.
Now onto news.google.ru which just causes NetSurf to terminate
unexpectedly without any error message.
I saved the HTML page using something other than NetSurf, and ran
csdetect over it. First problem - error:
1: Detected charset windows-1252 (2252) Source 1 Expected (0)
FAIL - mibenum == parserutils_charset_mibenum_from_name( expected, strlen(expected)) at line 133
Then I tried tokeniser and parser (both seem to have the same
output?). These appear to show the quitting phenomenom, as the final
line output is simply:
CHARACTERS: '
ie. no characters, no closing quotes, and no PASS or FAIL message
The page I was testing along with the output is at
http://homepage.ntlworld.com/cdyoung/tmp/googlerutests.zip
I'd be interested to know how this compares with the same tests on
other platforms - I expect it will continue past this point.
Other than that, I'm hoping this will give an indication of where I
can start looking to resolve this. I'll also see if I can cut the
test down to isolate it a little more.
Chris
PS I have also managed to get gdb working - but it is of little help
as it doesn't tell me what it was executing just before it quit.
14 years, 5 months
Plug-ins (was Re: NetSurf 2.0)
by Chris Young
On Sun, 26 Apr 2009 00:22:41 +0100, Rob Kendrick wrote:
> Java is a plug-in issue and is outside the scope of the NetSurf
> project.
Whilst we're on the subject of plug-ins, that just reminded me -
somebody was asking the other day about plug-ins in NetSurf. I know
the RISC OS version has the Acorn plugin protocol, but is it possible
to use a similar approach to implement the Netscape plugin API on
other platforms?
Estimate of amount of work required? I have little incentive to do
this myself until there is evidence of somebody writing/porting a
useful plug-in, but I may tackle it in the future if it's not a big
hassle rewrite type job.
This would be particulary useful for the gtk version I'd have thought,
given they have proper Java and Flash Netscape API plugins ready to
go.
(moved to the dev list as it is more relevant there)
Chris
14 years, 5 months
AGM, Saturday 25th April 2009
by Daniel Silverstone
Hello,
As per the society constitution point 15, the following nominations for
committee membership are valid for the AGM:
Chair: Michael Drake
Treasurer: John-Mark Bell
Secretary: Daniel Silverstone
I have received no other nominations and as per point 16, the time to
send them in is now over.
In order to vote on anything in the agenda in absentia, send an email to
me before the end of Friday 24th April with your vote in it. While the
society *is* quorate, we're fairly close to the wire, so I really do
need all the votes in.
The actual meeting will occur on IRC, either on #netsurf or on a channel
announced in #netsurf on Freenode. It will occur at 13:00 UK time (12:00
UTC) and I'd very much like to start it on time and get through it
quickly.
2009 NetSurf Society AGM Agenda:
1. Roll Call [dsilvers]
2. Thanking the current committee for their work [tlsa]
3. Preparation of the society bank account [jmb]
4. Voting on the next committee [dsilvers]
5. Financial report of the society [jmb]
6. Setting the date of the next AGM [tlsa]
7. Any other business [dsilvers]
8. Closing the meeting [dsilvers]
If anyone has any other business then it should be emailed to me before
the end of Friday 24th April.
According to the constitution, the following is the list of people able
to vote (by virtue of being members of the society):
Michael Drake
John-Mark Bell
Daniel Silverstone
Rob Kendrick
Andi Sidwell
Chris Young
Vincent Sanders
Bo Yang
The following people are eligible to be members but have, at this time,
not chosen to email me about it.
Adam Blokus
Adrian Lees
James Bursa
Sean Fox
John Tytgat
Mike Lester
François Revel
--
Daniel Silverstone http://www.netsurf-browser.org/
PGP mail accepted and encouraged. Key Id: 2BC8 4016 2068 7895
14 years, 5 months
Port to OS9?
by James Hill
Hi,
I'm a long time Macintosh developer and am involved in the Classic
Mac online scene. I just found about about Netsurf and was wondering
if it would be possible to port it to the old Macintosh OS9
environment and bring a modern, web standards compliant browser to
people using classic macs.
I need to know if it would be possible to compile Netsurf under the
older dev tools available for OS9 and where to start. I have
CodeWarrior 7 and the old Macintosh Developers Workshop.
Thanks,
Jay
14 years, 5 months
Final testing of ports for 2.0
by Michael Drake
Please can the people responsible for the AmigaOS, BeOS and Haiku ports
check that the stuff in /branches/release builds OK.
http://source.netsurf-browser.org/branches/release/
Note that /branches/release/netsurf/2 is for the 2.0 release.
/branches/release/netsurf/1 was for 1.x releases and is irrelevant.
If anything doesn't work, please fix it on trunk and jmb will merge it
into the release branch.
Once the release branch is tested and working everywhere, the 2.0 release
will be tagged. We will need packages for all the ports to be made from
the tag. The packages will then go on the web site.
Also, the web site changes for 2.0 are being prepared here:
staging-area [dot] netsurf-browser [dot] org
Not complete yet, but comments welcome. (Not linked as I don't want search
engines indexing it.)
Michael
--
Michael Drake (tlsa) http://www.netsurf-browser.org/
14 years, 5 months