NetSurf
css.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <string.h>
20#include <assert.h>
21#include <libwapcaplet/libwapcaplet.h>
22#include <dom/dom.h>
23
24#include "utils/errors.h"
25#include "utils/corestrings.h"
26#include "utils/utils.h"
27#include "utils/http.h"
28#include "utils/log.h"
29#include "utils/messages.h"
32#include "content/fetch.h"
33#include "content/hlcache.h"
35
36#include "css/css.h"
37#include "css/hints.h"
38#include "css/internal.h"
39
40/* Define to trace import fetches */
41#undef NSCSS_IMPORT_TRACE
42
43/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
44css_fixed nscss_screen_dpi = F_90;
45
46struct content_css_data;
47
48/**
49 * Type of callback called when a CSS object has finished
50 *
51 * \param css CSS object that has completed
52 * \param pw Client-specific data
53 */
54typedef void (*nscss_done_callback)(struct content_css_data *css, void *pw);
55
56/**
57 * CSS content data
58 */
60{
61 css_stylesheet *sheet; /**< Stylesheet object */
62 char *charset; /**< Character set of stylesheet */
63 struct nscss_import *imports; /**< Array of imported sheets */
64 uint32_t import_count; /**< Number of sheets imported */
65 uint32_t next_to_register; /**< Index of next import to register */
66 nscss_done_callback done; /**< Completion callback */
67 void *pw; /**< Client data */
68};
69
70/**
71 * CSS content data
72 */
73typedef struct nscss_content
74{
75 struct content base; /**< Underlying content object */
76
77 struct content_css_data data; /**< CSS data */
79
80/**
81 * Context for import fetches
82 */
83typedef struct {
84 struct content_css_data *css; /**< Object containing import */
85 uint32_t index; /**< Index into parent sheet's
86 * imports array */
88
89static bool nscss_convert(struct content *c);
90static void nscss_destroy(struct content *c);
91static nserror nscss_clone(const struct content *old, struct content **newc);
92static bool nscss_matches_quirks(const struct content *c, bool quirks);
94
96 const char *url, const char *charset, bool quirks,
98static css_error nscss_process_css_data(struct content_css_data *c, const char *data,
99 unsigned int size);
100static css_error nscss_convert_css_data(struct content_css_data *c);
101static void nscss_destroy_css_data(struct content_css_data *c);
102
103static void nscss_content_done(struct content_css_data *css, void *pw);
104static css_error nscss_handle_import(void *pw, css_stylesheet *parent,
105 lwc_string *url);
106static nserror nscss_import(hlcache_handle *handle,
107 const hlcache_event *event, void *pw);
108static css_error nscss_import_complete(nscss_import_ctx *ctx);
109
110static css_error nscss_register_imports(struct content_css_data *c);
111static css_error nscss_register_import(struct content_css_data *c,
112 const hlcache_handle *import);
113
114
115static css_stylesheet *blank_import;
116
117
118/**
119 * Initialise a CSS content
120 *
121 * \param handler content handler
122 * \param imime_type mime-type
123 * \param params Content-Type parameters
124 * \param llcache handle to content
125 * \param fallback_charset The character set to fallback to.
126 * \param quirks allow quirks
127 * \param c Content to initialise
128 * \return NSERROR_OK or error cod eon faliure
129 */
130static nserror
132 lwc_string *imime_type,
133 const http_parameter *params,
135 const char *fallback_charset,
136 bool quirks,
137 struct content **c)
138{
140 const char *charset = NULL;
141 const char *xnsbase = NULL;
142 lwc_string *charset_value = NULL;
143 nserror error;
144
145 result = calloc(1, sizeof(nscss_content));
146 if (result == NULL)
147 return NSERROR_NOMEM;
148
149 error = content__init(&result->base, handler, imime_type,
150 params, llcache, fallback_charset, quirks);
151 if (error != NSERROR_OK) {
152 free(result);
153 return error;
154 }
155
156 /* Find charset specified on HTTP layer, if any */
157 error = http_parameter_list_find_item(params, corestring_lwc_charset,
158 &charset_value);
159 if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) {
160 /* No charset specified, use fallback, if any */
161 /** \todo libcss will take this as gospel, which is wrong */
162 charset = fallback_charset;
163 } else {
164 charset = lwc_string_data(charset_value);
165 }
166
167 /* Compute base URL for stylesheet */
168 xnsbase = llcache_handle_get_header(llcache, "X-NS-Base");
169 if (xnsbase == NULL) {
170 xnsbase = nsurl_access(content_get_url(&result->base));
171 }
172
173 error = nscss_create_css_data(&result->data,
174 xnsbase, charset, result->base.quirks,
176 if (error != NSERROR_OK) {
178 lwc_string_unref(charset_value);
179 free(result);
180 return error;
181 }
182
183 lwc_string_unref(charset_value);
184
185 *c = (struct content *) result;
186
187 return NSERROR_OK;
188}
189
190/**
191 * Create a struct content_css_data, creating a stylesheet object
192 *
193 * \param c Struct to populate
194 * \param url URL of stylesheet
195 * \param charset Stylesheet charset
196 * \param quirks Stylesheet quirks mode
197 * \param done Callback to call when content has completed
198 * \param pw Client data for \a done
199 * \return NSERROR_OK on success, NSERROR_NOMEM on memory exhaustion
200 */
202 const char *url, const char *charset, bool quirks,
203 nscss_done_callback done, void *pw)
204{
205 css_error error;
206 css_stylesheet_params params;
207
208 c->pw = pw;
209 c->done = done;
210 c->next_to_register = (uint32_t) -1;
211 c->import_count = 0;
212 c->imports = NULL;
213 if (charset != NULL)
214 c->charset = strdup(charset);
215 else
216 c->charset = NULL;
217
218 params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
219 params.level = CSS_LEVEL_DEFAULT;
220 params.charset = charset;
221 params.url = url;
222 params.title = NULL;
223 params.allow_quirks = quirks;
224 params.inline_style = false;
225 params.resolve = nscss_resolve_url;
226 params.resolve_pw = NULL;
227 params.import = nscss_handle_import;
228 params.import_pw = c;
229 params.color = ns_system_colour;
230 params.color_pw = NULL;
231 params.font = NULL;
232 params.font_pw = NULL;
233
234 error = css_stylesheet_create(&params, &c->sheet);
235 if (error != CSS_OK) {
236 return NSERROR_NOMEM;
237 }
238
239 return NSERROR_OK;
240}
241
242/**
243 * Process CSS source data
244 *
245 * \param c Content structure
246 * \param data Data to process
247 * \param size Number of bytes to process
248 * \return true on success, false on failure
249 */
250static bool
251nscss_process_data(struct content *c, const char *data, unsigned int size)
252{
253 nscss_content *css = (nscss_content *) c;
254 css_error error;
255
256 error = nscss_process_css_data(&css->data, data, size);
257 if (error != CSS_OK && error != CSS_NEEDDATA) {
259 }
260
261 return (error == CSS_OK || error == CSS_NEEDDATA);
262}
263
264/**
265 * Process CSS data
266 *
267 * \param c CSS content object
268 * \param data Data to process
269 * \param size Number of bytes to process
270 * \return CSS_OK on success, appropriate error otherwise
271 */
272static css_error nscss_process_css_data(struct content_css_data *c,
273 const char *data, unsigned int size)
274{
275 return css_stylesheet_append_data(c->sheet,
276 (const uint8_t *) data, size);
277}
278
279/**
280 * Convert a CSS content ready for use
281 *
282 * \param c Content to convert
283 * \return true on success, false on failure
284 */
285bool nscss_convert(struct content *c)
286{
287 nscss_content *css = (nscss_content *) c;
288 css_error error;
289
290 error = nscss_convert_css_data(&css->data);
291 if (error != CSS_OK) {
293 return false;
294 }
295
296 return true;
297}
298
299/**
300 * Convert CSS data ready for use
301 *
302 * \param c CSS data to convert
303 * \return CSS error
304 */
305static css_error nscss_convert_css_data(struct content_css_data *c)
306{
307 css_error error;
308
309 error = css_stylesheet_data_done(c->sheet);
310
311 /* Process pending imports */
312 if (error == CSS_IMPORTS_PENDING) {
313 /* We must not have registered any imports yet */
314 assert(c->next_to_register == (uint32_t) -1);
315
316 /* Start registering, until we find one that
317 * hasn't finished fetching */
318 c->next_to_register = 0;
319 error = nscss_register_imports(c);
320 } else if (error == CSS_OK) {
321 /* No imports, and no errors, so complete conversion */
322 c->done(c, c->pw);
323 } else {
324 const char *url;
325
326 if (css_stylesheet_get_url(c->sheet, &url) == CSS_OK) {
327 NSLOG(netsurf, INFO, "Failed converting %p %s (%d)",
328 c, url, error);
329 } else {
330 NSLOG(netsurf, INFO, "Failed converting %p (%d)", c,
331 error);
332 }
333 }
334
335 return error;
336}
337
338/**
339 * Clean up a CSS content
340 *
341 * \param c Content to clean up
342 */
343void nscss_destroy(struct content *c)
344{
345 nscss_content *css = (nscss_content *) c;
346
348}
349
350/**
351 * Clean up CSS data
352 *
353 * \param c CSS data to clean up
354 */
356{
357 uint32_t i;
358
359 for (i = 0; i < c->import_count; i++) {
360 if (c->imports[i].c != NULL) {
362 }
363 c->imports[i].c = NULL;
364 }
365
366 free(c->imports);
367
368 if (c->sheet != NULL) {
369 css_stylesheet_destroy(c->sheet);
370 c->sheet = NULL;
371 }
372
373 free(c->charset);
374}
375
376nserror nscss_clone(const struct content *old, struct content **newc)
377{
378 const nscss_content *old_css = (const nscss_content *) old;
379 nscss_content *new_css;
380 const uint8_t *data;
381 size_t size;
382 nserror error;
383
384 new_css = calloc(1, sizeof(nscss_content));
385 if (new_css == NULL)
386 return NSERROR_NOMEM;
387
388 /* Clone content */
389 error = content__clone(old, &new_css->base);
390 if (error != NSERROR_OK) {
391 content_destroy(&new_css->base);
392 return error;
393 }
394
395 /* Simply replay create/process/convert */
396 error = nscss_create_css_data(&new_css->data,
398 old_css->data.charset,
399 new_css->base.quirks,
400 nscss_content_done, new_css);
401 if (error != NSERROR_OK) {
402 content_destroy(&new_css->base);
403 return error;
404 }
405
406 data = content__get_source_data(&new_css->base, &size);
407 if (size > 0) {
408 if (nscss_process_data(&new_css->base,
409 (char *)data,
410 (unsigned int)size) == false) {
411 content_destroy(&new_css->base);
413 }
414 }
415
416 if (old->status == CONTENT_STATUS_READY ||
417 old->status == CONTENT_STATUS_DONE) {
418 if (nscss_convert(&new_css->base) == false) {
419 content_destroy(&new_css->base);
421 }
422 }
423
424 *newc = (struct content *) new_css;
425
426 return NSERROR_OK;
427}
428
429bool nscss_matches_quirks(const struct content *c, bool quirks)
430{
431 return c->quirks == quirks;
432}
433
434/* exported interface documented in netsurf/css.h */
435css_stylesheet *nscss_get_stylesheet(struct hlcache_handle *h)
436{
438
439 assert(c != NULL);
440
441 return c->data.sheet;
442}
443
444/* exported interface documented in netsurf/css.h */
446{
448
449 assert(c != NULL);
450 assert(n != NULL);
451
452 *n = c->data.import_count;
453
454 return c->data.imports;
455}
456
457/**
458 * Compute the type of a content
459 *
460 * \return CONTENT_CSS
461 */
463{
464 return CONTENT_CSS;
465}
466
467/*****************************************************************************
468 * Object completion *
469 *****************************************************************************/
470
471/**
472 * Handle notification that a CSS object is done
473 *
474 * \param css CSS object
475 * \param pw Private data
476 */
477void nscss_content_done(struct content_css_data *css, void *pw)
478{
479 struct content *c = pw;
480 uint32_t i;
481 size_t size;
482 css_error error;
483
484 /* Retrieve the size of this sheet */
485 error = css_stylesheet_size(css->sheet, &size);
486 if (error != CSS_OK) {
489 return;
490 }
491 c->size += size;
492
493 /* Add on the size of the imported sheets */
494 for (i = 0; i < css->import_count; i++) {
495 if (css->imports[i].c != NULL) {
496 struct content *import = hlcache_handle_get_content(
497 css->imports[i].c);
498
499 if (import != NULL) {
500 c->size += import->size;
501 }
502 }
503 }
504
505 /* Finally, catch the content's users up with reality */
508}
509
510/*****************************************************************************
511 * Import handling *
512 *****************************************************************************/
513
514/**
515 * Handle notification of the need for an imported stylesheet
516 *
517 * \param pw CSS object requesting the import
518 * \param parent Stylesheet requesting the import
519 * \param url URL of the imported sheet
520 * \return CSS_OK on success, appropriate error otherwise
521 */
522css_error nscss_handle_import(void *pw, css_stylesheet *parent,
523 lwc_string *url)
524{
525 content_type accept = CONTENT_CSS;
526 struct content_css_data *c = pw;
527 nscss_import_ctx *ctx;
529 struct nscss_import *imports;
530 const char *referer;
531 css_error error;
532 nserror nerror;
533
534 nsurl *ns_url;
535 nsurl *ns_ref;
536
537 assert(parent == c->sheet);
538
539 error = css_stylesheet_get_url(c->sheet, &referer);
540 if (error != CSS_OK) {
541 return error;
542 }
543
544 ctx = malloc(sizeof(*ctx));
545 if (ctx == NULL)
546 return CSS_NOMEM;
547
548 ctx->css = c;
549 ctx->index = c->import_count;
550
551 /* Increase space in table */
552 imports = realloc(c->imports, (c->import_count + 1) *
553 sizeof(struct nscss_import));
554 if (imports == NULL) {
555 free(ctx);
556 return CSS_NOMEM;
557 }
558 c->imports = imports;
559
560 /** \todo fallback charset */
561 child.charset = NULL;
562 error = css_stylesheet_quirks_allowed(c->sheet, &child.quirks);
563 if (error != CSS_OK) {
564 free(ctx);
565 return error;
566 }
567
568 /* Create content */
569
570 /** \todo Why aren't we getting a relative url part, to join? */
571 nerror = nsurl_create(lwc_string_data(url), &ns_url);
572 if (nerror != NSERROR_OK) {
573 free(ctx);
574 return CSS_NOMEM;
575 }
576
577 /** \todo Constructing nsurl for referer here is silly, avoid */
578 nerror = nsurl_create(referer, &ns_ref);
579 if (nerror != NSERROR_OK) {
580 nsurl_unref(ns_url);
581 free(ctx);
582 return CSS_NOMEM;
583 }
584
585 /* Avoid importing ourself */
586 if (nsurl_compare(ns_url, ns_ref, NSURL_COMPLETE)) {
587 c->imports[c->import_count].c = NULL;
588 /* No longer require context as we're not fetching anything */
589 free(ctx);
590 ctx = NULL;
591 } else {
592 nerror = hlcache_handle_retrieve(ns_url,
593 0, ns_ref, NULL, nscss_import, ctx,
594 &child, accept,
595 &c->imports[c->import_count].c);
596 if (nerror != NSERROR_OK) {
597 free(ctx);
598 return CSS_NOMEM;
599 }
600 }
601
602 nsurl_unref(ns_url);
603 nsurl_unref(ns_ref);
604
605#ifdef NSCSS_IMPORT_TRACE
606 NSLOG(netsurf, INFO, "Import %d '%s' -> (handle: %p ctx: %p)",
607 c->import_count, lwc_string_data(url),
608 c->imports[c->import_count].c, ctx);
609#endif
610
611 c->import_count++;
612
613 return CSS_OK;
614}
615
616/**
617 * Handler for imported stylesheet events
618 *
619 * \param handle Handle for stylesheet
620 * \param event Event object
621 * \param pw Callback context
622 * \return NSERROR_OK on success, appropriate error otherwise
623 */
625 const hlcache_event *event, void *pw)
626{
627 nscss_import_ctx *ctx = pw;
628 css_error error = CSS_OK;
629
630#ifdef NSCSS_IMPORT_TRACE
631 NSLOG(netsurf, INFO, "Event %d for %p (%p)", event->type, handle, ctx);
632#endif
633
634 assert(ctx->css->imports[ctx->index].c == handle);
635
636 switch (event->type) {
637 case CONTENT_MSG_DONE:
638 error = nscss_import_complete(ctx);
639 break;
640
643 ctx->css->imports[ctx->index].c = NULL;
644
645 error = nscss_import_complete(ctx);
646 /* Already released handle */
647 break;
648 default:
649 break;
650 }
651
652 /* Preserve out-of-memory. Anything else is OK */
653 return error == CSS_NOMEM ? NSERROR_NOMEM : NSERROR_OK;
654}
655
656/**
657 * Handle an imported stylesheet completing
658 *
659 * \param ctx Import context
660 * \return CSS_OK on success, appropriate error otherwise
661 */
663{
664 css_error error = CSS_OK;
665
666 /* If this import is the next to be registered, do so */
667 if (ctx->css->next_to_register == ctx->index)
668 error = nscss_register_imports(ctx->css);
669
670#ifdef NSCSS_IMPORT_TRACE
671 NSLOG(netsurf, INFO, "Destroying import context %p for %d", ctx,
672 ctx->index);
673#endif
674
675 /* No longer need import context */
676 free(ctx);
677
678 return error;
679}
680
681/*****************************************************************************
682 * Import registration *
683 *****************************************************************************/
684
685/**
686 * Register imports with a stylesheet
687 *
688 * \param c CSS object containing the imports
689 * \return CSS_OK on success, appropriate error otherwise
690 */
692{
693 uint32_t index;
694 css_error error;
695
696 assert(c->next_to_register != (uint32_t) -1);
697 assert(c->next_to_register < c->import_count);
698
699 /* Register imported sheets */
700 for (index = c->next_to_register; index < c->import_count; index++) {
701 /* Stop registering if we encounter one whose fetch hasn't
702 * completed yet. We'll resume at this point when it has
703 * completed.
704 */
705 if (c->imports[index].c != NULL &&
706 content_get_status(c->imports[index].c) !=
708 break;
709 }
710
711 error = nscss_register_import(c, c->imports[index].c);
712 if (error != CSS_OK)
713 return error;
714 }
715
716 /* Record identity of the next import to register */
717 c->next_to_register = (uint32_t) index;
718
719 if (c->next_to_register == c->import_count) {
720 /* No more imports: notify parent that we're DONE */
721 c->done(c, c->pw);
722 }
723
724 return CSS_OK;
725}
726
727
728/**
729 * Register an import with a stylesheet
730 *
731 * \param c CSS object that requested the import
732 * \param import Cache handle of import, or NULL for blank
733 * \return CSS_OK on success, appropriate error otherwise
734 */
736 const hlcache_handle *import)
737{
738 css_stylesheet *sheet;
739 css_error error;
740
741 if (import != NULL) {
742 nscss_content *s =
744 sheet = s->data.sheet;
745 } else {
746 /* Create a blank sheet if needed. */
747 if (blank_import == NULL) {
748 css_stylesheet_params params;
749
750 params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
751 params.level = CSS_LEVEL_DEFAULT;
752 params.charset = NULL;
753 params.url = "";
754 params.title = NULL;
755 params.allow_quirks = false;
756 params.inline_style = false;
757 params.resolve = nscss_resolve_url;
758 params.resolve_pw = NULL;
759 params.import = NULL;
760 params.import_pw = NULL;
761 params.color = ns_system_colour;
762 params.color_pw = NULL;
763 params.font = NULL;
764 params.font_pw = NULL;
765
766 error = css_stylesheet_create(&params, &blank_import);
767 if (error != CSS_OK) {
768 return error;
769 }
770
771 error = css_stylesheet_data_done(blank_import);
772 if (error != CSS_OK) {
773 css_stylesheet_destroy(blank_import);
774 return error;
775 }
776 }
777
778 sheet = blank_import;
779 }
780
781 error = css_stylesheet_register_import(c->sheet, sheet);
782 if (error != CSS_OK) {
783 return error;
784 }
785
786 return error;
787}
788
789/**
790 * Clean up after the CSS content handler
791 */
792static void nscss_fini(void)
793{
794 if (blank_import != NULL) {
795 css_stylesheet_destroy(blank_import);
796 blank_import = NULL;
797 }
799}
800
802 .fini = nscss_fini,
803 .create = nscss_create,
804 .process_data = nscss_process_data,
805 .data_complete = nscss_convert,
806 .destroy = nscss_destroy,
807 .clone = nscss_clone,
808 .matches_quirks = nscss_matches_quirks,
809 .type = nscss_content_type,
810 .no_share = false,
811};
812
813/* exported interface documented in netsurf/css.h */
815{
816 nserror error;
817
818 error = content_factory_register_handler("text/css",
820 if (error != NSERROR_OK)
821 goto error;
822
823 error = css_hint_init();
824 if (error != NSERROR_OK)
825 goto error;
826
827 return NSERROR_OK;
828
829error:
830 nscss_fini();
831
832 return error;
833}
STATIC char result[100]
Definition: arexx.c:77
Fetching of data from a URL (interface).
void content_destroy(struct content *c)
Destroy and free a content.
Definition: content.c:354
void content_set_done(struct content *c)
Put a content in status CONTENT_STATUS_DONE.
Definition: content.c:299
nserror content__init(struct content *c, const content_handler *handler, lwc_string *imime_type, const struct http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks)
Definition: content.c:190
void content_set_error(struct content *c)
Put a content in status CONTENT_STATUS_ERROR and unlock the content.
Definition: content.c:313
nsurl * content_get_url(struct content *c)
Retrieve URL associated with content.
Definition: content.c:1043
const uint8_t * content__get_source_data(struct content *c, size_t *size)
Retrieve source of content.
Definition: content.c:1208
nserror content__clone(const struct content *c, struct content *nc)
Clone a content's data members.
Definition: content.c:1374
void content_set_ready(struct content *c)
Put a content in status CONTENT_STATUS_READY and unlock the content.
Definition: content.c:285
content_status content_get_status(hlcache_handle *h)
Retrieve status of content.
Definition: content.c:1116
void content_broadcast_error(struct content *c, nserror errorcode, const char *msg)
Send an error message to all users.
Definition: content.c:769
nserror content_factory_register_handler(const char *mime_type, const content_handler *handler)
Register a handler with the content factory.
Protected interface to Content handling.
@ CONTENT_STATUS_READY
Some parts of content still being loaded, but can be displayed.
Definition: content_type.h:92
@ CONTENT_STATUS_DONE
Content has completed all processing.
Definition: content_type.h:95
content_type
The type of a content.
Definition: content_type.h:53
@ CONTENT_CSS
content is CSS
Definition: content_type.h:64
@ CONTENT_MSG_DONE
content has finished processing
Definition: content_type.h:119
@ CONTENT_MSG_ERROR
error occurred
Definition: content_type.h:122
Useful interned string pointers (interface).
static nserror nscss_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c)
Initialise a CSS content.
Definition: css.c:131
static void nscss_destroy(struct content *c)
Clean up a CSS content.
Definition: css.c:343
static void nscss_destroy_css_data(struct content_css_data *c)
Clean up CSS data.
Definition: css.c:355
struct nscss_import * nscss_get_imports(hlcache_handle *h, uint32_t *n)
Retrieve imported stylesheets.
Definition: css.c:445
nserror nscss_init(void)
Initialise the CSS content handler.
Definition: css.c:814
static nserror nscss_clone(const struct content *old, struct content **newc)
Definition: css.c:376
static bool nscss_matches_quirks(const struct content *c, bool quirks)
Definition: css.c:429
css_fixed nscss_screen_dpi
Screen DPI in fixed point units: defaults to 90, which RISC OS uses.
Definition: css.c:44
static css_error nscss_register_imports(struct content_css_data *c)
Register imports with a stylesheet.
Definition: css.c:691
static nserror nscss_import(hlcache_handle *handle, const hlcache_event *event, void *pw)
Handler for imported stylesheet events.
Definition: css.c:624
static css_error nscss_process_css_data(struct content_css_data *c, const char *data, unsigned int size)
Process CSS data.
Definition: css.c:272
static content_type nscss_content_type(void)
Compute the type of a content.
Definition: css.c:462
static css_error nscss_handle_import(void *pw, css_stylesheet *parent, lwc_string *url)
Handle notification of the need for an imported stylesheet.
Definition: css.c:522
static css_stylesheet * blank_import
Definition: css.c:115
static const content_handler css_content_handler
Definition: css.c:801
struct nscss_content nscss_content
CSS content data.
static nserror nscss_create_css_data(struct content_css_data *c, const char *url, const char *charset, bool quirks, nscss_done_callback done, void *pw)
Create a struct content_css_data, creating a stylesheet object.
Definition: css.c:201
void(* nscss_done_callback)(struct content_css_data *css, void *pw)
Type of callback called when a CSS object has finished.
Definition: css.c:54
static void nscss_content_done(struct content_css_data *css, void *pw)
Handle notification that a CSS object is done.
Definition: css.c:477
static css_error nscss_convert_css_data(struct content_css_data *c)
Convert CSS data ready for use.
Definition: css.c:305
static void nscss_fini(void)
Clean up after the CSS content handler.
Definition: css.c:792
static bool nscss_process_data(struct content *c, const char *data, unsigned int size)
Process CSS source data.
Definition: css.c:251
static css_error nscss_import_complete(nscss_import_ctx *ctx)
Handle an imported stylesheet completing.
Definition: css.c:662
static css_error nscss_register_import(struct content_css_data *c, const hlcache_handle *import)
Register an import with a stylesheet.
Definition: css.c:735
css_stylesheet * nscss_get_stylesheet(struct hlcache_handle *h)
Retrieve the stylesheet object associated with a CSS content.
Definition: css.c:435
static bool nscss_convert(struct content *c)
Convert a CSS content ready for use.
Definition: css.c:285
wimp_w parent
Definition: dialog.c:88
Error codes.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_CSS
CSS call returned error.
Definition: errors.h:53
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_CLONE_FAILED
Failed to clone handle.
Definition: errors.h:37
@ NSERROR_OK
No error.
Definition: errors.h:30
void css_hint_fini(void)
Definition: hints.c:599
nserror css_hint_init(void)
Definition: hints.c:588
struct content * hlcache_handle_get_content(const hlcache_handle *handle)
Retrieve a content object from a cache handle.
Definition: hlcache.c:772
nserror hlcache_handle_release(hlcache_handle *handle)
Release a high-level cache handle.
Definition: hlcache.c:736
nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags, nsurl *referer, llcache_post_data *post, hlcache_handle_callback cb, void *pw, hlcache_child_context *child, content_type accepted_types, hlcache_handle **result)
Retrieve a high-level cache handle for an object.
Definition: hlcache.c:675
High-level resource cache interface.
HTTP header parsing functions.
css_error nscss_resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs)
URL resolution callback for libcss.
Definition: internal.c:27
static struct llcache_s * llcache
low level cache state
Definition: llcache.c:267
const char * llcache_handle_get_header(const llcache_handle *handle, const char *key)
Retrieve a header value associated with a low-level cache object.
Definition: llcache.c:4210
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
Localised message support (interface).
bool nsurl_compare(const nsurl *url1, const nsurl *url2, nsurl_component parts)
Compare two URLs.
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
@ NSURL_COMPLETE
Definition: nsurl.h:54
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
nserror http_parameter_list_find_item(const http_parameter *list, lwc_string *name, lwc_string **value)
Find a named item in an HTTP parameter list.
Definition: parameter.c:114
Interface to utility string handling.
CSS content data.
Definition: css.c:60
css_stylesheet * sheet
Stylesheet object.
Definition: css.c:61
char * charset
Character set of stylesheet.
Definition: css.c:62
void * pw
Client data.
Definition: css.c:67
struct nscss_import * imports
Array of imported sheets.
Definition: css.c:63
uint32_t import_count
Number of sheets imported.
Definition: css.c:64
uint32_t next_to_register
Index of next import to register.
Definition: css.c:65
nscss_done_callback done
Completion callback.
Definition: css.c:66
Content operation function table.
void(* fini)(void)
Content which corresponds to a single URL.
bool quirks
Content is in quirks mode.
content_status status
Current status.
unsigned int size
Estimated size of all data associated with this content.
Context for retrieving a child object.
Definition: hlcache.h:37
bool quirks
Whether parent is quirky.
Definition: hlcache.h:39
const char * charset
Charset of parent.
Definition: hlcache.h:38
High-level cache event.
Definition: hlcache.h:43
content_msg type
Event type.
Definition: hlcache.h:44
High-level cache handle.
Definition: hlcache.c:66
void * pw
Client data.
Definition: hlcache.c:70
Representation of an HTTP parameter.
Definition: parameter.c:31
Handle to low-level cache object.
Definition: llcache.c:76
CSS content data.
Definition: css.c:74
struct content_css_data data
CSS data.
Definition: css.c:77
struct content base
Underlying content object.
Definition: css.c:75
Context for import fetches.
Definition: css.c:83
uint32_t index
Index into parent sheet's imports array.
Definition: css.c:85
struct content_css_data * css
Object containing import.
Definition: css.c:84
Imported stylesheet record.
Definition: css.h:33
struct hlcache_handle * c
Content containing sheet.
Definition: css.h:34
css_error ns_system_colour(void *pw, lwc_string *name, css_color *colour)
css callback to obtain named system colour.
Definition: system_colour.c:95
Interface to system colour values.
Interface to a number of general purpose functionality.