r13122 mono - /trunk/netsurf/atari/browser.h
by netsurf@semichrome.net
Author: mono
Date: Fri Nov 4 20:47:23 2011
New Revision: 13122
URL: http://source.netsurf-browser.org?rev=13122&view=rev
Log:
Added comments.
Modified:
trunk/netsurf/atari/browser.h
Modified: trunk/netsurf/atari/browser.h
URL: http://source.netsurf-browser.org/trunk/netsurf/atari/browser.h?rev=13122...
==============================================================================
--- trunk/netsurf/atari/browser.h (original)
+++ trunk/netsurf/atari/browser.h Fri Nov 4 20:47:23 2011
@@ -21,7 +21,7 @@
/*
Each browser_window in the Atari Port is represented by an struct s_browser,
- which cosnist mainly of an WinDom COMPONENT.
+ which consist mainly of an WinDom COMPONENT.
*/
/*
@@ -61,7 +61,7 @@
/*
This struct holds information of the cursor within the browser
- viewport.
+ viewport.
*/
struct s_caret
{
@@ -83,8 +83,15 @@
};
/*
- This is the actual browser widget, containings GUI elements and
- the current state of the browser widget.
+ This is the browser content area (viewport).
+ It is redrawable and scrollable. It is based on the WinDOM
+ Component window (undocumented feature).
+
+ It's an windom component containing it's own Window controls,
+ like scrollbars, resizer, etc.
+
+ Now that the NetSurf core handles frames, the advantages of this
+ choice have probably vanished.
*/
struct s_browser
{
@@ -93,7 +100,7 @@
WINDOW * compwin;
struct browser_window * bw;
struct s_scroll_info scroll;
- struct s_browser_redrw_info redraw;
+ struct s_browser_redrw_info redraw;
struct s_caret caret;
bool attached;
};
@@ -106,8 +113,8 @@
void browser_set_content_size(struct gui_window * gw, int w, int h);
void browser_scroll( struct gui_window * gw, short MODE, int value, bool abs );
struct gui_window * browser_find_root( struct gui_window * gw );
-static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
bool browser_redraw_required( struct gui_window * gw);
+static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
/*
This queues an redraw to one of the slots.
@@ -129,10 +136,10 @@
void browser_schedule_redraw(struct gui_window * gw, short x, short y, short w, short h );
static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data);
+static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_mbutton( WINDOW * c, short buff[8], void * data);
static void __CDECL browser_evnt_arrowed( WINDOW *win, short buff[8], void * data);
-static void __CDECL browser_evnt_slider( WINDOW *win, short buff[8], void * data);
-static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data);
+static void __CDECL browser_evnt_slider( WINDOW *win, short buff[8], void * data);
static void __CDECL browser_evnt_redraw_x( WINDOW * c, short buff[8], void * data);
#endif
11 years, 6 months
r13121 mono - /trunk/netsurf/atari/browser.c
by netsurf@semichrome.net
Author: mono
Date: Fri Nov 4 20:46:41 2011
New Revision: 13121
URL: http://source.netsurf-browser.org?rev=13121&view=rev
Log:
Added comments.
Modified:
trunk/netsurf/atari/browser.c
Modified: trunk/netsurf/atari/browser.c
URL: http://source.netsurf-browser.org/trunk/netsurf/atari/browser.c?rev=13121...
==============================================================================
--- trunk/netsurf/atari/browser.c (original)
+++ trunk/netsurf/atari/browser.c Fri Nov 4 20:46:41 2011
@@ -13,7 +13,13 @@
* 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/>.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Module Description:
+ *
+ * This WinDom compo
+ *
+ *
*/
#include <limits.h>
@@ -63,11 +69,20 @@
static void __CDECL browser_evnt_wdestroy( WINDOW * c, short buff[8], void * data);
COMPONENT *comp_widget_create( APPvar *app, WINDOW *win, int size, int flex );
-
+
+/*
+The component window interface needs frame API init,
+keep track of frame API init:
+*/
static bool frameinit = true;
-/* create an browser component */
+/*
+ Create an browser component window (undcomented WinDom structure).
+ Currently, this area is the area which is used to display HTML content.
+ However, it could also contains other areas, these need to be handled within
+ "browser_get_rect" function.
+*/
struct s_browser * browser_create
(
struct gui_window * gw,
@@ -106,7 +121,9 @@
if( bnew->comp == NULL ) {
free(bnew);
return(NULL);
- }
+ }
+
+ /* Attach events to the component: */
mt_EvntDataAdd( &app, bnew->compwin, WM_XBUTTON,
browser_evnt_mbutton, (void*)gw, EV_BOT );
mt_CompEvntDataAttach( &app, bnew->comp, WM_REDRAW,
@@ -121,7 +138,9 @@
/* just stub, as an reminder: */
mt_EvntDataAttach( &app, bnew->compwin, WM_DESTROY,
browser_evnt_wdestroy, (void*)bnew );
-
+
+ /* Set the gui_window owner. */
+ /* it is an link to the netsurf window system */
mt_CompDataAttach( &app, bnew->comp, CDT_OWNER, gw );
bnew->scroll.requested.y = 0;
bnew->scroll.requested.x = 0;
@@ -139,22 +158,22 @@
assert( b->comp != NULL );
assert( b->bw != NULL );
- if( b->compwin != NULL ) {
+ if( b->compwin != NULL ) {
+ /* TODO: Only do this when it's the last browser viewport within the root win: */
COMPONENT * old = b->comp;
WINDOW * oldwin = b->compwin;
b->comp = NULL;
b->compwin = NULL;
- /* Im not sure if this is the right thing to do (after compdelete above,... */
- /* listRemove should be used when we just remove an frame... */
- /* (I encountered spurious events when not doing that...) */
- /* listRemove( (LINKABLE*) oldwin ); */
- /* listRemove( (LINKABLE*) old ); */
+ /* I'm not sure about the correct order of these 2 calls: */
WindDelete( oldwin );
mt_CompDelete(&app, old );
}
return( true );
}
-
+
+/*
+ Query the browser component for widget rectangles.
+*/
void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT * out)
{
GRECT work;
@@ -163,8 +182,13 @@
int slider_v_h = 22;
int slider_h_w = 20;
int slider_h_h = 22;
-
- WindGetGrect( gw->browser->compwin, WF_WORKXYWH, &work);
+
+ /* Query component for it's current size: */
+ WindGetGrect( gw->browser->compwin, WF_WORKXYWH, &work);
+
+ /* And extract the different widget dimensions: */
+
+ /* Redraw area of html content: */
if( type == BR_CONTENT ){
out->g_w = work.g_w;
out->g_h = work.g_h;
@@ -172,7 +196,8 @@
out->g_y = work.g_y;
return;
}
-
+
+ /* Horizontal scroller: */
LGRECT cur;
mt_CompGetLGrect(&app, gw->browser->comp, WF_WORKXYWH, &cur);
if( type == BR_HSLIDER ){
@@ -181,7 +206,8 @@
out->g_h = cur.g_h - work.g_h;
out->g_w = cur.g_w;
}
-
+
+ /* Vertical scroller: */
if( type == BR_VSLIDER ){
out->g_x = cur.g_x + work.g_w;
out->g_y = cur.g_y;
@@ -296,6 +322,10 @@
else if( dx < 0 )
browser_scroll( gw, WA_LFPAGE, abs(dx), false );
}
+
+/*
+ Mouse Button handler for browser component.
+*/
static void __CDECL browser_evnt_mbutton( WINDOW * c, short buff[8], void * data)
{
@@ -313,7 +343,8 @@
mx = evnt.mx - cwork.g_x;
my = evnt.my - cwork.g_y;
LOG(("mevent (%d) within %s at %d / %d\n", evnt.nb_click, gw->browser->bw->name, mx, my ));
-
+
+ /* Translate GEM key state to netsurf mouse modifier */
if( evnt.mkstate & (K_RSHIFT | K_LSHIFT) ){
bmstate |= BROWSER_MOUSE_MOD_1;
} else {
@@ -331,7 +362,8 @@
}
int sx = (mx + gw->browser->scroll.current.x);
int sy = (my + gw->browser->scroll.current.y);
-
+
+ /* Detect left mouse button state and compare with event state: */
graf_mkstate(&dummy, &dummy, &mbut, &dummy);
if( (mbut & 1) && (evnt.mbut & 1) ) {
if( mouse_hold_start[0] == 0 ) {
@@ -364,12 +396,16 @@
mouse_hold_start[0] = 0;
}
+ /* Right button pressed? */
if( (evnt.mbut & 2 ) ) {
context_popup( gw, evnt.mx, evnt.my );
}
}
-
+
+/*
+ Report scroll event to the browser component.
+*/
void browser_scroll( struct gui_window * gw, short mode, int value, bool abs )
{
LGRECT work;
@@ -552,7 +588,13 @@
mt_WindSlider( &app, gw->browser->compwin, HSLIDER|VSLIDER);
}
-
+/*
+ Report keypress to browser component.
+ The browser component doesn't list for keyinput by itself.
+ parameter:
+ - gui_window ( compocnent owner ).
+ - unsigned short nkc ( CFLIB normalised key code )
+*/
bool browser_input( struct gui_window * gw, unsigned short nkc )
{
LGRECT work;
@@ -859,7 +901,7 @@
caret = b->caret.requested;
caret.g_x -= gw->browser->scroll.current.x;
- caret.g_y -= gw->browser->scroll.current.y;
+ caret.g_y -= gw->browser->scroll.current.y;
clip.x0 = caret.g_x - 1;
clip.y0 = caret.g_y - 1;
clip.x1 = caret.g_x + caret.g_w + 1;
11 years, 6 months
r13120 tlsa - /trunk/libcss/src/select/select.c
by netsurf@semichrome.net
Author: tlsa
Date: Fri Nov 4 17:50:50 2011
New Revision: 13120
URL: http://source.netsurf-browser.org?rev=13120&view=rev
Log:
Selection micro optimisation.
Modified:
trunk/libcss/src/select/select.c
Modified: trunk/libcss/src/select/select.c
URL: http://source.netsurf-browser.org/trunk/libcss/src/select/select.c?rev=13...
==============================================================================
--- trunk/libcss/src/select/select.c (original)
+++ trunk/libcss/src/select/select.c Fri Nov 4 17:50:50 2011
@@ -1427,7 +1427,15 @@
css_error error;
css_pseudo_element pseudo = CSS_PSEUDO_ELEMENT_NONE;
- /* We match by default (if there are no details than the element
+ /* Skip the element selector detail, which is always first.
+ * (Named elements are handled by match_named_combinator, so the
+ * element selector detail always matches here.) */
+ if (detail->next)
+ detail++;
+ else
+ detail = NULL;
+
+ /* We match by default (if there are no details other than the element
* selector, then we must match) */
*match = true;
@@ -1437,26 +1445,20 @@
* simpler details come first (and thus the expensive match routines
* can be avoided unless absolutely necessary)? */
- do {
- /* Named elements are handled by match_named_combinator, so
- * the element selector detail always matches here. */
- if (detail->type != CSS_SELECTOR_ELEMENT) {
-
- error = match_detail(ctx, node, detail, state,
- match, &pseudo);
- if (error != CSS_OK)
- return error;
-
- /* Detail doesn't match, so reject selector chain */
- if (*match == false)
- return CSS_OK;
- }
+ while (detail != NULL) {
+ error = match_detail(ctx, node, detail, state, match, &pseudo);
+ if (error != CSS_OK)
+ return error;
+
+ /* Detail doesn't match, so reject selector chain */
+ if (*match == false)
+ return CSS_OK;
if (detail->next)
detail++;
else
detail = NULL;
- } while (detail != NULL);
+ }
/* Return the applicable pseudo element, if required */
if (pseudo_element != NULL)
11 years, 6 months
r13119 tlsa - /trunk/libcss/src/select/select.c
by netsurf@semichrome.net
Author: tlsa
Date: Fri Nov 4 16:52:24 2011
New Revision: 13119
URL: http://source.netsurf-browser.org?rev=13119&view=rev
Log:
Don't need to match CSS_SELECTOR_ELEMENT detail since it will always match.
Modified:
trunk/libcss/src/select/select.c
Modified: trunk/libcss/src/select/select.c
URL: http://source.netsurf-browser.org/trunk/libcss/src/select/select.c?rev=13...
==============================================================================
--- trunk/libcss/src/select/select.c (original)
+++ trunk/libcss/src/select/select.c Fri Nov 4 16:52:24 2011
@@ -1438,13 +1438,19 @@
* can be avoided unless absolutely necessary)? */
do {
- error = match_detail(ctx, node, detail, state, match, &pseudo);
- if (error != CSS_OK)
- return error;
-
- /* Detail doesn't match, so reject selector chain */
- if (*match == false)
- return CSS_OK;
+ /* Named elements are handled by match_named_combinator, so
+ * the element selector detail always matches here. */
+ if (detail->type != CSS_SELECTOR_ELEMENT) {
+
+ error = match_detail(ctx, node, detail, state,
+ match, &pseudo);
+ if (error != CSS_OK)
+ return error;
+
+ /* Detail doesn't match, so reject selector chain */
+ if (*match == false)
+ return CSS_OK;
+ }
if (detail->next)
detail++;
@@ -1485,8 +1491,7 @@
switch (detail->type) {
case CSS_SELECTOR_ELEMENT:
- error = state->handler->node_has_name(state->pw, node,
- &detail->qname, match);
+ /* Never any need to match this detail type. */
break;
case CSS_SELECTOR_CLASS:
error = state->handler->node_has_class(state->pw, node,
11 years, 6 months
r13118 jmb - in /trunk/libcss/src/select: select.c select.h
by netsurf@semichrome.net
Author: jmb
Date: Fri Nov 4 15:04:16 2011
New Revision: 13118
URL: http://source.netsurf-browser.org?rev=13118&view=rev
Log:
Cache rejected ancestor class/ID selectors to improve selection efficiency
Modified:
trunk/libcss/src/select/select.c
trunk/libcss/src/select/select.h
Modified: trunk/libcss/src/select/select.c
URL: http://source.netsurf-browser.org/trunk/libcss/src/select/select.c?rev=13...
==============================================================================
--- trunk/libcss/src/select/select.c (original)
+++ trunk/libcss/src/select/select.c Fri Nov 4 15:04:16 2011
@@ -94,7 +94,8 @@
css_select_state *state, void *node, void **next_node);
static css_error match_universal_combinator(css_select_ctx *ctx,
css_combinator type, const css_selector *selector,
- css_select_state *state, void *node, void **next_node);
+ css_select_state *state, void *node, bool may_optimise,
+ void **next_node);
static css_error match_details(css_select_ctx *ctx, void *node,
const css_selector_detail *detail, css_select_state *state,
bool *match, css_pseudo_element *pseudo_element);
@@ -349,6 +350,7 @@
state.media = media;
state.handler = handler;
state.pw = pw;
+ state.next_reject = state.reject_cache;
/* Allocate the result set */
state.results = ctx->alloc(NULL, sizeof(css_select_results), ctx->pw);
@@ -1128,13 +1130,52 @@
return error;
}
+static void update_reject_cache(css_select_state *state,
+ css_combinator comb, const css_selector *s)
+{
+ const css_selector_detail *detail = &s->data;
+ const css_selector_detail *next_detail = NULL;
+ reject_item *reject = state->reject_cache;
+ bool match = false;
+
+ if (detail->next)
+ next_detail = detail + 1;
+
+ if (state->next_reject >= state->reject_cache +
+ N_ELEMENTS(state->reject_cache) ||
+ comb != CSS_COMBINATOR_ANCESTOR ||
+ next_detail == NULL ||
+ (next_detail->type != CSS_SELECTOR_CLASS &&
+ next_detail->type != CSS_SELECTOR_ID))
+ return;
+
+ /* Search cache for matching entry */
+ while (reject != state->next_reject) {
+ if (reject->type == next_detail->type &&
+ lwc_string_isequal(reject->value,
+ next_detail->qname.name,
+ &match) == lwc_error_ok &&
+ match)
+ break;
+
+ reject++;
+ }
+
+ /* None found: insert */
+ if (reject == state->next_reject) {
+ state->next_reject->type = next_detail->type;
+ state->next_reject->value = next_detail->qname.name;
+ state->next_reject++;
+ }
+}
+
css_error match_selector_chain(css_select_ctx *ctx,
const css_selector *selector, css_select_state *state)
{
const css_selector *s = selector;
void *node = state->node;
const css_selector_detail *detail = &s->data;
- bool match = false;
+ bool match = false, may_optimise = true;
css_pseudo_element pseudo;
css_error error;
@@ -1168,6 +1209,10 @@
s->combinator->data.qname.name !=
ctx->universal) {
/* Named combinator */
+ may_optimise &=
+ (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
+ s->data.comb == CSS_COMBINATOR_PARENT);
+
error = match_named_combinator(ctx, s->data.comb,
s->combinator, state, node, &next_node);
if (error != CSS_OK)
@@ -1176,18 +1221,27 @@
/* No match for combinator, so reject selector chain */
if (next_node == NULL)
return CSS_OK;
- } else if (s->data.comb != CSS_COMBINATOR_NONE &&
- s->combinator->data.qname.name ==
- ctx->universal) {
+ } else if (s->data.comb != CSS_COMBINATOR_NONE) {
/* Universal combinator */
+ may_optimise &=
+ (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
+ s->data.comb == CSS_COMBINATOR_PARENT);
+
error = match_universal_combinator(ctx, s->data.comb,
- s->combinator, state, node, &next_node);
+ s->combinator, state, node,
+ may_optimise, &next_node);
if (error != CSS_OK)
return error;
/* No match for combinator, so reject selector chain */
- if (next_node == NULL)
+ if (next_node == NULL) {
+ if (may_optimise && s == selector) {
+ update_reject_cache(state, s->data.comb,
+ s->combinator);
+ }
+
return CSS_OK;
+ }
}
/* Details matched, so progress to combining selector */
@@ -1285,11 +1339,40 @@
css_error match_universal_combinator(css_select_ctx *ctx, css_combinator type,
const css_selector *selector, css_select_state *state,
- void *node, void **next_node)
+ void *node, bool may_optimise, void **next_node)
{
const css_selector_detail *detail = &selector->data;
+ const css_selector_detail *next_detail = NULL;
void *n = node;
css_error error;
+
+ if (detail->next)
+ next_detail = detail + 1;
+
+ /* Consult reject cache first */
+ if (may_optimise && (type == CSS_COMBINATOR_ANCESTOR ||
+ type == CSS_COMBINATOR_PARENT) &&
+ next_detail != NULL &&
+ (next_detail->type == CSS_SELECTOR_CLASS ||
+ next_detail->type == CSS_SELECTOR_ID)) {
+ reject_item *reject = state->reject_cache;
+ bool match = false;
+
+ while (reject != state->next_reject) {
+ /* Perform pessimistic matching (may hurt quirks) */
+ if (reject->type == next_detail->type &&
+ lwc_string_isequal(reject->value,
+ next_detail->qname.name,
+ &match) == lwc_error_ok &&
+ match) {
+ /* Found it: can't match */
+ *next_node = NULL;
+ return CSS_OK;
+ }
+
+ reject++;
+ }
+ }
do {
bool match = false;
Modified: trunk/libcss/src/select/select.h
URL: http://source.netsurf-browser.org/trunk/libcss/src/select/select.h?rev=13...
==============================================================================
--- trunk/libcss/src/select/select.h (original)
+++ trunk/libcss/src/select/select.h Fri Nov 4 15:04:16 2011
@@ -14,6 +14,14 @@
#include <libcss/select.h>
#include "stylesheet.h"
+
+/**
+ * Item in the reject cache (only class and id types are valid)
+ */
+typedef struct reject_item {
+ lwc_string *value;
+ css_selector_type type;
+} reject_item;
typedef struct prop_state {
uint32_t specificity; /* Specificity of property in result */
@@ -47,6 +55,9 @@
lwc_string **classes; /* Node classes, if any */
uint32_t n_classes; /* Number of classes */
+ reject_item reject_cache[128]; /* Reject cache */
+ reject_item *next_reject; /* Next free slot in reject cache */
+
prop_state props[CSS_N_PROPERTIES][CSS_PSEUDO_ELEMENT_COUNT];
} css_select_state;
11 years, 6 months
r13117 tlsa - in /branches/tlsa/libcss-selection-speedup-and-stats/src: select/select.c select/select.h stylesheet.c stylesheet.h
by netsurf@semichrome.net
Author: tlsa
Date: Fri Nov 4 12:47:06 2011
New Revision: 13117
URL: http://source.netsurf-browser.org?rev=13117&view=rev
Log:
Add the stats generation and rejection cache changes.
Modified:
branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.c
branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.h
branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.c
branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.h
Modified: branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.c
URL: http://source.netsurf-browser.org/branches/tlsa/libcss-selection-speedup-...
==============================================================================
--- branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.c (original)
+++ branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.c Fri Nov 4 12:47:06 2011
@@ -94,7 +94,8 @@
css_select_state *state, void *node, void **next_node);
static css_error match_universal_combinator(css_select_ctx *ctx,
css_combinator type, const css_selector *selector,
- css_select_state *state, void *node, void **next_node);
+ css_select_state *state, void *node, bool may_optimise,
+ void **next_node);
static css_error match_details(css_select_ctx *ctx, void *node,
const css_selector_detail *detail, css_select_state *state,
bool *match, css_pseudo_element *pseudo_element);
@@ -349,6 +350,7 @@
state.media = media;
state.handler = handler;
state.pw = pw;
+ state.next_reject = state.reject_cache;
/* Allocate the result set */
state.results = ctx->alloc(NULL, sizeof(css_select_results), ctx->pw);
@@ -1016,6 +1018,13 @@
css_selector_hash_iterator univ_iterator;
css_error error;
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)sheet;
+ sheet2->selection_stats.total_selection_calls++;
+}
+#endif
+
/* Find hash chain that applies to current node */
error = css__selector_hash_find(sheet->selectors,
&state->element, &node_iterator,
@@ -1119,7 +1128,7 @@
if (error != CSS_OK)
goto cleanup;
}
-
+
error = CSS_OK;
cleanup:
if (class_selectors != NULL)
@@ -1128,20 +1137,71 @@
return error;
}
+static void update_reject_cache(css_select_state *state,
+ css_combinator comb, const css_selector *s)
+{
+ const css_selector_detail *detail = &s->data;
+ const css_selector_detail *next_detail = NULL;
+ reject_item *reject = state->reject_cache;
+ bool match;
+
+ if (detail->next)
+ next_detail = detail + 1;
+
+ if (state->next_reject >= state->reject_cache +
+ N_ELEMENTS(state->reject_cache) ||
+ comb != CSS_COMBINATOR_ANCESTOR ||
+ next_detail == NULL ||
+ (next_detail->type != CSS_SELECTOR_CLASS &&
+ next_detail->type != CSS_SELECTOR_ID))
+ return;
+
+ /* Search cache for matching entry */
+ while (reject != state->next_reject) {
+ if (reject->type == next_detail->type &&
+ lwc_string_isequal(reject->value,
+ next_detail->value.string,
+ &match) == lwc_error_ok &&
+ match)
+ break;
+
+ reject++;
+ }
+
+ /* None found: insert */
+ if (reject == state->next_reject) {
+ state->next_reject->type = next_detail->type;
+ state->next_reject->value = next_detail->value.string;
+ state->next_reject++;
+ }
+}
+
css_error match_selector_chain(css_select_ctx *ctx,
const css_selector *selector, css_select_state *state)
{
const css_selector *s = selector;
void *node = state->node;
const css_selector_detail *detail = &s->data;
- bool match = false;
+ bool match = false, may_optimise = true;
css_pseudo_element pseudo;
css_error error;
+
+#ifdef CSS__GENERATE_STATS
+ int selector_count = 0;
+#endif
+
#ifdef DEBUG_CHAIN_MATCHING
fprintf(stderr, "matching: ");
dump_chain(selector);
fprintf(stderr, "\n");
+#endif
+
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_rules_examined++;
+}
#endif
/* Match the details of the first selector in the chain.
@@ -1156,38 +1216,77 @@
return error;
/* Details don't match, so reject selector chain */
- if (match == false)
+ if (match == false) {
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_reject_after[0]++;
+}
+#endif
return CSS_OK;
+ }
/* Iterate up the selector chain, matching combinators */
do {
void *next_node = NULL;
+
+#ifdef CSS__GENERATE_STATS
+ selector_count++;
+#endif
/* Consider any combinator on this selector */
if (s->data.comb != CSS_COMBINATOR_NONE &&
s->combinator->data.qname.name !=
ctx->universal) {
/* Named combinator */
+ may_optimise &=
+ (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
+ s->data.comb == CSS_COMBINATOR_PARENT);
+
error = match_named_combinator(ctx, s->data.comb,
s->combinator, state, node, &next_node);
if (error != CSS_OK)
return error;
/* No match for combinator, so reject selector chain */
- if (next_node == NULL)
+ if (next_node == NULL) {
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 =
+ (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_reject_after[
+ selector_count > 10 ? 10 : selector_count]++;
+}
+#endif
return CSS_OK;
- } else if (s->data.comb != CSS_COMBINATOR_NONE &&
- s->combinator->data.qname.name ==
- ctx->universal) {
+ }
+ } else if (s->data.comb != CSS_COMBINATOR_NONE) {
/* Universal combinator */
+ may_optimise &=
+ (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
+ s->data.comb == CSS_COMBINATOR_PARENT);
+
error = match_universal_combinator(ctx, s->data.comb,
- s->combinator, state, node, &next_node);
+ s->combinator, state, node,
+ may_optimise, &next_node);
if (error != CSS_OK)
return error;
/* No match for combinator, so reject selector chain */
- if (next_node == NULL)
+ if (next_node == NULL) {
+ if (s == selector)
+ update_reject_cache(state, s->data.comb,
+ s->combinator);
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 =
+ (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_reject_after[
+ selector_count > 10 ? 10 : selector_count]++;
+}
+#endif
return CSS_OK;
+ }
}
/* Details matched, so progress to combining selector */
@@ -1197,6 +1296,13 @@
/* If we got here, then the entire selector chain matched, so cascade */
state->current_specificity = selector->specificity;
+
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_rules_matched++;
+}
+#endif
/* No bytecode if rule body is empty or wholly invalid */
if (((css_rule_selector *) selector->rule)->style == NULL)
@@ -1225,8 +1331,41 @@
void *n = node;
css_error error;
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_named_combinators++;
+}
+#endif
+
do {
bool match = false;
+
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ switch (type) {
+ case CSS_COMBINATOR_ANCESTOR:
+ sheet2->selection_stats.
+ total_named_combinators_type[0]++;
+ break;
+ case CSS_COMBINATOR_PARENT:
+ sheet2->selection_stats.
+ total_named_combinators_type[1]++;
+ break;
+ case CSS_COMBINATOR_SIBLING:
+ sheet2->selection_stats.
+ total_named_combinators_type[2]++;
+ break;
+ case CSS_COMBINATOR_GENERIC_SIBLING:
+ sheet2->selection_stats.
+ total_named_combinators_type[3]++;
+ break;
+ case CSS_COMBINATOR_NONE:
+ break;
+ }
+}
+#endif
/* Find candidate node */
switch (type) {
@@ -1285,14 +1424,84 @@
css_error match_universal_combinator(css_select_ctx *ctx, css_combinator type,
const css_selector *selector, css_select_state *state,
- void *node, void **next_node)
+ void *node, bool may_optimise, void **next_node)
{
const css_selector_detail *detail = &selector->data;
+ const css_selector_detail *next_detail = NULL;
void *n = node;
css_error error;
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_universal_combinators++;
+}
+#endif
+
+ if (detail->next)
+ next_detail = detail + 1;
+
+ /* Consult reject cache first */
+ if (may_optimise && (type == CSS_COMBINATOR_ANCESTOR ||
+ type == CSS_COMBINATOR_PARENT) &&
+ next_detail != NULL &&
+ (next_detail->type == CSS_SELECTOR_CLASS ||
+ next_detail->type == CSS_SELECTOR_ID)) {
+ reject_item *reject = state->reject_cache;
+ bool match = false;
+
+ while (reject != state->next_reject) {
+ /* Perform pessimistic matching (may hurt quirks) */
+ if (reject->type == next_detail->type &&
+ lwc_string_isequal(reject->value,
+ next_detail->value.string,
+ &match) == lwc_error_ok &&
+ match) {
+ /* Found it: can't match */
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 =
+ (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.
+ total_rules_rejected_by_cache++;
+}
+#endif
+ *next_node = NULL;
+ return CSS_OK;
+ }
+
+ reject++;
+ }
+ }
+
do {
bool match = false;
+
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ switch (type) {
+ case CSS_COMBINATOR_ANCESTOR:
+ sheet2->selection_stats.
+ total_universal_combinators_type[0]++;
+ break;
+ case CSS_COMBINATOR_PARENT:
+ sheet2->selection_stats.
+ total_universal_combinators_type[1]++;
+ break;
+ case CSS_COMBINATOR_SIBLING:
+ sheet2->selection_stats.
+ total_universal_combinators_type[2]++;
+ break;
+ case CSS_COMBINATOR_GENERIC_SIBLING:
+ sheet2->selection_stats.
+ total_universal_combinators_type[3]++;
+ break;
+ case CSS_COMBINATOR_NONE:
+ break;
+ }
+}
+#endif
/* Find candidate node */
switch (type) {
@@ -1399,6 +1608,53 @@
{
bool is_root = false;
css_error error = CSS_OK;
+
+
+#ifdef CSS__GENERATE_STATS
+{
+ css_stylesheet *sheet2 = (css_stylesheet *)state->sheet;
+ sheet2->selection_stats.total_details++;
+
+ switch (detail->type) {
+ case CSS_SELECTOR_ELEMENT:
+ sheet2->selection_stats.total_details_type[0]++;
+ break;
+ case CSS_SELECTOR_CLASS:
+ sheet2->selection_stats.total_details_type[1]++;
+ break;
+ case CSS_SELECTOR_ID:
+ sheet2->selection_stats.total_details_type[2]++;
+ break;
+ case CSS_SELECTOR_PSEUDO_CLASS:
+ sheet2->selection_stats.total_details_type[3]++;
+ break;
+ case CSS_SELECTOR_PSEUDO_ELEMENT:
+ sheet2->selection_stats.total_details_type[4]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE:
+ sheet2->selection_stats.total_details_type[5]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_EQUAL:
+ sheet2->selection_stats.total_details_type[6]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_DASHMATCH:
+ sheet2->selection_stats.total_details_type[7]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_INCLUDES:
+ sheet2->selection_stats.total_details_type[8]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_PREFIX:
+ sheet2->selection_stats.total_details_type[9]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_SUFFIX:
+ sheet2->selection_stats.total_details_type[10]++;
+ break;
+ case CSS_SELECTOR_ATTRIBUTE_SUBSTRING:
+ sheet2->selection_stats.total_details_type[11]++;
+ break;
+ }
+}
+#endif
switch (detail->type) {
case CSS_SELECTOR_ELEMENT:
Modified: branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.h
URL: http://source.netsurf-browser.org/branches/tlsa/libcss-selection-speedup-...
==============================================================================
--- branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.h (original)
+++ branches/tlsa/libcss-selection-speedup-and-stats/src/select/select.h Fri Nov 4 12:47:06 2011
@@ -14,6 +14,14 @@
#include <libcss/select.h>
#include "stylesheet.h"
+
+/**
+ * Item in the reject cache (only class and id types are valid)
+ */
+typedef struct reject_item {
+ lwc_string *value;
+ css_selector_type type;
+} reject_item;
typedef struct prop_state {
uint32_t specificity; /* Specificity of property in result */
@@ -47,6 +55,9 @@
lwc_string **classes; /* Node classes, if any */
uint32_t n_classes; /* Number of classes */
+ reject_item reject_cache[128]; /* Reject cache */
+ reject_item *next_reject; /* Next free slot in reject cache */
+
prop_state props[CSS_N_PROPERTIES][CSS_PSEUDO_ELEMENT_COUNT];
} css_select_state;
Modified: branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.c
URL: http://source.netsurf-browser.org/branches/tlsa/libcss-selection-speedup-...
==============================================================================
--- branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.c (original)
+++ branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.c Fri Nov 4 12:47:06 2011
@@ -248,6 +248,31 @@
if (sheet->title != NULL)
sheet->size += strlen(sheet->title);
+#ifdef CSS__GENERATE_STATS
+{
+ int i;
+ sheet->selection_stats.total_selection_calls = 0;
+ sheet->selection_stats.total_rules_examined = 0;
+ sheet->selection_stats.total_rules_matched = 0;
+ sheet->selection_stats.total_rules_rejected_by_cache = 0;
+
+ for (i = 0; i < 11; i++)
+ sheet->selection_stats.total_reject_after[i] = 0;
+
+ sheet->selection_stats.total_named_combinators = 0;
+ for (i = 0; i < 4; i++)
+ sheet->selection_stats.total_named_combinators_type[i] = 0;
+
+ sheet->selection_stats.total_universal_combinators = 0;
+ for (i = 0; i < 4; i++)
+ sheet->selection_stats.total_universal_combinators_type[i] = 0;
+
+ sheet->selection_stats.total_details = 0;
+ for (i = 0; i < 12; i++)
+ sheet->selection_stats.total_details_type[i] = 0;
+}
+#endif
+
*stylesheet = sheet;
return CSS_OK;
@@ -306,6 +331,141 @@
sheet->alloc(sheet->string_vector, 0, sheet->pw);
css__propstrings_unref();
+
+#ifdef CSS__GENERATE_STATS
+{
+ int i;
+
+ printf("===========================================================\n"
+ "\tStylesheet Selection Stats\n"
+ "\t(sheet %p, with %u rules)\n",
+ (void *)sheet, (unsigned int)sheet->rule_count);
+ printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
+
+ printf("\tTotal selection calls: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_selection_calls);
+ printf("\tTotal rules evaluated during selection: %u\n"
+ "\t-->\tAverage rules per call: %.3f\n\n",
+ (unsigned int)sheet->selection_stats.
+ total_rules_examined,
+ (double)sheet->selection_stats.
+ total_rules_examined /
+ (double)sheet->selection_stats.
+ total_selection_calls);
+
+ printf("\tTotal evaluated rules which matched: %u\n"
+ "\t-->\t%.3f%% matched, %.3f%% dismissed\n\n",
+ (unsigned int)sheet->selection_stats.
+ total_rules_matched,
+ ((double)sheet->selection_stats.
+ total_rules_matched * (double)100) /
+ (double)sheet->selection_stats.
+ total_rules_examined,
+ (((double)sheet->selection_stats.
+ total_rules_examined -
+ (double)sheet->selection_stats.
+ total_rules_matched) * (double)100) /
+ (double)sheet->selection_stats.
+ total_rules_examined);
+
+ printf("\tProportion of dismissed rules rejected by cache:\n"
+ "\t-->\t%.3f%%\n\n",
+ (double)sheet->selection_stats.
+ total_rules_rejected_by_cache *
+ (double)100 /
+ ((double)((unsigned int)sheet->selection_stats.
+ total_rules_examined -
+ (unsigned int)sheet->selection_stats.
+ total_rules_matched)));
+
+ printf("\tBreakdown of dismissed rules by number of simple\n"
+ "\tselectors evaluated:\n");
+ for (i = 0; i < 10; i++) {
+ printf("\t%3i | %u\n", i + 1,
+ (unsigned int)sheet->selection_stats.
+ total_reject_after[i]);
+ }
+ printf("\t 11+ | %u\n\n",
+ (unsigned int)sheet->selection_stats.
+ total_reject_after[10]);
+
+ printf("\tBreakdown of evaluated combinators by type:\n");
+ printf("\tNamed: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_named_combinators);
+ printf("\t-->\t Ancestor: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_named_combinators_type[0]);
+ printf("\t-->\t Parent: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_named_combinators_type[1]);
+ printf("\t-->\t Sibling: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_named_combinators_type[2]);
+ printf("\t-->\tGeneric sibling: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_named_combinators_type[3]);
+ printf("\tUniversal: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_universal_combinators);
+ printf("\t-->\t Ancestor: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_universal_combinators_type[0]);
+ printf("\t-->\t Parent: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_universal_combinators_type[1]);
+ printf("\t-->\t Sibling: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_universal_combinators_type[2]);
+ printf("\t-->\tGeneric sibling: %u\n\n",
+ (unsigned int)sheet->selection_stats.
+ total_universal_combinators_type[3]);
+
+ printf("\tTotal details evaluated: %u\n\n",
+ (unsigned int)sheet->selection_stats.
+ total_details);
+ printf("\tBreakdown of evaluated details by type:\n");
+ printf("\t Element: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[0]);
+ printf("\t Class: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[1]);
+ printf("\t Id: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[2]);
+ printf("\t Pseudo class: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[3]);
+ printf("\t Pseudo element: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[4]);
+ printf("\t Attribute: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[5]);
+ printf("\t Attribute equal: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[6]);
+ printf("\tAttribute dashmatch: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[7]);
+ printf("\t Attribute includes: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[8]);
+ printf("\t Attribute prefix: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[9]);
+ printf("\t Attribute suffix: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[10]);
+ printf("\tAttribute substring: %u\n",
+ (unsigned int)sheet->selection_stats.
+ total_details_type[11]);
+
+ printf("===========================================================\n");
+}
+#endif
sheet->alloc(sheet, 0, sheet->pw);
Modified: branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.h
URL: http://source.netsurf-browser.org/branches/tlsa/libcss-selection-speedup-...
==============================================================================
--- branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.h (original)
+++ branches/tlsa/libcss-selection-speedup-and-stats/src/stylesheet.h Fri Nov 4 12:47:06 2011
@@ -12,6 +12,10 @@
#include <stdio.h>
#include <libwapcaplet/libwapcaplet.h>
+
+/** Define to generate selection stats, printed on stylesheet destruction */
+#undef CSS__GENERATE_STATS
+#define CSS__GENERATE_STATS
#include <libcss/errors.h>
#include <libcss/functypes.h>
@@ -214,6 +218,23 @@
* length in entries */
uint32_t string_vector_c; /**< The number of string
* vector entries used */
+
+#ifdef CSS__GENERATE_STATS
+ struct css_stats {
+ uint64_t total_selection_calls;
+ uint64_t total_rules_examined;
+ uint64_t total_rules_matched;
+ uint64_t total_rules_rejected_by_cache;
+ uint64_t total_reject_after[11];
+ uint64_t total_rejected_by_cache;
+ uint64_t total_named_combinators;
+ uint64_t total_named_combinators_type[4];
+ uint64_t total_universal_combinators;
+ uint64_t total_universal_combinators_type[4];
+ uint64_t total_details;
+ uint64_t total_details_type[12];
+ } selection_stats; /**< Selection stats */
+#endif
};
css_error css__stylesheet_style_create(css_stylesheet *sheet,
11 years, 6 months
r13115 tlsa - /trunk/netsurf/test/
by netsurf@semichrome.net
Author: tlsa
Date: Thu Nov 3 07:20:55 2011
New Revision: 13115
URL: http://source.netsurf-browser.org?rev=13115&view=rev
Log:
Ignore test binaries.
Modified:
trunk/netsurf/test/ (props changed)
Propchange: trunk/netsurf/test/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Nov 3 07:20:55 2011
@@ -1,0 +1,4 @@
+nsurl
+urldbtest
+llcache
+
11 years, 6 months
r13114 tlsa - /trunk/netsurf/test/nsurl.c
by netsurf@semichrome.net
Author: tlsa
Date: Thu Nov 3 07:16:01 2011
New Revision: 13114
URL: http://source.netsurf-browser.org?rev=13114&view=rev
Log:
Add some tests.
Modified:
trunk/netsurf/test/nsurl.c
Modified: trunk/netsurf/test/nsurl.c
URL: http://source.netsurf-browser.org/trunk/netsurf/test/nsurl.c?rev=13114&r1...
==============================================================================
--- trunk/netsurf/test/nsurl.c (original)
+++ trunk/netsurf/test/nsurl.c Thu Nov 3 07:16:01 2011
@@ -53,6 +53,14 @@
"http://u@www.ns-b.org/hello" },
{ "http://u:p@www.ns-b.org:/hello",
"http://u:p@www.ns-b.org/hello" },
+
+ { "http:a/", "http://a/" },
+ { "http:/a/", "http://a/" },
+ { "http://u@a", "http://u@a/" },
+ { "http://@a", "http://a/" },
+
+ { "mailto:u@a", "mailto:u@a" },
+ { "mailto:@a", "mailto:a" },
{ NULL, NULL }
};
11 years, 6 months
r13113 tlsa - /trunk/netsurf/utils/nsurl.c
by netsurf@semichrome.net
Author: tlsa
Date: Thu Nov 3 07:15:32 2011
New Revision: 13113
URL: http://source.netsurf-browser.org?rev=13113&view=rev
Log:
Fix handling of bad mailto: urls.
Modified:
trunk/netsurf/utils/nsurl.c
Modified: trunk/netsurf/utils/nsurl.c
URL: http://source.netsurf-browser.org/trunk/netsurf/utils/nsurl.c?rev=13113&r...
==============================================================================
--- trunk/netsurf/utils/nsurl.c (original)
+++ trunk/netsurf/utils/nsurl.c Thu Nov 3 07:15:32 2011
@@ -119,6 +119,17 @@
return no_escape[c];
}
+
+/** nsurl scheme type */
+enum scheme_type {
+ NSURL_SCHEME_OTHER,
+ NSURL_SCHEME_HTTP,
+ NSURL_SCHEME_HTTPS,
+ NSURL_SCHEME_FTP,
+ NSURL_SCHEME_MAILTO
+};
+
+
/** nsurl components */
struct nsurl_components {
lwc_string *scheme;
@@ -129,7 +140,10 @@
lwc_string *path;
lwc_string *query;
lwc_string *fragment;
+
+ enum scheme_type scheme_type;
};
+
/**
* NetSurf URL object
@@ -161,6 +175,8 @@
size_t fragment;
size_t end; /** end of URL */
+
+ enum scheme_type scheme_type;
};
@@ -233,7 +249,8 @@
bool trailing_whitespace = false;
/* Initialise marker set */
- struct url_markers marker = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ struct url_markers marker = { 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, NSURL_SCHEME_OTHER };
/* Skip any leading whitespace in url_s */
while (isspace(*pos))
@@ -267,7 +284,8 @@
off = marker.scheme_end - marker.start;
- /* Detect http(s) for scheme specifc normalisation */
+ /* Detect http(s) and mailto for scheme specifc
+ * normalisation */
if (off == SLEN("http") &&
(((*(pos - off + 0) == 'h') ||
(*(pos - off + 0) == 'H')) &&
@@ -277,6 +295,7 @@
(*(pos - off + 2) == 'T')) &&
((*(pos - off + 3) == 'p') ||
(*(pos - off + 3) == 'P')))) {
+ marker.scheme_type = NSURL_SCHEME_HTTP;
is_http = true;
} else if (off == SLEN("https") &&
(((*(pos - off + 0) == 'h') ||
@@ -287,9 +306,32 @@
(*(pos - off + 2) == 'T')) &&
((*(pos - off + 3) == 'p') ||
(*(pos - off + 3) == 'P')) &&
- ((*(pos - off + 3) == 's') ||
- (*(pos - off + 3) == 'S')))) {
+ ((*(pos - off + 4) == 's') ||
+ (*(pos - off + 4) == 'S')))) {
+ marker.scheme_type = NSURL_SCHEME_HTTPS;
is_http = true;
+ } else if (off == SLEN("https") &&
+ (((*(pos - off + 0) == 'f') ||
+ (*(pos - off + 0) == 'F')) &&
+ ((*(pos - off + 1) == 't') ||
+ (*(pos - off + 1) == 'T')) &&
+ ((*(pos - off + 2) == 'p') ||
+ (*(pos - off + 2) == 'P')))) {
+ marker.scheme_type = NSURL_SCHEME_FTP;
+ } else if (off == SLEN("mailto") &&
+ (((*(pos - off + 0) == 'm') ||
+ (*(pos - off + 0) == 'M')) &&
+ ((*(pos - off + 1) == 'a') ||
+ (*(pos - off + 1) == 'A')) &&
+ ((*(pos - off + 2) == 'i') ||
+ (*(pos - off + 2) == 'I')) &&
+ ((*(pos - off + 3) == 'l') ||
+ (*(pos - off + 3) == 'L')) &&
+ ((*(pos - off + 4) == 't') ||
+ (*(pos - off + 4) == 'T')) &&
+ ((*(pos - off + 5) == 'o') ||
+ (*(pos - off + 5) == 'O')))) {
+ marker.scheme_type = NSURL_SCHEME_MAILTO;
}
/* Skip over colon */
@@ -304,6 +346,7 @@
/* Not found a scheme */
if (joining == false) {
/* Assuming no scheme == http */
+ marker.scheme_type = NSURL_SCHEME_HTTP;
is_http = true;
}
}
@@ -316,11 +359,13 @@
* We are more relaxed in the case of http:
* a. when joining, one or more slashes indicates start of authority
* b. when not joining, we assume authority if no scheme was present
+ * and in the case of mailto: when we assume there is an authority.
*/
if ((*pos == '/' && *(pos + 1) == '/') ||
(is_http && ((joining && *pos == '/') ||
(joining == false &&
- marker.scheme_end != marker.start)))) {
+ marker.scheme_end != marker.start))) ||
+ marker.scheme_type == NSURL_SCHEME_MAILTO) {
/* Skip over leading slashes */
if (*pos == '/') {
@@ -853,13 +898,13 @@
1 : 0;
sec_start = norm_start + colon - pegs->at +
skip;
- if (url->scheme != NULL && length -
+ if (url->scheme != NULL &&
+ url->scheme_type ==
+ NSURL_SCHEME_HTTP &&
+ length -
(colon - pegs->at + skip) == 2 &&
*sec_start == '8' &&
- *(sec_start + 1) == '0' &&
- strncmp(lwc_string_data(
- url->scheme), "http",
- SLEN("http")) == 0) {
+ *(sec_start + 1) == '0') {
/* Scheme is http, and port is default
* (80) */
flags |= NSURL_F_NO_PORT;
@@ -902,7 +947,8 @@
&url->path) != lwc_error_ok) {
return NSERROR_NOMEM;
}
- } else if (url->host != NULL) {
+ } else if (url->host != NULL &&
+ url->scheme_type != NSURL_SCHEME_MAILTO) {
/* Set empty path to "/", if there's a host */
if (lwc_intern_string("/", SLEN("/"),
&url->path) != lwc_error_ok) {
@@ -1188,6 +1234,9 @@
buff = malloc(length * 3 + 1);
if (buff == NULL)
return NSERROR_NOMEM;
+
+ /* Set scheme type */
+ c.scheme_type = m.scheme_type;
/* Build NetSurf URL object from sections */
e |= nsurl__create_from_section(url_s, URL_SCHEME, &m, buff, &c);
@@ -1598,11 +1647,16 @@
/* Form joined URL from base or rel components, as appropriate */
- if (joined_parts & NSURL_F_BASE_SCHEME)
+ if (joined_parts & NSURL_F_BASE_SCHEME) {
+ c.scheme_type = base->components.scheme_type;
+
c.scheme = nsurl__component_copy(base->components.scheme);
- else
+ } else {
+ c.scheme_type = m.scheme_type;
+
error |= nsurl__create_from_section(rel, URL_SCHEME, &m,
buff, &c);
+ }
if (joined_parts & NSURL_F_BASE_AUTHORITY) {
c.username = nsurl__component_copy(base->components.username);
@@ -1755,6 +1809,8 @@
(*no_frag)->components.query =
nsurl__component_copy(url->components.query);
(*no_frag)->components.fragment = NULL;
+
+ (*no_frag)->components.scheme_type = url->components.scheme_type;
(*no_frag)->length = length;
@@ -1827,6 +1883,8 @@
(*new_url)->components.fragment =
lwc_string_ref(frag);
+ (*new_url)->components.scheme_type = url->components.scheme_type;
+
/* Give the URL a reference */
(*new_url)->count = 1;
11 years, 6 months